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