1 /*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_compat.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/sysproto.h> 40 #include <sys/kernel.h> 41 #include <sys/priv.h> 42 #include <sys/proc.h> 43 #include <sys/lock.h> 44 #include <sys/mutex.h> 45 #include <sys/sysctl.h> 46 #include <sys/utsname.h> 47 48 49 #if defined(COMPAT_43) 50 51 #ifndef _SYS_SYSPROTO_H_ 52 struct gethostname_args { 53 char *hostname; 54 u_int len; 55 }; 56 #endif 57 /* ARGSUSED */ 58 int 59 ogethostname(td, uap) 60 struct thread *td; 61 struct gethostname_args *uap; 62 { 63 int name[2]; 64 int error; 65 size_t len = uap->len; 66 67 name[0] = CTL_KERN; 68 name[1] = KERN_HOSTNAME; 69 mtx_lock(&Giant); 70 error = userland_sysctl(td, name, 2, uap->hostname, &len, 71 1, 0, 0, 0, 0); 72 mtx_unlock(&Giant); 73 return(error); 74 } 75 76 #ifndef _SYS_SYSPROTO_H_ 77 struct sethostname_args { 78 char *hostname; 79 u_int len; 80 }; 81 #endif 82 /* ARGSUSED */ 83 int 84 osethostname(td, uap) 85 struct thread *td; 86 register struct sethostname_args *uap; 87 { 88 int name[2]; 89 int error; 90 91 name[0] = CTL_KERN; 92 name[1] = KERN_HOSTNAME; 93 mtx_lock(&Giant); 94 error = userland_sysctl(td, name, 2, 0, 0, 0, uap->hostname, 95 uap->len, 0, 0); 96 mtx_unlock(&Giant); 97 return (error); 98 } 99 100 #ifndef _SYS_SYSPROTO_H_ 101 struct ogethostid_args { 102 int dummy; 103 }; 104 #endif 105 /* ARGSUSED */ 106 int 107 ogethostid(td, uap) 108 struct thread *td; 109 struct ogethostid_args *uap; 110 { 111 112 *(long *)(td->td_retval) = hostid; 113 return (0); 114 } 115 #endif /* COMPAT_43 */ 116 117 #ifdef COMPAT_43 118 #ifndef _SYS_SYSPROTO_H_ 119 struct osethostid_args { 120 long hostid; 121 }; 122 #endif 123 /* ARGSUSED */ 124 int 125 osethostid(td, uap) 126 struct thread *td; 127 struct osethostid_args *uap; 128 { 129 int error; 130 131 error = priv_check(td, PRIV_SETHOSTID); 132 if (error) 133 return (error); 134 mtx_lock(&Giant); 135 hostid = uap->hostid; 136 mtx_unlock(&Giant); 137 return (0); 138 } 139 140 int 141 oquota(td, uap) 142 struct thread *td; 143 struct oquota_args *uap; 144 { 145 146 return (ENOSYS); 147 } 148 #endif /* COMPAT_43 */ 149 150 /* 151 * This is the FreeBSD-1.1 compatable uname(2) interface. These days it is 152 * done in libc as a wrapper around a bunch of sysctl's. This must maintain 153 * the old 1.1 binary ABI. 154 */ 155 #if SYS_NMLN != 32 156 #error "FreeBSD-1.1 uname syscall has been broken" 157 #endif 158 #ifndef _SYS_SYSPROTO_H_ 159 struct uname_args { 160 struct utsname *name; 161 }; 162 #endif 163 /* ARGSUSED */ 164 int 165 uname(td, uap) 166 struct thread *td; 167 struct uname_args *uap; 168 { 169 int name[2], error; 170 size_t len; 171 char *s, *us; 172 173 name[0] = CTL_KERN; 174 name[1] = KERN_OSTYPE; 175 len = sizeof (uap->name->sysname); 176 mtx_lock(&Giant); 177 error = userland_sysctl(td, name, 2, uap->name->sysname, &len, 178 1, 0, 0, 0, 0); 179 if (error) 180 goto done2; 181 subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); 182 183 name[1] = KERN_HOSTNAME; 184 len = sizeof uap->name->nodename; 185 error = userland_sysctl(td, name, 2, uap->name->nodename, &len, 186 1, 0, 0, 0, 0); 187 if (error) 188 goto done2; 189 subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); 190 191 name[1] = KERN_OSRELEASE; 192 len = sizeof uap->name->release; 193 error = userland_sysctl(td, name, 2, uap->name->release, &len, 194 1, 0, 0, 0, 0); 195 if (error) 196 goto done2; 197 subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); 198 199 /* 200 name = KERN_VERSION; 201 len = sizeof uap->name->version; 202 error = userland_sysctl(td, name, 2, uap->name->version, &len, 203 1, 0, 0, 0, 0); 204 if (error) 205 goto done2; 206 subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); 207 */ 208 209 /* 210 * this stupid hackery to make the version field look like FreeBSD 1.1 211 */ 212 for(s = version; *s && *s != '#'; s++); 213 214 for(us = uap->name->version; *s && *s != ':'; s++) { 215 error = subyte( us++, *s); 216 if (error) 217 goto done2; 218 } 219 error = subyte( us++, 0); 220 if (error) 221 goto done2; 222 223 name[0] = CTL_HW; 224 name[1] = HW_MACHINE; 225 len = sizeof uap->name->machine; 226 error = userland_sysctl(td, name, 2, uap->name->machine, &len, 227 1, 0, 0, 0, 0); 228 if (error) 229 goto done2; 230 subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); 231 done2: 232 mtx_unlock(&Giant); 233 return (error); 234 } 235 236 #ifndef _SYS_SYSPROTO_H_ 237 struct getdomainname_args { 238 char *domainname; 239 int len; 240 }; 241 #endif 242 /* ARGSUSED */ 243 int 244 getdomainname(td, uap) 245 struct thread *td; 246 struct getdomainname_args *uap; 247 { 248 int domainnamelen; 249 int error; 250 251 mtx_lock(&Giant); 252 domainnamelen = strlen(domainname) + 1; 253 if ((u_int)uap->len > domainnamelen) 254 uap->len = domainnamelen; 255 error = copyout(domainname, uap->domainname, uap->len); 256 mtx_unlock(&Giant); 257 return (error); 258 } 259 260 #ifndef _SYS_SYSPROTO_H_ 261 struct setdomainname_args { 262 char *domainname; 263 int len; 264 }; 265 #endif 266 /* ARGSUSED */ 267 int 268 setdomainname(td, uap) 269 struct thread *td; 270 struct setdomainname_args *uap; 271 { 272 int error, domainnamelen; 273 274 error = priv_check(td, PRIV_SETDOMAINNAME); 275 if (error) 276 return (error); 277 mtx_lock(&Giant); 278 if ((u_int)uap->len > sizeof (domainname) - 1) { 279 error = EINVAL; 280 goto done2; 281 } 282 domainnamelen = uap->len; 283 error = copyin(uap->domainname, domainname, uap->len); 284 domainname[domainnamelen] = 0; 285 done2: 286 mtx_unlock(&Giant); 287 return (error); 288 } 289