]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/svr4/svr4_stat.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / compat / svr4 / svr4_stat.c
1 /*-
2  * Copyright (c) 1998 Mark Newton
3  * Copyright (c) 1994 Christos Zoulas
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/proc.h>
35 #include <sys/stat.h>
36 #include <sys/filedesc.h>
37 #include <sys/jail.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/unistd.h>
41 #include <sys/time.h>
42 #include <sys/syscallsubr.h>
43 #include <sys/sysctl.h>
44 #include <sys/sysproto.h>
45 #include <sys/un.h>
46 #include <sys/vimage.h>
47
48 #include <vm/vm.h>
49
50 #include <netinet/in.h>
51
52 #include <compat/svr4/svr4.h>
53 #include <compat/svr4/svr4_types.h>
54 #include <compat/svr4/svr4_signal.h>
55 #include <compat/svr4/svr4_proto.h>
56 #include <compat/svr4/svr4_util.h>
57 #include <compat/svr4/svr4_stat.h>
58 #include <compat/svr4/svr4_ustat.h>
59 #include <compat/svr4/svr4_utsname.h>
60 #include <compat/svr4/svr4_systeminfo.h>
61 #include <compat/svr4/svr4_socket.h>
62 #include <compat/svr4/svr4_time.h>
63 #if defined(NOTYET)
64 #include "svr4_fuser.h"
65 #endif
66
67 #ifdef sparc
68 /* 
69  * Solaris-2.4 on the sparc has the old stat call using the new
70  * stat data structure...
71  */
72 # define SVR4_NO_OSTAT
73 #endif
74
75 struct svr4_ustat_args {
76         svr4_dev_t              dev;
77         struct svr4_ustat * name;
78 };
79
80 static void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *);
81 static void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *);
82 int svr4_ustat(struct thread *, struct svr4_ustat_args *);
83 static int svr4_to_bsd_pathconf(int);
84
85 /*
86  * SVR4 uses named pipes as named sockets, so we tell programs
87  * that sockets are named pipes with mode 0
88  */
89 #define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
90
91
92 #ifndef SVR4_NO_OSTAT
93 static void bsd_to_svr4_stat(struct stat *, struct svr4_stat *);
94
95 static void
96 bsd_to_svr4_stat(st, st4)
97         struct stat             *st;
98         struct svr4_stat        *st4;
99 {
100         memset(st4, 0, sizeof(*st4));
101         st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
102         st4->st_ino = st->st_ino;
103         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
104         st4->st_nlink = st->st_nlink;
105         st4->st_uid = st->st_uid;
106         st4->st_gid = st->st_gid;
107         st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
108         st4->st_size = st->st_size;
109         st4->st_atim = st->st_atimespec.tv_sec;
110         st4->st_mtim = st->st_mtimespec.tv_sec;
111         st4->st_ctim = st->st_ctimespec.tv_sec;
112 }
113 #endif
114
115
116 static void
117 bsd_to_svr4_xstat(st, st4)
118         struct stat             *st;
119         struct svr4_xstat       *st4;
120 {
121         memset(st4, 0, sizeof(*st4));
122         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
123         st4->st_ino = st->st_ino;
124         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
125         st4->st_nlink = st->st_nlink;
126         st4->st_uid = st->st_uid;
127         st4->st_gid = st->st_gid;
128         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
129         st4->st_size = st->st_size;
130         st4->st_atim = st->st_atimespec;
131         st4->st_mtim = st->st_mtimespec;
132         st4->st_ctim = st->st_ctimespec;
133         st4->st_blksize = st->st_blksize;
134         st4->st_blocks = st->st_blocks;
135         strcpy(st4->st_fstype, "unknown");
136 }
137
138
139 static void
140 bsd_to_svr4_stat64(st, st4)
141         struct stat             *st;
142         struct svr4_stat64      *st4;
143 {
144         memset(st4, 0, sizeof(*st4));
145         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
146         st4->st_ino = st->st_ino;
147         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
148         st4->st_nlink = st->st_nlink;
149         st4->st_uid = st->st_uid;
150         st4->st_gid = st->st_gid;
151         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
152         st4->st_size = st->st_size;
153         st4->st_atim = st->st_atimespec;
154         st4->st_mtim = st->st_mtimespec;
155         st4->st_ctim = st->st_ctimespec;
156         st4->st_blksize = st->st_blksize;
157         st4->st_blocks = st->st_blocks;
158         strcpy(st4->st_fstype, "unknown");
159 }
160
161 int
162 svr4_sys_stat(td, uap)
163         struct thread *td;
164         struct svr4_sys_stat_args *uap;
165 {
166         struct svr4_stat svr4_st;
167         struct stat st;
168         char *path;
169         int error;
170
171         CHECKALTEXIST(td, uap->path, &path);
172
173         error = kern_stat(td, path, UIO_SYSSPACE, &st);
174         free(path, M_TEMP);
175         if (error)
176                 return (error);
177         bsd_to_svr4_stat(&st, &svr4_st);
178
179         if (S_ISSOCK(st.st_mode))
180                 (void) svr4_add_socket(td, uap->path, &st);
181
182         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
183 }
184
185
186 int
187 svr4_sys_lstat(td, uap)
188         register struct thread *td;
189         struct svr4_sys_lstat_args *uap;
190 {
191         struct svr4_stat svr4_st;
192         struct stat st;
193         char *path;
194         int error;
195
196         CHECKALTEXIST(td, uap->path, &path);
197
198         error = kern_lstat(td, path, UIO_SYSSPACE, &st);
199         free(path, M_TEMP);
200         if (error)
201                 return (error);
202         bsd_to_svr4_stat(&st, &svr4_st);
203
204         if (S_ISSOCK(st.st_mode))
205                 (void) svr4_add_socket(td, uap->path, &st);
206
207         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
208 }
209
210
211 int
212 svr4_sys_fstat(td, uap)
213         register struct thread *td;
214         struct svr4_sys_fstat_args *uap;
215 {
216         struct svr4_stat svr4_st;
217         struct stat st;
218         int error;
219
220
221         error = kern_fstat(td, uap->fd, &st);
222         if (error)
223                 return (error);
224         bsd_to_svr4_stat(&st, &svr4_st);
225         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
226 }
227
228
229 int
230 svr4_sys_xstat(td, uap)
231         register struct thread *td;
232         struct svr4_sys_xstat_args *uap;
233 {
234         struct svr4_xstat svr4_st;
235         struct stat st;
236         char *path;
237         int error;
238
239         CHECKALTEXIST(td, uap->path, &path);
240
241         error = kern_stat(td, path, UIO_SYSSPACE, &st);
242         free(path, M_TEMP);
243         if (error)
244                 return (error);
245
246         bsd_to_svr4_xstat(&st, &svr4_st);
247
248 #if defined(SOCKET_NOTYET)
249         if (S_ISSOCK(st.st_mode))
250                 (void) svr4_add_socket(td, uap->path, &st);
251 #endif
252
253         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
254 }
255
256 int
257 svr4_sys_lxstat(td, uap)
258         register struct thread *td;
259         struct svr4_sys_lxstat_args *uap;
260 {
261         struct svr4_xstat svr4_st;
262         struct stat st;
263         char *path;
264         int error;
265
266         CHECKALTEXIST(td, uap->path, &path);
267
268         error = kern_lstat(td, path, UIO_SYSSPACE, &st);
269         free(path, M_TEMP);
270         if (error)
271                 return (error);
272
273         bsd_to_svr4_xstat(&st, &svr4_st);
274
275 #if defined(SOCKET_NOTYET)
276         if (S_ISSOCK(st.st_mode))
277                 (void) svr4_add_socket(td, uap->path, &st);
278 #endif
279         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
280 }
281
282
283 int
284 svr4_sys_fxstat(td, uap)
285         register struct thread *td;
286         struct svr4_sys_fxstat_args *uap;
287 {
288         struct svr4_xstat svr4_st;
289         struct stat st;
290         int error;
291
292
293         error = kern_fstat(td, uap->fd, &st);
294         if (error)
295                 return (error);
296         bsd_to_svr4_xstat(&st, &svr4_st);
297         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
298 }
299
300 int
301 svr4_sys_stat64(td, uap)
302         register struct thread *td;
303         struct svr4_sys_stat64_args *uap;
304 {
305         struct svr4_stat64 svr4_st;
306         struct stat st;
307         char *path;
308         int error;
309
310         CHECKALTEXIST(td, uap->path, &path);
311
312         error = kern_stat(td, path, UIO_SYSSPACE, &st);
313         free(path, M_TEMP);
314         if (error)
315                 return (error);
316
317         bsd_to_svr4_stat64(&st, &svr4_st);
318
319         if (S_ISSOCK(st.st_mode))
320                 (void) svr4_add_socket(td, uap->path, &st);
321
322         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
323 }
324
325
326 int
327 svr4_sys_lstat64(td, uap)
328         register struct thread *td;
329         struct svr4_sys_lstat64_args *uap;
330 {
331         struct svr4_stat64 svr4_st;
332         struct stat st;
333         char *path;
334         int error;
335
336         CHECKALTEXIST(td, uap->path, &path);
337
338         error = kern_lstat(td, path, UIO_SYSSPACE, &st);
339         free(path, M_TEMP);
340         if (error)
341                 return (error);
342
343         bsd_to_svr4_stat64(&st, &svr4_st);
344
345         if (S_ISSOCK(st.st_mode))
346                 (void) svr4_add_socket(td, uap->path, &st);
347
348         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
349 }
350
351
352 int
353 svr4_sys_fstat64(td, uap)
354         register struct thread *td;
355         struct svr4_sys_fstat64_args *uap;
356 {
357         struct svr4_stat64 svr4_st;
358         struct stat st;
359         int error;
360
361         error = kern_fstat(td, uap->fd, &st);
362         if (error)
363                 return (error);
364         bsd_to_svr4_stat64(&st, &svr4_st);
365         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
366 }
367
368
369 int
370 svr4_ustat(td, uap)
371         register struct thread *td;
372         struct svr4_ustat_args *uap;
373 {
374         struct svr4_ustat       us;
375         int                     error;
376
377         memset(&us, 0, sizeof us);
378
379         /*
380          * XXX: should set f_tfree and f_tinode at least
381          * How do we translate dev -> fstat? (and then to svr4_ustat)
382          */
383         if ((error = copyout(&us, uap->name, sizeof us)) != 0)
384                 return (error);
385
386         return 0;
387 }
388
389 /*extern char ostype[], hostname[], osrelease[], version[], machine[];*/
390
391 int
392 svr4_sys_uname(td, uap)
393         register struct thread *td;
394         struct svr4_sys_uname_args *uap;
395 {
396         struct svr4_utsname     sut;
397         
398         memset(&sut, 0, sizeof(sut));
399
400         strlcpy(sut.sysname, ostype, sizeof(sut.sysname));
401         getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename));
402         strlcpy(sut.release, osrelease, sizeof(sut.release));
403         strlcpy(sut.version, version, sizeof(sut.version));
404         strlcpy(sut.machine, machine, sizeof(sut.machine));
405
406         return copyout((caddr_t) &sut, (caddr_t) uap->name,
407                        sizeof(struct svr4_utsname));
408 }
409
410 int
411 svr4_sys_systeminfo(td, uap)
412         struct thread *td;
413         struct svr4_sys_systeminfo_args *uap;
414 {
415         char            *str = NULL;
416         int             error = 0;
417         register_t      *retval = td->td_retval;
418         size_t          len = 0;
419         char            buf[1];   /* XXX NetBSD uses 256, but that seems
420                                      like awfully excessive kstack usage
421                                      for an empty string... */
422         u_int           rlen = uap->len;
423
424         switch (uap->what) {
425         case SVR4_SI_SYSNAME:
426                 str = ostype;
427                 break;
428
429         case SVR4_SI_HOSTNAME:
430                 str = V_hostname;
431                 break;
432
433         case SVR4_SI_RELEASE:
434                 str = osrelease;
435                 break;
436
437         case SVR4_SI_VERSION:
438                 str = version;
439                 break;
440
441         case SVR4_SI_MACHINE:
442                 str = machine;
443                 break;
444
445         case SVR4_SI_ARCHITECTURE:
446                 str = machine;
447                 break;
448
449         case SVR4_SI_HW_SERIAL:
450                 str = "0";
451                 break;
452
453         case SVR4_SI_HW_PROVIDER:
454                 str = ostype;
455                 break;
456
457         case SVR4_SI_SRPC_DOMAIN:
458                 /* XXXRW: locking? */
459                 str = V_domainname;
460                 break;
461
462         case SVR4_SI_PLATFORM:
463 #ifdef __i386__
464                 str = "i86pc";
465 #else
466                 str = "unknown";
467 #endif
468                 break;
469
470         case SVR4_SI_KERB_REALM:
471                 str = "unsupported";
472                 break;
473 #if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
474         case SVR4_SI_SET_HOSTNAME:
475                 name = KERN_HOSTNAME;
476                 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
477
478         case SVR4_SI_SET_SRPC_DOMAIN:
479                 name = KERN_NISDOMAINNAME;
480                 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
481 #else
482         case SVR4_SI_SET_HOSTNAME:
483         case SVR4_SI_SET_SRPC_DOMAIN:
484                 /* FALLTHROUGH */
485 #endif
486         case SVR4_SI_SET_KERB_REALM:
487                 return 0;
488
489         default:
490                 DPRINTF(("Bad systeminfo command %d\n", uap->what));
491                 return ENOSYS;
492         }
493
494         if (str) {
495                 len = strlen(str) + 1;
496                 if (len > rlen)
497                         len = rlen;
498
499                 if (uap->buf) {
500                         error = copyout(str, uap->buf, len);
501                         if (error)
502                                 return error;
503                         /* make sure we are NULL terminated */
504                         buf[0] = '\0';
505                         error = copyout(buf, &(uap->buf[len - 1]), 1);
506                 }
507                 else
508                         error = 0;
509         }
510         /* XXX NetBSD has hostname setting stuff here.  Why would an emulator
511            want to do that? */
512
513         *retval = len;
514         return error;
515 }
516
517 int
518 svr4_sys_utssys(td, uap)
519         register struct thread *td;
520         struct svr4_sys_utssys_args *uap;
521 {
522         switch (uap->sel) {
523         case 0:         /* uname(2)  */
524                 {
525                         struct svr4_sys_uname_args ua;
526                         ua.name = uap->a1;
527                         return svr4_sys_uname(td, &ua);
528                 }
529
530         case 2:         /* ustat(2)  */
531                 {
532                         struct svr4_ustat_args ua;
533                         ua.dev = (svr4_dev_t) uap->a2;
534                         ua.name = uap->a1;
535                         return svr4_ustat(td, &ua);
536                 }
537
538         case 3:         /* fusers(2) */
539                 return ENOSYS;
540
541         default:
542                 return ENOSYS;
543         }
544         return ENOSYS;
545 }
546
547
548 int
549 svr4_sys_utime(td, uap)
550         register struct thread *td;
551         struct svr4_sys_utime_args *uap;
552 {
553         struct svr4_utimbuf ub;
554         struct timeval tbuf[2], *tp;
555         char *path;
556         int error;
557      
558         if (uap->ubuf != NULL) {
559                 error = copyin(uap->ubuf, &ub, sizeof(ub));
560                 if (error)
561                         return (error);
562                 tbuf[0].tv_sec = ub.actime;
563                 tbuf[0].tv_usec = 0;
564                 tbuf[1].tv_sec = ub.modtime;
565                 tbuf[1].tv_usec = 0;
566                 tp = tbuf;
567         } else
568                 tp = NULL;
569
570         CHECKALTEXIST(td, uap->path, &path);
571         error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE);
572         free(path, M_TEMP);
573         return (error);
574 }
575
576
577 int
578 svr4_sys_utimes(td, uap)
579         register struct thread *td;
580         struct svr4_sys_utimes_args *uap;
581 {
582         char *path;
583         int error;
584
585         CHECKALTEXIST(td, uap->path, &path);
586         error = kern_utimes(td, path, UIO_SYSSPACE, uap->tptr, UIO_USERSPACE);
587         free(path, M_TEMP);
588         return (error);
589 }
590
591 static int
592 svr4_to_bsd_pathconf(name)
593         int name;
594 {
595         switch (name) {
596         case SVR4_PC_LINK_MAX:
597                 return _PC_LINK_MAX;
598
599         case SVR4_PC_MAX_CANON:
600                 return _PC_MAX_CANON;
601
602         case SVR4_PC_MAX_INPUT:
603                 return _PC_MAX_INPUT;
604
605         case SVR4_PC_NAME_MAX:
606                 return _PC_NAME_MAX;
607
608         case SVR4_PC_PATH_MAX:
609                 return _PC_PATH_MAX;
610
611         case SVR4_PC_PIPE_BUF:
612                 return _PC_PIPE_BUF;
613
614         case SVR4_PC_NO_TRUNC:
615                 return _PC_NO_TRUNC;
616
617         case SVR4_PC_VDISABLE:
618                 return _PC_VDISABLE;
619
620         case SVR4_PC_CHOWN_RESTRICTED:
621                 return _PC_CHOWN_RESTRICTED;
622         case SVR4_PC_SYNC_IO:
623 #if defined(_PC_SYNC_IO)
624                 return _PC_SYNC_IO;
625 #else
626                 return 0;
627 #endif
628         case SVR4_PC_ASYNC_IO:
629         case SVR4_PC_PRIO_IO:
630                 /* Not supported */
631                 return 0;
632
633         default:
634                 /* Invalid */
635                 return -1;
636         }
637 }
638
639
640 int
641 svr4_sys_pathconf(td, uap)
642         register struct thread *td;
643         struct svr4_sys_pathconf_args *uap;
644 {
645         char *path;
646         int error, name;
647
648         name = svr4_to_bsd_pathconf(uap->name);
649
650         switch (name) {
651         case -1:
652                 td->td_retval[0] = -1;
653                 return (EINVAL);
654         case 0:
655                 td->td_retval[0] = 0;
656                 return (0);
657         default:
658                 CHECKALTEXIST(td, uap->path, &path);
659                 error = kern_pathconf(td, path, UIO_SYSSPACE, name);
660                 free(path, M_TEMP);
661                 return (error);
662         }
663 }
664
665
666 int
667 svr4_sys_fpathconf(td, uap)
668         register struct thread *td;
669         struct svr4_sys_fpathconf_args *uap;
670 {
671         register_t      *retval = td->td_retval;
672
673         uap->name = svr4_to_bsd_pathconf(uap->name);
674
675         switch (uap->name) {
676         case -1:
677                 *retval = -1;
678                 return EINVAL;
679         case 0:
680                 *retval = 0;
681                 return 0;
682         default:
683                 return fpathconf(td, (struct fpathconf_args *)uap);
684         }
685 }