bsd-family-tree: Sync with FreeBSD (FreeBSD 11.0).
[dragonfly.git] / sys / emulation / 43bsd / 43bsd_hostinfo.c
blobc1ab45989c7c817d759e91c48540dc28a574e809
1 /*
2 * 43BSD_HOSTINFO.C - 4.3BSD compatibility host info syscalls
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 * $DragonFly: src/sys/emulation/43bsd/43bsd_hostinfo.c,v 1.4 2006/09/05 00:55:44 dillon Exp $
32 * from: DragonFly kern/kern_xxx.c,v 1.7
33 * from: DragonFly kern/kern_sysctl.c,v 1.12
35 * These syscalls used to live in kern/kern_xxx.c and kern/kern_sysctl.c.
38 #include "opt_compat.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sysproto.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/priv.h>
46 #include <sys/socket.h>
47 #include <sys/sysctl.h>
49 #include <vm/vm_param.h>
51 int
52 sys_ogethostname(struct gethostname_args *uap)
54 size_t len;
55 char *hostname;
56 int error, name[2];
58 name[0] = CTL_KERN;
59 name[1] = KERN_HOSTNAME;
60 len = MIN(uap->len, MAXHOSTNAMELEN);
61 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
63 error = kernel_sysctl(name, 2, hostname, &len, NULL, 0, NULL);
65 if (error == 0)
66 error = copyout(hostname, uap->hostname, len);
68 kfree(hostname, M_TEMP);
69 return (error);
72 int
73 sys_osethostname(struct sethostname_args *uap)
75 struct thread *td = curthread;
76 size_t len;
77 char *hostname;
78 int name[2];
79 int error;
81 name[0] = CTL_KERN;
82 name[1] = KERN_HOSTNAME;
83 error = priv_check_cred(td->td_ucred, PRIV_SETHOSTNAME, 0);
84 if (error)
85 return (error);
86 len = MIN(uap->len, MAXHOSTNAMELEN);
87 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
89 error = copyin(uap->hostname, hostname, len);
90 if (error) {
91 kfree(hostname, M_TEMP);
92 return (error);
95 error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL);
97 kfree(hostname, M_TEMP);
98 return (error);
102 * MPSAFE
105 sys_ogethostid(struct ogethostid_args *uap)
107 uap->sysmsg_lresult = hostid;
108 return (0);
112 * MPSAFE
115 sys_osethostid(struct osethostid_args *uap)
117 struct thread *td = curthread;
118 int error;
120 error = priv_check(td, PRIV_ROOT);
121 if (error)
122 return (error);
123 hostid = uap->hostid;
124 return (0);
128 * MPSAFE
131 sys_oquota(struct oquota_args *uap)
133 return (ENOSYS);
136 #define KINFO_PROC (0<<8)
137 #define KINFO_RT (1<<8)
138 #define KINFO_VNODE (2<<8)
139 #define KINFO_FILE (3<<8)
140 #define KINFO_METER (4<<8)
141 #define KINFO_LOADAVG (5<<8)
142 #define KINFO_CLOCKRATE (6<<8)
144 /* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
145 #define KINFO_BSDI_SYSINFO (101<<8)
148 * XXX this is bloat, but I hope it's better here than on the potentially
149 * limited kernel stack... -Peter
152 static struct {
153 int bsdi_machine; /* "i386" on BSD/386 */
154 /* ^^^ this is an offset to the string, relative to the struct start */
155 char *pad0;
156 long pad1;
157 long pad2;
158 long pad3;
159 u_long pad4;
160 u_long pad5;
161 u_long pad6;
163 int bsdi_ostype; /* "BSD/386" on BSD/386 */
164 int bsdi_osrelease; /* "1.1" on BSD/386 */
165 long pad7;
166 long pad8;
167 char *pad9;
169 long pad10;
170 long pad11;
171 int pad12;
172 long pad13;
173 quad_t pad14;
174 long pad15;
176 struct timeval pad16;
177 /* we dont set this, because BSDI's uname used gethostname() instead */
178 int bsdi_hostname; /* hostname on BSD/386 */
180 /* the actual string data is appended here */
182 } bsdi_si;
184 * this data is appended to the end of the bsdi_si structure during copyout.
185 * The "char *" offsets are relative to the base of the bsdi_si struct.
186 * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
187 * should not exceed the length of the buffer here... (or else!! :-)
189 static char bsdi_strings[80]; /* It had better be less than this! */
192 * MPALMOSTSAFE
195 sys_ogetkerninfo(struct getkerninfo_args *uap)
197 int error, name[6];
198 size_t size;
199 u_int needed = 0;
201 switch (uap->op & 0xff00) {
202 case KINFO_RT:
203 name[0] = CTL_NET;
204 name[1] = PF_ROUTE;
205 name[2] = 0;
206 name[3] = (uap->op & 0xff0000) >> 16;
207 name[4] = uap->op & 0xff;
208 name[5] = uap->arg;
209 error = userland_sysctl(name, 6, uap->where, uap->size,
210 0, 0, 0, &size);
211 break;
213 case KINFO_VNODE:
214 name[0] = CTL_KERN;
215 name[1] = KERN_VNODE;
216 error = userland_sysctl(name, 2, uap->where, uap->size,
217 0, 0, 0, &size);
218 break;
220 case KINFO_PROC:
221 name[0] = CTL_KERN;
222 name[1] = KERN_PROC;
223 name[2] = uap->op & 0xff;
224 name[3] = uap->arg;
225 error = userland_sysctl(name, 4, uap->where, uap->size,
226 0, 0, 0, &size);
227 break;
229 case KINFO_FILE:
230 name[0] = CTL_KERN;
231 name[1] = KERN_FILE;
232 error = userland_sysctl(name, 2, uap->where, uap->size,
233 0, 0, 0, &size);
234 break;
236 case KINFO_METER:
237 name[0] = CTL_VM;
238 name[1] = VM_METER;
239 error = userland_sysctl(name, 2, uap->where, uap->size,
240 0, 0, 0, &size);
241 break;
243 case KINFO_LOADAVG:
244 name[0] = CTL_VM;
245 name[1] = VM_LOADAVG;
246 error = userland_sysctl(name, 2, uap->where, uap->size,
247 0, 0, 0, &size);
248 break;
250 case KINFO_CLOCKRATE:
251 name[0] = CTL_KERN;
252 name[1] = KERN_CLOCKRATE;
253 error = userland_sysctl(name, 2, uap->where, uap->size,
254 0, 0, 0, &size);
255 break;
257 case KINFO_BSDI_SYSINFO: {
259 * this is pretty crude, but it's just enough for uname()
260 * from BSDI's 1.x libc to work.
261 * *size gives the size of the buffer before the call, and
262 * the amount of data copied after a successful call.
263 * If successful, the return value is the amount of data
264 * available, which can be larger than *size.
266 * BSDI's 2.x product apparently fails with ENOMEM if
267 * *size is too small.
270 u_int left;
271 char *s;
273 bzero((char *)&bsdi_si, sizeof(bsdi_si));
274 bzero(bsdi_strings, sizeof(bsdi_strings));
276 s = bsdi_strings;
278 bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
279 strcpy(s, ostype);
280 s += strlen(s) + 1;
282 bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
283 strcpy(s, osrelease);
284 s += strlen(s) + 1;
286 bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
287 strcpy(s, machine);
288 s += strlen(s) + 1;
290 needed = sizeof(bsdi_si) + (s - bsdi_strings);
292 if (uap->where == NULL || (uap->size == NULL)) {
293 /* process is asking how much buffer to supply.. */
294 size = needed;
295 error = 0;
296 break;
299 if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
300 break;
302 /* if too much buffer supplied, trim it down */
303 if (size > needed)
304 size = needed;
306 /* how much of the buffer is remaining */
307 left = size;
309 if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
310 break;
312 /* is there any point in continuing? */
313 if (left > sizeof(bsdi_si)) {
314 left -= sizeof(bsdi_si);
315 error = copyout(&bsdi_strings,
316 uap->where + sizeof(bsdi_si), left);
318 break;
320 default:
321 error = EOPNOTSUPP;
322 break;
325 if (error)
326 return (error);
327 uap->sysmsg_iresult = (int)size;
328 if (uap->size)
329 error = copyout(&size, uap->size, sizeof(size));
330 return (error);