AMD64 - Refactor uio_resid and size_t assumptions.
[dragonfly.git] / sys / emulation / 43bsd / 43bsd_hostinfo.c
CommitLineData
9906751f
DRJ
1/*
2 * 43BSD_HOSTINFO.C - 4.3BSD compatibility host info syscalls
3 *
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
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. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
efda3bd0 35 * $DragonFly: src/sys/emulation/43bsd/43bsd_hostinfo.c,v 1.4 2006/09/05 00:55:44 dillon Exp $
9906751f 36 * from: DragonFly kern/kern_xxx.c,v 1.7
dddc9696 37 * from: DragonFly kern/kern_sysctl.c,v 1.12
9906751f 38 *
dddc9696 39 * These syscalls used to live in kern/kern_xxx.c and kern/kern_sysctl.c.
9906751f
DRJ
40 */
41
42#include "opt_compat.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/sysproto.h>
47#include <sys/kernel.h>
48#include <sys/proc.h>
895c1f85 49#include <sys/priv.h>
dddc9696 50#include <sys/socket.h>
9906751f 51#include <sys/sysctl.h>
dddc9696 52#include <vm/vm_param.h>
9906751f
DRJ
53
54int
753fd850 55sys_ogethostname(struct gethostname_args *uap)
9906751f
DRJ
56{
57 size_t len;
58 char *hostname;
59 int error, name[2];
60
61 name[0] = CTL_KERN;
62 name[1] = KERN_HOSTNAME;
63 len = MIN(uap->len, MAXHOSTNAMELEN);
efda3bd0 64 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
9906751f
DRJ
65
66 error = kernel_sysctl(name, 2, hostname, &len, NULL, 0, NULL);
67
68 if (error == 0)
69 error = copyout(hostname, uap->hostname, len);
70
efda3bd0 71 kfree(hostname, M_TEMP);
9906751f
DRJ
72 return (error);
73}
74
75int
753fd850 76sys_osethostname(struct sethostname_args *uap)
9906751f
DRJ
77{
78 struct thread *td = curthread;
79 struct proc *p = td->td_proc;
80 size_t len;
81 char *hostname;
82 int name[2];
83 int error;
84
85 KKASSERT(p);
86 name[0] = CTL_KERN;
87 name[1] = KERN_HOSTNAME;
ed869814 88 error = priv_check_cred(p->p_ucred, PRIV_SETHOSTNAME, 0);
9906751f
DRJ
89 if (error)
90 return (error);
91 len = MIN(uap->len, MAXHOSTNAMELEN);
efda3bd0 92 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
9906751f
DRJ
93
94 error = copyin(uap->hostname, hostname, len);
95 if (error) {
efda3bd0 96 kfree(hostname, M_TEMP);
9906751f
DRJ
97 return (error);
98 }
99
100 error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL);
101
efda3bd0 102 kfree(hostname, M_TEMP);
9906751f
DRJ
103 return (error);
104}
105
106int
753fd850 107sys_ogethostid(struct ogethostid_args *uap)
9906751f
DRJ
108{
109 uap->sysmsg_lresult = hostid;
110 return (0);
111}
112
113int
753fd850 114sys_osethostid(struct osethostid_args *uap)
9906751f
DRJ
115{
116 struct thread *td = curthread;
117 int error;
118
895c1f85 119 error = priv_check(td, PRIV_ROOT);
9906751f
DRJ
120 if (error)
121 return (error);
122 hostid = uap->hostid;
123 return (0);
124}
125
126int
753fd850 127sys_oquota(struct oquota_args *uap)
9906751f
DRJ
128{
129 return (ENOSYS);
130}
dddc9696
DRJ
131
132#define KINFO_PROC (0<<8)
133#define KINFO_RT (1<<8)
134#define KINFO_VNODE (2<<8)
135#define KINFO_FILE (3<<8)
136#define KINFO_METER (4<<8)
137#define KINFO_LOADAVG (5<<8)
138#define KINFO_CLOCKRATE (6<<8)
139
140/* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
141#define KINFO_BSDI_SYSINFO (101<<8)
142
143/*
144 * XXX this is bloat, but I hope it's better here than on the potentially
145 * limited kernel stack... -Peter
146 */
147
148static struct {
149 int bsdi_machine; /* "i386" on BSD/386 */
150/* ^^^ this is an offset to the string, relative to the struct start */
151 char *pad0;
152 long pad1;
153 long pad2;
154 long pad3;
155 u_long pad4;
156 u_long pad5;
157 u_long pad6;
158
159 int bsdi_ostype; /* "BSD/386" on BSD/386 */
160 int bsdi_osrelease; /* "1.1" on BSD/386 */
161 long pad7;
162 long pad8;
163 char *pad9;
164
165 long pad10;
166 long pad11;
167 int pad12;
168 long pad13;
169 quad_t pad14;
170 long pad15;
171
172 struct timeval pad16;
173 /* we dont set this, because BSDI's uname used gethostname() instead */
174 int bsdi_hostname; /* hostname on BSD/386 */
175
176 /* the actual string data is appended here */
177
178} bsdi_si;
179/*
180 * this data is appended to the end of the bsdi_si structure during copyout.
181 * The "char *" offsets are relative to the base of the bsdi_si struct.
182 * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
183 * should not exceed the length of the buffer here... (or else!! :-)
184 */
185static char bsdi_strings[80]; /* It had better be less than this! */
186
187int
753fd850 188sys_ogetkerninfo(struct getkerninfo_args *uap)
dddc9696
DRJ
189{
190 int error, name[6];
191 size_t size;
192 u_int needed = 0;
193
194 switch (uap->op & 0xff00) {
195
196 case KINFO_RT:
197 name[0] = CTL_NET;
198 name[1] = PF_ROUTE;
199 name[2] = 0;
200 name[3] = (uap->op & 0xff0000) >> 16;
201 name[4] = uap->op & 0xff;
202 name[5] = uap->arg;
203 error = userland_sysctl(name, 6, uap->where, uap->size,
204 0, 0, 0, &size);
205 break;
206
207 case KINFO_VNODE:
208 name[0] = CTL_KERN;
209 name[1] = KERN_VNODE;
210 error = userland_sysctl(name, 2, uap->where, uap->size,
211 0, 0, 0, &size);
212 break;
213
214 case KINFO_PROC:
215 name[0] = CTL_KERN;
216 name[1] = KERN_PROC;
217 name[2] = uap->op & 0xff;
218 name[3] = uap->arg;
219 error = userland_sysctl(name, 4, uap->where, uap->size,
220 0, 0, 0, &size);
221 break;
222
223 case KINFO_FILE:
224 name[0] = CTL_KERN;
225 name[1] = KERN_FILE;
226 error = userland_sysctl(name, 2, uap->where, uap->size,
227 0, 0, 0, &size);
228 break;
229
230 case KINFO_METER:
231 name[0] = CTL_VM;
232 name[1] = VM_METER;
233 error = userland_sysctl(name, 2, uap->where, uap->size,
234 0, 0, 0, &size);
235 break;
236
237 case KINFO_LOADAVG:
238 name[0] = CTL_VM;
239 name[1] = VM_LOADAVG;
240 error = userland_sysctl(name, 2, uap->where, uap->size,
241 0, 0, 0, &size);
242 break;
243
244 case KINFO_CLOCKRATE:
245 name[0] = CTL_KERN;
246 name[1] = KERN_CLOCKRATE;
247 error = userland_sysctl(name, 2, uap->where, uap->size,
248 0, 0, 0, &size);
249 break;
250
251 case KINFO_BSDI_SYSINFO: {
252 /*
253 * this is pretty crude, but it's just enough for uname()
254 * from BSDI's 1.x libc to work.
255 * *size gives the size of the buffer before the call, and
256 * the amount of data copied after a successful call.
257 * If successful, the return value is the amount of data
258 * available, which can be larger than *size.
259 *
260 * BSDI's 2.x product apparently fails with ENOMEM if
261 * *size is too small.
262 */
263
264 u_int left;
265 char *s;
266
267 bzero((char *)&bsdi_si, sizeof(bsdi_si));
268 bzero(bsdi_strings, sizeof(bsdi_strings));
269
270 s = bsdi_strings;
271
272 bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
273 strcpy(s, ostype);
274 s += strlen(s) + 1;
275
276 bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
277 strcpy(s, osrelease);
278 s += strlen(s) + 1;
279
280 bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
281 strcpy(s, machine);
282 s += strlen(s) + 1;
283
284 needed = sizeof(bsdi_si) + (s - bsdi_strings);
285
286 if (uap->where == NULL || (uap->size == NULL)) {
287 /* process is asking how much buffer to supply.. */
288 size = needed;
289 error = 0;
290 break;
291 }
292
293 if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
294 break;
295
296 /* if too much buffer supplied, trim it down */
297 if (size > needed)
298 size = needed;
299
300 /* how much of the buffer is remaining */
301 left = size;
302
303 if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
304 break;
305
306 /* is there any point in continuing? */
307 if (left > sizeof(bsdi_si)) {
308 left -= sizeof(bsdi_si);
309 error = copyout(&bsdi_strings,
310 uap->where + sizeof(bsdi_si), left);
311 }
312 break;
313 }
314
315 default:
316 return (EOPNOTSUPP);
317 }
318 if (error)
319 return (error);
e54488bb 320 uap->sysmsg_iresult = (int)size;
dddc9696
DRJ
321 if (uap->size)
322 error = copyout((caddr_t)&size, (caddr_t)uap->size,
323 sizeof(size));
324 return (error);
325}