kern_xxx.c revision 12200
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1982, 1986, 1989, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 3. All advertising materials mentioning features or use of this software
141541Srgrimes *    must display the following acknowledgement:
151541Srgrimes *	This product includes software developed by the University of
161541Srgrimes *	California, Berkeley and its contributors.
171541Srgrimes * 4. Neither the name of the University nor the names of its contributors
181541Srgrimes *    may be used to endorse or promote products derived from this software
191541Srgrimes *    without specific prior written permission.
201541Srgrimes *
211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311541Srgrimes * SUCH DAMAGE.
321541Srgrimes *
331541Srgrimes *	@(#)kern_xxx.c	8.2 (Berkeley) 11/14/93
3412200Sbde * $Id: kern_xxx.c,v 1.15 1995/11/09 20:22:12 phk Exp $
351541Srgrimes */
361541Srgrimes
371541Srgrimes#include <sys/param.h>
381541Srgrimes#include <sys/systm.h>
391541Srgrimes#include <sys/kernel.h>
401541Srgrimes#include <sys/proc.h>
411541Srgrimes#include <sys/reboot.h>
421541Srgrimes#include <vm/vm.h>
431541Srgrimes#include <sys/sysctl.h>
441549Srgrimes#include <sys/utsname.h>
453308Sphk#include <sys/signalvar.h>
461541Srgrimes
474959Sphk/* This implements a "TEXT_SET" for cleanup functions */
484959Sphk
494959Sphkstatic void
504959Sphkdummy_cleanup() {}
514959SphkTEXT_SET(cleanup_set, dummy_cleanup);
528876Srgrimes
534959Sphktypedef void (*cleanup_func_t)(void);
544959Sphkextern const struct linker_set cleanup_set;
554959Sphkstatic const cleanup_func_t *cleanups =
564959Sphk        (const cleanup_func_t *)&cleanup_set.ls_items[0];
574959Sphk
581541Srgrimesstruct reboot_args {
591541Srgrimes	int	opt;
601541Srgrimes};
611541Srgrimes/* ARGSUSED */
621549Srgrimesint
631541Srgrimesreboot(p, uap, retval)
641541Srgrimes	struct proc *p;
651541Srgrimes	struct reboot_args *uap;
661541Srgrimes	int *retval;
671541Srgrimes{
681541Srgrimes	int error;
691541Srgrimes
703098Sphk	if ((error = suser(p->p_ucred, &p->p_acflag)))
711541Srgrimes		return (error);
724959Sphk
734959Sphk	if (!uap->opt & RB_NOSYNC) {
744959Sphk		printf("\ncleaning up... ");
754959Sphk                while(*cleanups) {
764959Sphk                        (**cleanups++)();
774959Sphk                }
784959Sphk	}
794959Sphk
801541Srgrimes	boot(uap->opt);
811541Srgrimes	return (0);
821541Srgrimes}
831541Srgrimes
841541Srgrimes#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
851541Srgrimes
861541Srgrimesstruct gethostname_args {
871541Srgrimes	char	*hostname;
881541Srgrimes	u_int	len;
891541Srgrimes};
901541Srgrimes/* ARGSUSED */
911549Srgrimesint
921541Srgrimesogethostname(p, uap, retval)
931541Srgrimes	struct proc *p;
941541Srgrimes	struct gethostname_args *uap;
951541Srgrimes	int *retval;
961541Srgrimes{
9712171Sphk	int name[2];
981541Srgrimes
9912171Sphk	name[0] = CTL_KERN;
10012171Sphk	name[1] = KERN_HOSTNAME;
10112171Sphk	return (userland_sysctl(p, name, 2, uap->hostname, &uap->len,
10212171Sphk		1, 0, 0, 0));
1031541Srgrimes}
1041541Srgrimes
1051541Srgrimesstruct sethostname_args {
1061541Srgrimes	char	*hostname;
1071541Srgrimes	u_int	len;
1081541Srgrimes};
1091541Srgrimes/* ARGSUSED */
1101549Srgrimesint
1111541Srgrimesosethostname(p, uap, retval)
1121541Srgrimes	struct proc *p;
1131541Srgrimes	register struct sethostname_args *uap;
1141541Srgrimes	int *retval;
1151541Srgrimes{
11612171Sphk	int name[2];
1171541Srgrimes	int error;
1181541Srgrimes
11912171Sphk	name[0] = CTL_KERN;
12012171Sphk	name[1] = KERN_HOSTNAME;
1213098Sphk	if ((error = suser(p->p_ucred, &p->p_acflag)))
1221541Srgrimes		return (error);
12312171Sphk	return (userland_sysctl(p, name, 2, 0, 0, 0,
12412171Sphk		uap->hostname, uap->len, 0));
1251541Srgrimes}
1261541Srgrimes
12712200Sbdestruct ogethostid_args {
1281541Srgrimes	int	dummy;
1291541Srgrimes};
1301541Srgrimes/* ARGSUSED */
1311549Srgrimesint
1321541Srgrimesogethostid(p, uap, retval)
1331541Srgrimes	struct proc *p;
13412200Sbde	struct ogethostid_args *uap;
1351541Srgrimes	int *retval;
1361541Srgrimes{
1371541Srgrimes
1381541Srgrimes	*(long *)retval = hostid;
1391541Srgrimes	return (0);
1401541Srgrimes}
1411541Srgrimes#endif /* COMPAT_43 || COMPAT_SUNOS */
1421541Srgrimes
1431541Srgrimes#ifdef COMPAT_43
14412200Sbdestruct osethostid_args {
1451541Srgrimes	long	hostid;
1461541Srgrimes};
1471541Srgrimes/* ARGSUSED */
1481549Srgrimesint
1491541Srgrimesosethostid(p, uap, retval)
1501541Srgrimes	struct proc *p;
15112200Sbde	struct osethostid_args *uap;
1521541Srgrimes	int *retval;
1531541Srgrimes{
1541541Srgrimes	int error;
1551541Srgrimes
1563098Sphk	if ((error = suser(p->p_ucred, &p->p_acflag)))
1571541Srgrimes		return (error);
1581541Srgrimes	hostid = uap->hostid;
1591541Srgrimes	return (0);
1601541Srgrimes}
1611541Srgrimes
1621549Srgrimesint
16312200Sbdeoquota(p, uap, retval)
16412200Sbde	struct proc *p;
16512200Sbde	struct oquota_args *uap;
16612200Sbde	int *retval;
1671541Srgrimes{
1681541Srgrimes
1691541Srgrimes	return (ENOSYS);
1701541Srgrimes}
1711541Srgrimes#endif /* COMPAT_43 */
1721549Srgrimes
1731549Srgrimesvoid
1741549Srgrimesshutdown_nice(void)
1751549Srgrimes{
1761549Srgrimes	/* Send a signal to init(8) and have it shutdown the world */
17710127Sdg	if (initproc != NULL) {
1789798Sdg		psignal(initproc, SIGINT);
17910127Sdg	} else {
18010127Sdg		/* No init(8) running, so simply reboot */
18110127Sdg		boot(RB_NOSYNC);
18210127Sdg	}
1831549Srgrimes	return;
1841549Srgrimes}
1851549Srgrimes
1861549Srgrimes
1871549Srgrimesstruct uname_args {
1881549Srgrimes        struct utsname  *name;
1891549Srgrimes};
1901549Srgrimes
1911549Srgrimes/* ARGSUSED */
1921549Srgrimesint
1931549Srgrimesuname(p, uap, retval)
1941549Srgrimes	struct proc *p;
1951549Srgrimes	struct uname_args *uap;
1961549Srgrimes	int *retval;
1971549Srgrimes{
19812171Sphk	int name[2], len, rtval, junk;
1991549Srgrimes	char *s, *us;
2001549Srgrimes
20112171Sphk	name[0] = CTL_KERN;
20212171Sphk	name[1] = KERN_OSTYPE;
2031549Srgrimes	len = sizeof uap->name->sysname;
20412171Sphk	rtval = userland_sysctl(p, name, 2, uap->name->sysname, &len,
20512171Sphk		1, 0, 0, 0);
2061549Srgrimes	if( rtval) return rtval;
2071549Srgrimes	subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
2081549Srgrimes
20912171Sphk	name[1] = KERN_HOSTNAME;
2101549Srgrimes	len = sizeof uap->name->nodename;
21112171Sphk	rtval = userland_sysctl(p, name, 2, uap->name->nodename, &len,
21212171Sphk		1, 0, 0, 0);
2131549Srgrimes	if( rtval) return rtval;
2141549Srgrimes	subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
2151549Srgrimes
21612171Sphk	name[1] = KERN_OSRELEASE;
2171549Srgrimes	len = sizeof uap->name->release;
21812171Sphk	rtval = userland_sysctl(p, name, 2, uap->name->release, &len,
21912171Sphk		1, 0, 0, 0);
2201549Srgrimes	if( rtval) return rtval;
2211549Srgrimes	subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
2221549Srgrimes
2231549Srgrimes/*
2241549Srgrimes	name = KERN_VERSION;
2251549Srgrimes	len = sizeof uap->name->version;
22612171Sphk	rtval = userland_sysctl(p, name, 2, uap->name->version, &len,
22712171Sphk		1, 0, 0, 0);
2281549Srgrimes	if( rtval) return rtval;
2291549Srgrimes	subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
2301549Srgrimes*/
2311549Srgrimes
2321549Srgrimes/*
2331549Srgrimes * this stupid hackery to make the version field look like FreeBSD 1.1
2341549Srgrimes */
2351549Srgrimes	for(s = version; *s && *s != '#'; s++);
2361549Srgrimes
2371549Srgrimes	for(us = uap->name->version; *s && *s != ':'; s++) {
2381549Srgrimes		rtval = subyte( us++, *s);
2391549Srgrimes		if( rtval)
2401549Srgrimes			return rtval;
2411549Srgrimes	}
2421549Srgrimes	rtval = subyte( us++, 0);
2431549Srgrimes	if( rtval)
2441549Srgrimes		return rtval;
2451549Srgrimes
24612171Sphk	name[1] = HW_MACHINE;
2471549Srgrimes	len = sizeof uap->name->machine;
24812171Sphk	rtval = userland_sysctl(p, name, 2, uap->name->machine, &len,
24912171Sphk		1, 0, 0, 0);
2501549Srgrimes	if( rtval) return rtval;
2511549Srgrimes	subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
2521549Srgrimes
2531549Srgrimes	return 0;
2541549Srgrimes}
2551549Srgrimes
2561549Srgrimesstruct getdomainname_args {
2571549Srgrimes        char    *domainname;
2581549Srgrimes        u_int   len;
2591549Srgrimes};
2601549Srgrimes
2611549Srgrimes/* ARGSUSED */
2621549Srgrimesint
2631549Srgrimesgetdomainname(p, uap, retval)
2641549Srgrimes        struct proc *p;
2651549Srgrimes        struct getdomainname_args *uap;
2661549Srgrimes        int *retval;
2671549Srgrimes{
2681549Srgrimes	if (uap->len > domainnamelen + 1)
2691549Srgrimes		uap->len = domainnamelen + 1;
2701549Srgrimes	return (copyout((caddr_t)domainname, (caddr_t)uap->domainname, uap->len));
2711549Srgrimes}
2721549Srgrimes
2731549Srgrimesstruct setdomainname_args {
2741549Srgrimes        char    *domainname;
2751549Srgrimes        u_int   len;
2761549Srgrimes};
2771549Srgrimes
2781549Srgrimes/* ARGSUSED */
2791549Srgrimesint
2801549Srgrimessetdomainname(p, uap, retval)
2811549Srgrimes        struct proc *p;
2821549Srgrimes        struct setdomainname_args *uap;
2831549Srgrimes        int *retval;
2841549Srgrimes{
2851549Srgrimes        int error;
2861549Srgrimes
2873098Sphk        if ((error = suser(p->p_ucred, &p->p_acflag)))
2881549Srgrimes                return (error);
2891549Srgrimes        if (uap->len > sizeof (domainname) - 1)
2901549Srgrimes                return EINVAL;
2911549Srgrimes        domainnamelen = uap->len;
2921549Srgrimes        error = copyin((caddr_t)uap->domainname, domainname, uap->len);
2931549Srgrimes        domainname[domainnamelen] = 0;
2941549Srgrimes        return (error);
2951549Srgrimes}
2961549Srgrimes
297