kern_xxx.c revision 12171
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 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)kern_xxx.c	8.2 (Berkeley) 11/14/93
34 * $Id: kern_xxx.c,v 1.14 1995/09/06 15:23:20 nate Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/proc.h>
41#include <sys/reboot.h>
42#include <vm/vm.h>
43#include <sys/sysctl.h>
44#include <sys/utsname.h>
45#include <sys/signalvar.h>
46
47/* This implements a "TEXT_SET" for cleanup functions */
48
49static void
50dummy_cleanup() {}
51TEXT_SET(cleanup_set, dummy_cleanup);
52
53typedef void (*cleanup_func_t)(void);
54extern const struct linker_set cleanup_set;
55static const cleanup_func_t *cleanups =
56        (const cleanup_func_t *)&cleanup_set.ls_items[0];
57
58struct reboot_args {
59	int	opt;
60};
61/* ARGSUSED */
62int
63reboot(p, uap, retval)
64	struct proc *p;
65	struct reboot_args *uap;
66	int *retval;
67{
68	int error;
69
70	if ((error = suser(p->p_ucred, &p->p_acflag)))
71		return (error);
72
73	if (!uap->opt & RB_NOSYNC) {
74		printf("\ncleaning up... ");
75                while(*cleanups) {
76                        (**cleanups++)();
77                }
78	}
79
80	boot(uap->opt);
81	return (0);
82}
83
84#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
85
86struct gethostname_args {
87	char	*hostname;
88	u_int	len;
89};
90/* ARGSUSED */
91int
92ogethostname(p, uap, retval)
93	struct proc *p;
94	struct gethostname_args *uap;
95	int *retval;
96{
97	int name[2];
98
99	name[0] = CTL_KERN;
100	name[1] = KERN_HOSTNAME;
101	return (userland_sysctl(p, name, 2, uap->hostname, &uap->len,
102		1, 0, 0, 0));
103}
104
105struct sethostname_args {
106	char	*hostname;
107	u_int	len;
108};
109/* ARGSUSED */
110int
111osethostname(p, uap, retval)
112	struct proc *p;
113	register struct sethostname_args *uap;
114	int *retval;
115{
116	int name[2];
117	int error;
118
119	name[0] = CTL_KERN;
120	name[1] = KERN_HOSTNAME;
121	if ((error = suser(p->p_ucred, &p->p_acflag)))
122		return (error);
123	return (userland_sysctl(p, name, 2, 0, 0, 0,
124		uap->hostname, uap->len, 0));
125}
126
127struct gethostid_args {
128	int	dummy;
129};
130/* ARGSUSED */
131int
132ogethostid(p, uap, retval)
133	struct proc *p;
134	struct gethostid_args *uap;
135	int *retval;
136{
137
138	*(long *)retval = hostid;
139	return (0);
140}
141#endif /* COMPAT_43 || COMPAT_SUNOS */
142
143#ifdef COMPAT_43
144struct sethostid_args {
145	long	hostid;
146};
147/* ARGSUSED */
148int
149osethostid(p, uap, retval)
150	struct proc *p;
151	struct sethostid_args *uap;
152	int *retval;
153{
154	int error;
155
156	if ((error = suser(p->p_ucred, &p->p_acflag)))
157		return (error);
158	hostid = uap->hostid;
159	return (0);
160}
161
162int
163oquota()
164{
165
166	return (ENOSYS);
167}
168#endif /* COMPAT_43 */
169
170void
171shutdown_nice(void)
172{
173	/* Send a signal to init(8) and have it shutdown the world */
174	if (initproc != NULL) {
175		psignal(initproc, SIGINT);
176	} else {
177		/* No init(8) running, so simply reboot */
178		boot(RB_NOSYNC);
179	}
180	return;
181}
182
183
184struct uname_args {
185        struct utsname  *name;
186};
187
188/* ARGSUSED */
189int
190uname(p, uap, retval)
191	struct proc *p;
192	struct uname_args *uap;
193	int *retval;
194{
195	int name[2], len, rtval, junk;
196	char *s, *us;
197
198	name[0] = CTL_KERN;
199	name[1] = KERN_OSTYPE;
200	len = sizeof uap->name->sysname;
201	rtval = userland_sysctl(p, name, 2, uap->name->sysname, &len,
202		1, 0, 0, 0);
203	if( rtval) return rtval;
204	subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
205
206	name[1] = KERN_HOSTNAME;
207	len = sizeof uap->name->nodename;
208	rtval = userland_sysctl(p, name, 2, uap->name->nodename, &len,
209		1, 0, 0, 0);
210	if( rtval) return rtval;
211	subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
212
213	name[1] = KERN_OSRELEASE;
214	len = sizeof uap->name->release;
215	rtval = userland_sysctl(p, name, 2, uap->name->release, &len,
216		1, 0, 0, 0);
217	if( rtval) return rtval;
218	subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
219
220/*
221	name = KERN_VERSION;
222	len = sizeof uap->name->version;
223	rtval = userland_sysctl(p, name, 2, uap->name->version, &len,
224		1, 0, 0, 0);
225	if( rtval) return rtval;
226	subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
227*/
228
229/*
230 * this stupid hackery to make the version field look like FreeBSD 1.1
231 */
232	for(s = version; *s && *s != '#'; s++);
233
234	for(us = uap->name->version; *s && *s != ':'; s++) {
235		rtval = subyte( us++, *s);
236		if( rtval)
237			return rtval;
238	}
239	rtval = subyte( us++, 0);
240	if( rtval)
241		return rtval;
242
243	name[1] = HW_MACHINE;
244	len = sizeof uap->name->machine;
245	rtval = userland_sysctl(p, name, 2, uap->name->machine, &len,
246		1, 0, 0, 0);
247	if( rtval) return rtval;
248	subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
249
250	return 0;
251}
252
253struct getdomainname_args {
254        char    *domainname;
255        u_int   len;
256};
257
258/* ARGSUSED */
259int
260getdomainname(p, uap, retval)
261        struct proc *p;
262        struct getdomainname_args *uap;
263        int *retval;
264{
265	if (uap->len > domainnamelen + 1)
266		uap->len = domainnamelen + 1;
267	return (copyout((caddr_t)domainname, (caddr_t)uap->domainname, uap->len));
268}
269
270struct setdomainname_args {
271        char    *domainname;
272        u_int   len;
273};
274
275/* ARGSUSED */
276int
277setdomainname(p, uap, retval)
278        struct proc *p;
279        struct setdomainname_args *uap;
280        int *retval;
281{
282        int error;
283
284        if ((error = suser(p->p_ucred, &p->p_acflag)))
285                return (error);
286        if (uap->len > sizeof (domainname) - 1)
287                return EINVAL;
288        domainnamelen = uap->len;
289        error = copyin((caddr_t)uap->domainname, domainname, uap->len);
290        domainname[domainnamelen] = 0;
291        return (error);
292}
293
294