kern_xxx.c revision 136404
1254721Semaste/* 2254721Semaste * Copyright (c) 1982, 1986, 1989, 1993 3254721Semaste * The Regents of the University of California. All rights reserved. 4254721Semaste * 5254721Semaste * Redistribution and use in source and binary forms, with or without 6254721Semaste * modification, are permitted provided that the following conditions 7254721Semaste * are met: 8254721Semaste * 1. Redistributions of source code must retain the above copyright 9254721Semaste * notice, this list of conditions and the following disclaimer. 10254721Semaste * 2. Redistributions in binary form must reproduce the above copyright 11254721Semaste * notice, this list of conditions and the following disclaimer in the 12254721Semaste * documentation and/or other materials provided with the distribution. 13321369Sdim * 4. Neither the name of the University nor the names of its contributors 14321369Sdim * may be used to endorse or promote products derived from this software 15321369Sdim * without specific prior written permission. 16314564Sdim * 17296417Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18254721Semaste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19321369Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20321369Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21321369Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22321369Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23321369Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24321369Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25314564Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26321369Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27314564Sdim * SUCH DAMAGE. 28309124Sdim * 29314564Sdim * @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93 30314564Sdim */ 31254721Semaste 32314564Sdim#include <sys/cdefs.h> 33321369Sdim__FBSDID("$FreeBSD: head/sys/kern/kern_xxx.c 136404 2004-10-11 22:04:16Z peter $"); 34314564Sdim 35321369Sdim#include "opt_compat.h" 36321369Sdim 37314564Sdim#include <sys/param.h> 38314564Sdim#include <sys/systm.h> 39314564Sdim#include <sys/sysproto.h> 40254721Semaste#include <sys/kernel.h> 41321369Sdim#include <sys/proc.h> 42321369Sdim#include <sys/lock.h> 43321369Sdim#include <sys/mutex.h> 44321369Sdim#include <sys/sysctl.h> 45321369Sdim#include <sys/utsname.h> 46321369Sdim 47321369Sdim 48321369Sdim#if defined(COMPAT_43) 49321369Sdim 50321369Sdim#ifndef _SYS_SYSPROTO_H_ 51321369Sdimstruct gethostname_args { 52321369Sdim char *hostname; 53321369Sdim u_int len; 54321369Sdim}; 55321369Sdim#endif 56321369Sdim/* 57321369Sdim * MPSAFE 58321369Sdim */ 59321369Sdim/* ARGSUSED */ 60321369Sdimint 61321369Sdimogethostname(td, uap) 62321369Sdim struct thread *td; 63321369Sdim struct gethostname_args *uap; 64321369Sdim{ 65321369Sdim int name[2]; 66321369Sdim int error; 67321369Sdim size_t len = uap->len; 68321369Sdim 69321369Sdim name[0] = CTL_KERN; 70321369Sdim name[1] = KERN_HOSTNAME; 71321369Sdim mtx_lock(&Giant); 72321369Sdim error = userland_sysctl(td, name, 2, uap->hostname, &len, 1, 0, 0, 0); 73321369Sdim mtx_unlock(&Giant); 74321369Sdim return(error); 75321369Sdim} 76321369Sdim 77321369Sdim#ifndef _SYS_SYSPROTO_H_ 78321369Sdimstruct sethostname_args { 79321369Sdim char *hostname; 80321369Sdim u_int len; 81321369Sdim}; 82321369Sdim#endif 83321369Sdim/* 84321369Sdim * MPSAFE 85321369Sdim */ 86321369Sdim/* ARGSUSED */ 87321369Sdimint 88321369Sdimosethostname(td, uap) 89321369Sdim struct thread *td; 90321369Sdim register struct sethostname_args *uap; 91254721Semaste{ 92321369Sdim int name[2]; 93321369Sdim int error; 94254721Semaste 95254721Semaste name[0] = CTL_KERN; 96254721Semaste name[1] = KERN_HOSTNAME; 97254721Semaste mtx_lock(&Giant); 98254721Semaste if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) == 0) { 99254721Semaste error = userland_sysctl(td, name, 2, 0, 0, 0, 100254721Semaste uap->hostname, uap->len, 0); 101254721Semaste } 102254721Semaste mtx_unlock(&Giant); 103254721Semaste return (error); 104254721Semaste} 105254721Semaste 106254721Semaste#ifndef _SYS_SYSPROTO_H_ 107254721Semastestruct ogethostid_args { 108254721Semaste int dummy; 109254721Semaste}; 110254721Semaste#endif 111254721Semaste/* 112254721Semaste * MPSAFE 113314564Sdim */ 114314564Sdim/* ARGSUSED */ 115254721Semasteint 116314564Sdimogethostid(td, uap) 117314564Sdim struct thread *td; 118314564Sdim struct ogethostid_args *uap; 119314564Sdim{ 120314564Sdim 121314564Sdim *(long *)(td->td_retval) = hostid; 122314564Sdim return (0); 123314564Sdim} 124254721Semaste#endif /* COMPAT_43 */ 125314564Sdim 126254721Semaste#ifdef COMPAT_43 127314564Sdim#ifndef _SYS_SYSPROTO_H_ 128254721Semastestruct osethostid_args { 129314564Sdim long hostid; 130314564Sdim}; 131314564Sdim#endif 132314564Sdim/* 133314564Sdim * MPSAFE 134314564Sdim */ 135314564Sdim/* ARGSUSED */ 136314564Sdimint 137314564Sdimosethostid(td, uap) 138314564Sdim struct thread *td; 139314564Sdim struct osethostid_args *uap; 140314564Sdim{ 141314564Sdim int error; 142314564Sdim 143314564Sdim if ((error = suser(td))) 144314564Sdim return (error); 145314564Sdim mtx_lock(&Giant); 146314564Sdim hostid = uap->hostid; 147314564Sdim mtx_unlock(&Giant); 148314564Sdim return (0); 149314564Sdim} 150314564Sdim 151314564Sdim/* 152314564Sdim * MPSAFE 153314564Sdim */ 154314564Sdimint 155314564Sdimoquota(td, uap) 156314564Sdim struct thread *td; 157314564Sdim struct oquota_args *uap; 158254721Semaste{ 159314564Sdim return (ENOSYS); 160254721Semaste} 161314564Sdim#endif /* COMPAT_43 */ 162314564Sdim 163254721Semaste/* 164314564Sdim * This is the FreeBSD-1.1 compatable uname(2) interface. These 165314564Sdim * days it is done in libc as a wrapper around a bunch of sysctl's. 166314564Sdim * This must maintain the old 1.1 binary ABI. 167314564Sdim */ 168254721Semaste#if SYS_NMLN != 32 169314564Sdim#error "FreeBSD-1.1 uname syscall has been broken" 170254721Semaste#endif 171314564Sdim#ifndef _SYS_SYSPROTO_H_ 172314564Sdimstruct uname_args { 173314564Sdim struct utsname *name; 174314564Sdim}; 175314564Sdim#endif 176314564Sdim 177314564Sdim/* 178314564Sdim * MPSAFE 179314564Sdim */ 180314564Sdim/* ARGSUSED */ 181314564Sdimint 182314564Sdimuname(td, uap) 183314564Sdim struct thread *td; 184314564Sdim struct uname_args *uap; 185314564Sdim{ 186314564Sdim int name[2], error; 187314564Sdim size_t len; 188314564Sdim char *s, *us; 189314564Sdim 190314564Sdim name[0] = CTL_KERN; 191314564Sdim name[1] = KERN_OSTYPE; 192314564Sdim len = sizeof (uap->name->sysname); 193314564Sdim mtx_lock(&Giant); 194314564Sdim error = userland_sysctl(td, name, 2, uap->name->sysname, &len, 195314564Sdim 1, 0, 0, 0, 0); 196314564Sdim if (error) 197314564Sdim goto done2; 198314564Sdim subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0); 199314564Sdim 200314564Sdim name[1] = KERN_HOSTNAME; 201314564Sdim len = sizeof uap->name->nodename; 202314564Sdim error = userland_sysctl(td, name, 2, uap->name->nodename, &len, 203314564Sdim 1, 0, 0, 0, 0); 204314564Sdim if (error) 205314564Sdim goto done2; 206314564Sdim subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0); 207314564Sdim 208314564Sdim name[1] = KERN_OSRELEASE; 209314564Sdim len = sizeof uap->name->release; 210314564Sdim error = userland_sysctl(td, name, 2, uap->name->release, &len, 211254721Semaste 1, 0, 0, 0, 0); 212314564Sdim if (error) 213314564Sdim goto done2; 214314564Sdim subyte( uap->name->release + sizeof(uap->name->release) - 1, 0); 215314564Sdim 216314564Sdim/* 217314564Sdim name = KERN_VERSION; 218254721Semaste len = sizeof uap->name->version; 219314564Sdim error = userland_sysctl(td, name, 2, uap->name->version, &len, 220254721Semaste 1, 0, 0, 0, 0); 221314564Sdim if (error) 222314564Sdim goto done2; 223314564Sdim subyte( uap->name->version + sizeof(uap->name->version) - 1, 0); 224254721Semaste*/ 225314564Sdim 226314564Sdim/* 227314564Sdim * this stupid hackery to make the version field look like FreeBSD 1.1 228314564Sdim */ 229314564Sdim for(s = version; *s && *s != '#'; s++); 230314564Sdim 231314564Sdim for(us = uap->name->version; *s && *s != ':'; s++) { 232314564Sdim error = subyte( us++, *s); 233314564Sdim if (error) 234314564Sdim goto done2; 235314564Sdim } 236314564Sdim error = subyte( us++, 0); 237314564Sdim if (error) 238314564Sdim goto done2; 239314564Sdim 240314564Sdim name[0] = CTL_HW; 241314564Sdim name[1] = HW_MACHINE; 242314564Sdim len = sizeof uap->name->machine; 243314564Sdim error = userland_sysctl(td, name, 2, uap->name->machine, &len, 244314564Sdim 1, 0, 0, 0, 0); 245314564Sdim if (error) 246254721Semaste goto done2; 247314564Sdim subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0); 248314564Sdimdone2: 249314564Sdim mtx_unlock(&Giant); 250314564Sdim return (error); 251314564Sdim} 252314564Sdim 253314564Sdim#ifndef _SYS_SYSPROTO_H_ 254314564Sdimstruct getdomainname_args { 255314564Sdim char *domainname; 256314564Sdim int len; 257314564Sdim}; 258314564Sdim#endif 259314564Sdim 260254721Semaste/* 261314564Sdim * MPSAFE 262314564Sdim */ 263314564Sdim/* ARGSUSED */ 264314564Sdimint 265314564Sdimgetdomainname(td, uap) 266314564Sdim struct thread *td; 267254721Semaste struct getdomainname_args *uap; 268314564Sdim{ 269314564Sdim int domainnamelen; 270314564Sdim int error; 271314564Sdim 272314564Sdim mtx_lock(&Giant); 273314564Sdim domainnamelen = strlen(domainname) + 1; 274314564Sdim if ((u_int)uap->len > domainnamelen) 275314564Sdim uap->len = domainnamelen; 276314564Sdim error = copyout(domainname, uap->domainname, uap->len); 277314564Sdim mtx_unlock(&Giant); 278314564Sdim return (error); 279314564Sdim} 280314564Sdim 281314564Sdim#ifndef _SYS_SYSPROTO_H_ 282314564Sdimstruct setdomainname_args { 283314564Sdim char *domainname; 284314564Sdim int len; 285314564Sdim}; 286314564Sdim#endif 287254721Semaste 288314564Sdim/* 289314564Sdim * MPSAFE 290314564Sdim */ 291254721Semaste/* ARGSUSED */ 292314564Sdimint 293314564Sdimsetdomainname(td, uap) 294314564Sdim struct thread *td; 295258054Semaste struct setdomainname_args *uap; 296314564Sdim{ 297314564Sdim int error, domainnamelen; 298314564Sdim 299314564Sdim mtx_lock(&Giant); 300314564Sdim if ((error = suser(td))) 301314564Sdim goto done2; 302314564Sdim if ((u_int)uap->len > sizeof (domainname) - 1) { 303314564Sdim error = EINVAL; 304314564Sdim goto done2; 305314564Sdim } 306314564Sdim domainnamelen = uap->len; 307314564Sdim error = copyin(uap->domainname, domainname, uap->len); 308314564Sdim domainname[domainnamelen] = 0; 309314564Sdimdone2: 310314564Sdim mtx_unlock(&Giant); 311314564Sdim return (error); 312314564Sdim} 313314564Sdim 314314564Sdim