kernel - use new td_ucred in numerous places
[dragonfly.git] / sys / emulation / 43bsd / 43bsd_hostinfo.c
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  *
35  * $DragonFly: src/sys/emulation/43bsd/43bsd_hostinfo.c,v 1.4 2006/09/05 00:55:44 dillon Exp $
36  *      from: DragonFly kern/kern_xxx.c,v 1.7
37  *      from: DragonFly kern/kern_sysctl.c,v 1.12
38  *
39  * These syscalls used to live in kern/kern_xxx.c and kern/kern_sysctl.c.
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>
49 #include <sys/priv.h>
50 #include <sys/socket.h>
51 #include <sys/sysctl.h>
52 #include <vm/vm_param.h>
53
54 /*
55  * MPALMOSTSAFE
56  */
57 int
58 sys_ogethostname(struct gethostname_args *uap)
59 {
60         size_t len;
61         char *hostname;
62         int error, name[2];
63
64         name[0] = CTL_KERN;
65         name[1] = KERN_HOSTNAME;
66         len = MIN(uap->len, MAXHOSTNAMELEN);
67         hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
68
69         get_mplock();
70         error = kernel_sysctl(name, 2, hostname, &len, NULL, 0, NULL);
71         rel_mplock();
72
73         if (error == 0)
74                 error = copyout(hostname, uap->hostname, len);
75
76         kfree(hostname, M_TEMP);
77         return (error);
78 }
79
80 /*
81  * MPALMOSTSAFE
82  */
83 int
84 sys_osethostname(struct sethostname_args *uap)
85 {
86         struct thread *td = curthread;
87         size_t len;
88         char *hostname;
89         int name[2];
90         int error;
91
92         name[0] = CTL_KERN;
93         name[1] = KERN_HOSTNAME;
94         error = priv_check_cred(td->td_ucred, PRIV_SETHOSTNAME, 0);
95         if (error)
96                 return (error);
97         len = MIN(uap->len, MAXHOSTNAMELEN);
98         hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
99
100         error = copyin(uap->hostname, hostname, len);
101         if (error) {
102                 kfree(hostname, M_TEMP);
103                 return (error);
104         }
105
106         get_mplock();
107         error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL);
108         rel_mplock();
109
110         kfree(hostname, M_TEMP);
111         return (error);
112 }
113
114 /*
115  * MPSAFE
116  */
117 int
118 sys_ogethostid(struct ogethostid_args *uap)
119 {
120         uap->sysmsg_lresult = hostid;
121         return (0);
122 }
123
124 /*
125  * MPSAFE
126  */
127 int
128 sys_osethostid(struct osethostid_args *uap)
129 {
130         struct thread *td = curthread;
131         int error;
132
133         error = priv_check(td, PRIV_ROOT);
134         if (error)
135                 return (error);
136         hostid = uap->hostid;
137         return (0);
138 }
139
140 /*
141  * MPSAFE
142  */
143 int
144 sys_oquota(struct oquota_args *uap)
145 {
146         return (ENOSYS);
147 }
148
149 #define KINFO_PROC              (0<<8)
150 #define KINFO_RT                (1<<8)
151 #define KINFO_VNODE             (2<<8)
152 #define KINFO_FILE              (3<<8)
153 #define KINFO_METER             (4<<8)
154 #define KINFO_LOADAVG           (5<<8)
155 #define KINFO_CLOCKRATE         (6<<8)
156
157 /* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
158 #define KINFO_BSDI_SYSINFO      (101<<8)
159
160 /*
161  * XXX this is bloat, but I hope it's better here than on the potentially
162  * limited kernel stack...  -Peter
163  */
164
165 static struct {
166         int     bsdi_machine;           /* "i386" on BSD/386 */
167 /*      ^^^ this is an offset to the string, relative to the struct start */
168         char    *pad0;
169         long    pad1;
170         long    pad2;
171         long    pad3;
172         u_long  pad4;
173         u_long  pad5;
174         u_long  pad6;
175
176         int     bsdi_ostype;            /* "BSD/386" on BSD/386 */
177         int     bsdi_osrelease;         /* "1.1" on BSD/386 */
178         long    pad7;
179         long    pad8;
180         char    *pad9;
181
182         long    pad10;
183         long    pad11;
184         int     pad12;
185         long    pad13;
186         quad_t  pad14;
187         long    pad15;
188
189         struct  timeval pad16;
190         /* we dont set this, because BSDI's uname used gethostname() instead */
191         int     bsdi_hostname;          /* hostname on BSD/386 */
192
193         /* the actual string data is appended here */
194
195 } bsdi_si;
196 /*
197  * this data is appended to the end of the bsdi_si structure during copyout.
198  * The "char *" offsets are relative to the base of the bsdi_si struct.
199  * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
200  * should not exceed the length of the buffer here... (or else!! :-)
201  */
202 static char bsdi_strings[80];   /* It had better be less than this! */
203
204 /*
205  * MPALMOSTSAFE
206  */
207 int
208 sys_ogetkerninfo(struct getkerninfo_args *uap)
209 {
210         int error, name[6];
211         size_t size;
212         u_int needed = 0;
213
214         get_mplock();
215
216         switch (uap->op & 0xff00) {
217         case KINFO_RT:
218                 name[0] = CTL_NET;
219                 name[1] = PF_ROUTE;
220                 name[2] = 0;
221                 name[3] = (uap->op & 0xff0000) >> 16;
222                 name[4] = uap->op & 0xff;
223                 name[5] = uap->arg;
224                 error = userland_sysctl(name, 6, uap->where, uap->size,
225                         0, 0, 0, &size);
226                 break;
227
228         case KINFO_VNODE:
229                 name[0] = CTL_KERN;
230                 name[1] = KERN_VNODE;
231                 error = userland_sysctl(name, 2, uap->where, uap->size,
232                         0, 0, 0, &size);
233                 break;
234
235         case KINFO_PROC:
236                 name[0] = CTL_KERN;
237                 name[1] = KERN_PROC;
238                 name[2] = uap->op & 0xff;
239                 name[3] = uap->arg;
240                 error = userland_sysctl(name, 4, uap->where, uap->size,
241                         0, 0, 0, &size);
242                 break;
243
244         case KINFO_FILE:
245                 name[0] = CTL_KERN;
246                 name[1] = KERN_FILE;
247                 error = userland_sysctl(name, 2, uap->where, uap->size,
248                         0, 0, 0, &size);
249                 break;
250
251         case KINFO_METER:
252                 name[0] = CTL_VM;
253                 name[1] = VM_METER;
254                 error = userland_sysctl(name, 2, uap->where, uap->size,
255                         0, 0, 0, &size);
256                 break;
257
258         case KINFO_LOADAVG:
259                 name[0] = CTL_VM;
260                 name[1] = VM_LOADAVG;
261                 error = userland_sysctl(name, 2, uap->where, uap->size,
262                         0, 0, 0, &size);
263                 break;
264
265         case KINFO_CLOCKRATE:
266                 name[0] = CTL_KERN;
267                 name[1] = KERN_CLOCKRATE;
268                 error = userland_sysctl(name, 2, uap->where, uap->size,
269                         0, 0, 0, &size);
270                 break;
271
272         case KINFO_BSDI_SYSINFO: {
273                 /*
274                  * this is pretty crude, but it's just enough for uname()
275                  * from BSDI's 1.x libc to work.
276                  * *size gives the size of the buffer before the call, and
277                  * the amount of data copied after a successful call.
278                  * If successful, the return value is the amount of data
279                  * available, which can be larger than *size.
280                  *
281                  * BSDI's 2.x product apparently fails with ENOMEM if
282                  * *size is too small.
283                  */
284
285                 u_int left;
286                 char *s;
287
288                 bzero((char *)&bsdi_si, sizeof(bsdi_si));
289                 bzero(bsdi_strings, sizeof(bsdi_strings));
290
291                 s = bsdi_strings;
292
293                 bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
294                 strcpy(s, ostype);
295                 s += strlen(s) + 1;
296
297                 bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
298                 strcpy(s, osrelease);
299                 s += strlen(s) + 1;
300
301                 bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
302                 strcpy(s, machine);
303                 s += strlen(s) + 1;
304
305                 needed = sizeof(bsdi_si) + (s - bsdi_strings);
306
307                 if (uap->where == NULL || (uap->size == NULL)) {
308                         /* process is asking how much buffer to supply.. */
309                         size = needed;
310                         error = 0;
311                         break;
312                 }
313
314                 if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
315                                 break;
316
317                 /* if too much buffer supplied, trim it down */
318                 if (size > needed)
319                         size = needed;
320
321                 /* how much of the buffer is remaining */
322                 left = size;
323
324                 if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
325                         break;
326
327                 /* is there any point in continuing? */
328                 if (left > sizeof(bsdi_si)) {
329                         left -= sizeof(bsdi_si);
330                         error = copyout(&bsdi_strings,
331                                         uap->where + sizeof(bsdi_si), left);
332                 }
333                 break;
334         }
335         default:
336                 error = EOPNOTSUPP;
337                 break;
338         }
339         rel_mplock();
340         if (error)
341                 return (error);
342         uap->sysmsg_iresult = (int)size;
343         if (uap->size)
344                 error = copyout(&size, uap->size, sizeof(size));
345         return (error);
346 }