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