xref: /freebsd/sys/kern/kern_xxx.c (revision 48991a368427cadb9cdac39581d1676c29619c52)
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.19 1995/11/14 09:10:45 phk Exp $
35  */
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/sysproto.h>
40 #include <sys/kernel.h>
41 #include <sys/proc.h>
42 #include <sys/reboot.h>
43 #include <vm/vm.h>
44 #include <sys/sysctl.h>
45 #include <sys/utsname.h>
46 #include <sys/signalvar.h>
47 
48 /* This implements a "TEXT_SET" for cleanup functions */
49 
50 static void
51 dummy_cleanup() {}
52 TEXT_SET(cleanup_set, dummy_cleanup);
53 
54 typedef void (*cleanup_func_t)(void);
55 extern const struct linker_set cleanup_set;
56 static const cleanup_func_t *cleanups =
57         (const cleanup_func_t *)&cleanup_set.ls_items[0];
58 
59 #ifndef _SYS_SYSPROTO_H_
60 struct reboot_args {
61 	int	opt;
62 };
63 #endif
64 /* ARGSUSED */
65 int
66 reboot(p, uap, retval)
67 	struct proc *p;
68 	struct reboot_args *uap;
69 	int *retval;
70 {
71 	int error;
72 
73 	if ((error = suser(p->p_ucred, &p->p_acflag)))
74 		return (error);
75 
76 	if (!uap->opt & RB_NOSYNC) {
77 		printf("\ncleaning up... ");
78                 while(*cleanups) {
79                         (**cleanups++)();
80                 }
81 	}
82 
83 	boot(uap->opt);
84 	return (0);
85 }
86 
87 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
88 
89 #ifndef _SYS_SYSPROTO_H_
90 struct gethostname_args {
91 	char	*hostname;
92 	u_int	len;
93 };
94 #endif
95 /* ARGSUSED */
96 int
97 ogethostname(p, uap, retval)
98 	struct proc *p;
99 	struct gethostname_args *uap;
100 	int *retval;
101 {
102 	int name[2];
103 
104 	name[0] = CTL_KERN;
105 	name[1] = KERN_HOSTNAME;
106 	return (userland_sysctl(p, name, 2, uap->hostname, &uap->len,
107 		1, 0, 0, 0));
108 }
109 
110 #ifndef _SYS_SYSPROTO_H_
111 struct sethostname_args {
112 	char	*hostname;
113 	u_int	len;
114 };
115 #endif
116 /* ARGSUSED */
117 int
118 osethostname(p, uap, retval)
119 	struct proc *p;
120 	register struct sethostname_args *uap;
121 	int *retval;
122 {
123 	int name[2];
124 	int error;
125 
126 	name[0] = CTL_KERN;
127 	name[1] = KERN_HOSTNAME;
128 	if ((error = suser(p->p_ucred, &p->p_acflag)))
129 		return (error);
130 	return (userland_sysctl(p, name, 2, 0, 0, 0,
131 		uap->hostname, uap->len, 0));
132 }
133 
134 #ifndef _SYS_SYSPROTO_H_
135 struct ogethostid_args {
136 	int	dummy;
137 };
138 #endif
139 /* ARGSUSED */
140 int
141 ogethostid(p, uap, retval)
142 	struct proc *p;
143 	struct ogethostid_args *uap;
144 	int *retval;
145 {
146 
147 	*(long *)retval = hostid;
148 	return (0);
149 }
150 #endif /* COMPAT_43 || COMPAT_SUNOS */
151 
152 #ifdef COMPAT_43
153 #ifndef _SYS_SYSPROTO_H_
154 struct osethostid_args {
155 	long	hostid;
156 };
157 #endif
158 /* ARGSUSED */
159 int
160 osethostid(p, uap, retval)
161 	struct proc *p;
162 	struct osethostid_args *uap;
163 	int *retval;
164 {
165 	int error;
166 
167 	if ((error = suser(p->p_ucred, &p->p_acflag)))
168 		return (error);
169 	hostid = uap->hostid;
170 	return (0);
171 }
172 
173 int
174 oquota(p, uap, retval)
175 	struct proc *p;
176 	struct oquota_args *uap;
177 	int *retval;
178 {
179 
180 	return (ENOSYS);
181 }
182 #endif /* COMPAT_43 */
183 
184 void
185 shutdown_nice(void)
186 {
187 	/* Send a signal to init(8) and have it shutdown the world */
188 	if (initproc != NULL) {
189 		psignal(initproc, SIGINT);
190 	} else {
191 		/* No init(8) running, so simply reboot */
192 		boot(RB_NOSYNC);
193 	}
194 	return;
195 }
196 
197 
198 #ifndef _SYS_SYSPROTO_H_
199 struct uname_args {
200         struct utsname  *name;
201 };
202 #endif
203 
204 /* ARGSUSED */
205 int
206 uname(p, uap, retval)
207 	struct proc *p;
208 	struct uname_args *uap;
209 	int *retval;
210 {
211 	int name[2], len, rtval;
212 	char *s, *us;
213 
214 	name[0] = CTL_KERN;
215 	name[1] = KERN_OSTYPE;
216 	len = sizeof uap->name->sysname;
217 	rtval = userland_sysctl(p, name, 2, uap->name->sysname, &len,
218 		1, 0, 0, 0);
219 	if( rtval) return rtval;
220 	subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
221 
222 	name[1] = KERN_HOSTNAME;
223 	len = sizeof uap->name->nodename;
224 	rtval = userland_sysctl(p, name, 2, uap->name->nodename, &len,
225 		1, 0, 0, 0);
226 	if( rtval) return rtval;
227 	subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
228 
229 	name[1] = KERN_OSRELEASE;
230 	len = sizeof uap->name->release;
231 	rtval = userland_sysctl(p, name, 2, uap->name->release, &len,
232 		1, 0, 0, 0);
233 	if( rtval) return rtval;
234 	subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
235 
236 /*
237 	name = KERN_VERSION;
238 	len = sizeof uap->name->version;
239 	rtval = userland_sysctl(p, name, 2, uap->name->version, &len,
240 		1, 0, 0, 0);
241 	if( rtval) return rtval;
242 	subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
243 */
244 
245 /*
246  * this stupid hackery to make the version field look like FreeBSD 1.1
247  */
248 	for(s = version; *s && *s != '#'; s++);
249 
250 	for(us = uap->name->version; *s && *s != ':'; s++) {
251 		rtval = subyte( us++, *s);
252 		if( rtval)
253 			return rtval;
254 	}
255 	rtval = subyte( us++, 0);
256 	if( rtval)
257 		return rtval;
258 
259 	name[1] = HW_MACHINE;
260 	len = sizeof uap->name->machine;
261 	rtval = userland_sysctl(p, name, 2, uap->name->machine, &len,
262 		1, 0, 0, 0);
263 	if( rtval) return rtval;
264 	subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
265 
266 	return 0;
267 }
268 
269 #ifndef _SYS_SYSPROTO_H_
270 struct getdomainname_args {
271         char    *domainname;
272         int     len;
273 };
274 #endif
275 
276 /* ARGSUSED */
277 int
278 getdomainname(p, uap, retval)
279         struct proc *p;
280         struct getdomainname_args *uap;
281         int *retval;
282 {
283 	int domainnamelen = strlen(domainname) + 1;
284 	if ((u_int)uap->len > domainnamelen + 1)
285 		uap->len = domainnamelen + 1;
286 	return (copyout((caddr_t)domainname, (caddr_t)uap->domainname, uap->len));
287 }
288 
289 #ifndef _SYS_SYSPROTO_H_
290 struct setdomainname_args {
291         char    *domainname;
292         int     len;
293 };
294 #endif
295 
296 /* ARGSUSED */
297 int
298 setdomainname(p, uap, retval)
299         struct proc *p;
300         struct setdomainname_args *uap;
301         int *retval;
302 {
303         int error, domainnamelen;
304 
305         if ((error = suser(p->p_ucred, &p->p_acflag)))
306                 return (error);
307         if ((u_int)uap->len > sizeof (domainname) - 1)
308                 return EINVAL;
309         domainnamelen = uap->len;
310         error = copyin((caddr_t)uap->domainname, domainname, uap->len);
311         domainname[domainnamelen] = 0;
312         return (error);
313 }
314 
315