]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/svr4/svr4_stat.c
Merge ^/vendor/NetBSD/tests/dist@r312294
[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/fcntl.h>
38 #include <sys/jail.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/namei.h>
42 #include <sys/unistd.h>
43 #include <sys/time.h>
44 #include <sys/syscallsubr.h>
45 #include <sys/sysctl.h>
46 #include <sys/sysproto.h>
47 #include <sys/un.h>
48
49 #include <vm/vm.h>
50
51 #include <netinet/in.h>
52
53 #include <compat/svr4/svr4.h>
54 #include <compat/svr4/svr4_types.h>
55 #include <compat/svr4/svr4_signal.h>
56 #include <compat/svr4/svr4_proto.h>
57 #include <compat/svr4/svr4_util.h>
58 #include <compat/svr4/svr4_stat.h>
59 #include <compat/svr4/svr4_ustat.h>
60 #include <compat/svr4/svr4_utsname.h>
61 #include <compat/svr4/svr4_systeminfo.h>
62 #include <compat/svr4/svr4_socket.h>
63 #include <compat/svr4/svr4_time.h>
64 #if defined(NOTYET)
65 #include "svr4_fuser.h"
66 #endif
67
68 #ifdef sparc
69 /* 
70  * Solaris-2.4 on the sparc has the old stat call using the new
71  * stat data structure...
72  */
73 # define SVR4_NO_OSTAT
74 #endif
75
76 struct svr4_ustat_args {
77         svr4_dev_t              dev;
78         struct svr4_ustat * name;
79 };
80
81 static void bsd_to_svr4_xstat(struct stat *, struct svr4_xstat *);
82 static void bsd_to_svr4_stat64(struct stat *, struct svr4_stat64 *);
83 int svr4_ustat(struct thread *, struct svr4_ustat_args *);
84 static int svr4_to_bsd_pathconf(int);
85
86 /*
87  * SVR4 uses named pipes as named sockets, so we tell programs
88  * that sockets are named pipes with mode 0
89  */
90 #define BSD_TO_SVR4_MODE(mode) (S_ISSOCK(mode) ? S_IFIFO : (mode))
91
92
93 #ifndef SVR4_NO_OSTAT
94 static void bsd_to_svr4_stat(struct stat *, struct svr4_stat *);
95
96 static void
97 bsd_to_svr4_stat(st, st4)
98         struct stat             *st;
99         struct svr4_stat        *st4;
100 {
101         memset(st4, 0, sizeof(*st4));
102         st4->st_dev = bsd_to_svr4_odev_t(st->st_dev);
103         st4->st_ino = st->st_ino;
104         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
105         st4->st_nlink = st->st_nlink;
106         st4->st_uid = st->st_uid;
107         st4->st_gid = st->st_gid;
108         st4->st_rdev = bsd_to_svr4_odev_t(st->st_rdev);
109         st4->st_size = st->st_size;
110         st4->st_atim = st->st_atim.tv_sec;
111         st4->st_mtim = st->st_mtim.tv_sec;
112         st4->st_ctim = st->st_ctim.tv_sec;
113 }
114 #endif
115
116
117 static void
118 bsd_to_svr4_xstat(st, st4)
119         struct stat             *st;
120         struct svr4_xstat       *st4;
121 {
122         memset(st4, 0, sizeof(*st4));
123         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
124         st4->st_ino = st->st_ino;
125         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
126         st4->st_nlink = st->st_nlink;
127         st4->st_uid = st->st_uid;
128         st4->st_gid = st->st_gid;
129         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
130         st4->st_size = st->st_size;
131         st4->st_atim = st->st_atim;
132         st4->st_mtim = st->st_mtim;
133         st4->st_ctim = st->st_ctim;
134         st4->st_blksize = st->st_blksize;
135         st4->st_blocks = st->st_blocks;
136         strcpy(st4->st_fstype, "unknown");
137 }
138
139
140 static void
141 bsd_to_svr4_stat64(st, st4)
142         struct stat             *st;
143         struct svr4_stat64      *st4;
144 {
145         memset(st4, 0, sizeof(*st4));
146         st4->st_dev = bsd_to_svr4_dev_t(st->st_dev);
147         st4->st_ino = st->st_ino;
148         st4->st_mode = BSD_TO_SVR4_MODE(st->st_mode);
149         st4->st_nlink = st->st_nlink;
150         st4->st_uid = st->st_uid;
151         st4->st_gid = st->st_gid;
152         st4->st_rdev = bsd_to_svr4_dev_t(st->st_rdev);
153         st4->st_size = st->st_size;
154         st4->st_atim = st->st_atim;
155         st4->st_mtim = st->st_mtim;
156         st4->st_ctim = st->st_ctim;
157         st4->st_blksize = st->st_blksize;
158         st4->st_blocks = st->st_blocks;
159         strcpy(st4->st_fstype, "unknown");
160 }
161
162 int
163 svr4_sys_stat(td, uap)
164         struct thread *td;
165         struct svr4_sys_stat_args *uap;
166 {
167         struct svr4_stat svr4_st;
168         struct stat st;
169         char *path;
170         int error;
171
172         CHECKALTEXIST(td, uap->path, &path);
173
174         error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
175         free(path, M_TEMP);
176         if (error)
177                 return (error);
178         bsd_to_svr4_stat(&st, &svr4_st);
179
180         if (S_ISSOCK(st.st_mode))
181                 (void) svr4_add_socket(td, uap->path, &st);
182
183         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
184 }
185
186
187 int
188 svr4_sys_lstat(td, uap)
189         struct thread *td;
190         struct svr4_sys_lstat_args *uap;
191 {
192         struct svr4_stat svr4_st;
193         struct stat st;
194         char *path;
195         int error;
196
197         CHECKALTEXIST(td, uap->path, &path);
198
199         error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
200             UIO_SYSSPACE, &st, NULL);
201         free(path, M_TEMP);
202         if (error)
203                 return (error);
204         bsd_to_svr4_stat(&st, &svr4_st);
205
206         if (S_ISSOCK(st.st_mode))
207                 (void) svr4_add_socket(td, uap->path, &st);
208
209         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
210 }
211
212
213 int
214 svr4_sys_fstat(td, uap)
215         struct thread *td;
216         struct svr4_sys_fstat_args *uap;
217 {
218         struct svr4_stat svr4_st;
219         struct stat st;
220         int error;
221
222
223         error = kern_fstat(td, uap->fd, &st);
224         if (error)
225                 return (error);
226         bsd_to_svr4_stat(&st, &svr4_st);
227         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
228 }
229
230
231 int
232 svr4_sys_xstat(td, uap)
233         struct thread *td;
234         struct svr4_sys_xstat_args *uap;
235 {
236         struct svr4_xstat svr4_st;
237         struct stat st;
238         char *path;
239         int error;
240
241         CHECKALTEXIST(td, uap->path, &path);
242
243         error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
244         free(path, M_TEMP);
245         if (error)
246                 return (error);
247
248         bsd_to_svr4_xstat(&st, &svr4_st);
249
250 #if defined(SOCKET_NOTYET)
251         if (S_ISSOCK(st.st_mode))
252                 (void) svr4_add_socket(td, uap->path, &st);
253 #endif
254
255         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
256 }
257
258 int
259 svr4_sys_lxstat(td, uap)
260         struct thread *td;
261         struct svr4_sys_lxstat_args *uap;
262 {
263         struct svr4_xstat svr4_st;
264         struct stat st;
265         char *path;
266         int error;
267
268         CHECKALTEXIST(td, uap->path, &path);
269
270         error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
271             UIO_SYSSPACE, &st, NULL);
272         free(path, M_TEMP);
273         if (error)
274                 return (error);
275
276         bsd_to_svr4_xstat(&st, &svr4_st);
277
278 #if defined(SOCKET_NOTYET)
279         if (S_ISSOCK(st.st_mode))
280                 (void) svr4_add_socket(td, uap->path, &st);
281 #endif
282         return (copyout(&svr4_st, uap->ub, sizeof svr4_st));
283 }
284
285
286 int
287 svr4_sys_fxstat(td, uap)
288         struct thread *td;
289         struct svr4_sys_fxstat_args *uap;
290 {
291         struct svr4_xstat svr4_st;
292         struct stat st;
293         int error;
294
295
296         error = kern_fstat(td, uap->fd, &st);
297         if (error)
298                 return (error);
299         bsd_to_svr4_xstat(&st, &svr4_st);
300         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
301 }
302
303 int
304 svr4_sys_stat64(td, uap)
305         struct thread *td;
306         struct svr4_sys_stat64_args *uap;
307 {
308         struct svr4_stat64 svr4_st;
309         struct stat st;
310         char *path;
311         int error;
312
313         CHECKALTEXIST(td, uap->path, &path);
314
315         error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL);
316         free(path, M_TEMP);
317         if (error)
318                 return (error);
319
320         bsd_to_svr4_stat64(&st, &svr4_st);
321
322         if (S_ISSOCK(st.st_mode))
323                 (void) svr4_add_socket(td, uap->path, &st);
324
325         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
326 }
327
328
329 int
330 svr4_sys_lstat64(td, uap)
331         struct thread *td;
332         struct svr4_sys_lstat64_args *uap;
333 {
334         struct svr4_stat64 svr4_st;
335         struct stat st;
336         char *path;
337         int error;
338
339         CHECKALTEXIST(td, uap->path, &path);
340
341         error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path,
342             UIO_SYSSPACE, &st, NULL);
343         free(path, M_TEMP);
344         if (error)
345                 return (error);
346
347         bsd_to_svr4_stat64(&st, &svr4_st);
348
349         if (S_ISSOCK(st.st_mode))
350                 (void) svr4_add_socket(td, uap->path, &st);
351
352         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
353 }
354
355
356 int
357 svr4_sys_fstat64(td, uap)
358         struct thread *td;
359         struct svr4_sys_fstat64_args *uap;
360 {
361         struct svr4_stat64 svr4_st;
362         struct stat st;
363         int error;
364
365         error = kern_fstat(td, uap->fd, &st);
366         if (error)
367                 return (error);
368         bsd_to_svr4_stat64(&st, &svr4_st);
369         return (copyout(&svr4_st, uap->sb, sizeof svr4_st));
370 }
371
372
373 int
374 svr4_ustat(td, uap)
375         struct thread *td;
376         struct svr4_ustat_args *uap;
377 {
378         struct svr4_ustat       us;
379         int                     error;
380
381         memset(&us, 0, sizeof us);
382
383         /*
384          * XXX: should set f_tfree and f_tinode at least
385          * How do we translate dev -> fstat? (and then to svr4_ustat)
386          */
387         if ((error = copyout(&us, uap->name, sizeof us)) != 0)
388                 return (error);
389
390         return 0;
391 }
392
393 /*extern char ostype[], osrelease[], version[], machine[];*/
394
395 int
396 svr4_sys_uname(td, uap)
397         struct thread *td;
398         struct svr4_sys_uname_args *uap;
399 {
400         struct svr4_utsname     sut;
401         
402         memset(&sut, 0, sizeof(sut));
403
404         strlcpy(sut.sysname, ostype, sizeof(sut.sysname));
405         getcredhostname(td->td_ucred, sut.nodename, sizeof(sut.nodename));
406         strlcpy(sut.release, osrelease, sizeof(sut.release));
407         strlcpy(sut.version, version, sizeof(sut.version));
408         strlcpy(sut.machine, machine, sizeof(sut.machine));
409
410         return copyout((caddr_t) &sut, (caddr_t) uap->name,
411                        sizeof(struct svr4_utsname));
412 }
413
414 int
415 svr4_sys_systeminfo(td, uap)
416         struct thread *td;
417         struct svr4_sys_systeminfo_args *uap;
418 {
419         char            *str = NULL;
420         int             error = 0;
421         register_t      *retval = td->td_retval;
422         u_long          hostid;
423         size_t          len = 0;
424         char            buf[MAXHOSTNAMELEN];
425         u_int           rlen = uap->len;
426
427         switch (uap->what) {
428         case SVR4_SI_SYSNAME:
429                 str = ostype;
430                 break;
431
432         case SVR4_SI_HOSTNAME:
433                 getcredhostname(td->td_ucred, buf, sizeof(buf));
434                 str = buf;
435                 break;
436
437         case SVR4_SI_RELEASE:
438                 str = osrelease;
439                 break;
440
441         case SVR4_SI_VERSION:
442                 str = version;
443                 break;
444
445         case SVR4_SI_MACHINE:
446                 str = machine;
447                 break;
448
449         case SVR4_SI_ARCHITECTURE:
450                 str = machine;
451                 break;
452
453         case SVR4_SI_ISALIST:
454 #if defined(__sparc__)
455                 str = "sparcv9 sparcv9-fsmuld sparcv8 sparcv8-fsmuld sparcv7 sparc";
456 #elif defined(__i386__)
457                 str = "i386";
458 #elif defined(__amd64__)
459                 str = "amd64";
460 #else
461                 str = "unknown";
462 #endif
463                 break;
464
465         case SVR4_SI_HW_SERIAL:
466                 getcredhostid(td->td_ucred, &hostid);
467                 snprintf(buf, sizeof(buf), "%lu", hostid);
468                 str = buf;
469                 break;
470
471         case SVR4_SI_HW_PROVIDER:
472                 str = ostype;
473                 break;
474
475         case SVR4_SI_SRPC_DOMAIN:
476                 getcreddomainname(td->td_ucred, buf, sizeof(buf));
477                 str = buf;
478                 break;
479
480         case SVR4_SI_PLATFORM:
481 #if defined(__i386__)
482                 str = "i86pc";
483 #else
484                 str = "unknown";
485 #endif
486                 break;
487
488         case SVR4_SI_KERB_REALM:
489                 str = "unsupported";
490                 break;
491 #if defined(WHY_DOES_AN_EMULATOR_WANT_TO_SET_HOSTNAMES)
492         case SVR4_SI_SET_HOSTNAME:
493                 name = KERN_HOSTNAME;
494                 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
495
496         case SVR4_SI_SET_SRPC_DOMAIN:
497                 name = KERN_NISDOMAINNAME;
498                 return kern_sysctl(&name, 1, 0, 0, uap->buf, rlen, td);
499 #else
500         case SVR4_SI_SET_HOSTNAME:
501         case SVR4_SI_SET_SRPC_DOMAIN:
502                 /* FALLTHROUGH */
503 #endif
504         case SVR4_SI_SET_KERB_REALM:
505                 return 0;
506
507         default:
508                 DPRINTF(("Bad systeminfo command %d\n", uap->what));
509                 return ENOSYS;
510         }
511
512         if (str) {
513                 len = strlen(str) + 1;
514                 if (len > rlen)
515                         len = rlen;
516
517                 if (uap->buf) {
518                         error = copyout(str, uap->buf, len);
519                         if (error)
520                                 return error;
521                         /* make sure we are NULL terminated */
522                         buf[0] = '\0';
523                         error = copyout(buf, &(uap->buf[len - 1]), 1);
524                 }
525                 else
526                         error = 0;
527         }
528         /* XXX NetBSD has hostname setting stuff here.  Why would an emulator
529            want to do that? */
530
531         *retval = len;
532         return error;
533 }
534
535 int
536 svr4_sys_utssys(td, uap)
537         struct thread *td;
538         struct svr4_sys_utssys_args *uap;
539 {
540         switch (uap->sel) {
541         case 0:         /* uname(2)  */
542                 {
543                         struct svr4_sys_uname_args ua;
544                         ua.name = uap->a1;
545                         return svr4_sys_uname(td, &ua);
546                 }
547
548         case 2:         /* ustat(2)  */
549                 {
550                         struct svr4_ustat_args ua;
551                         ua.dev = (svr4_dev_t) uap->a2;
552                         ua.name = uap->a1;
553                         return svr4_ustat(td, &ua);
554                 }
555
556         case 3:         /* fusers(2) */
557                 return ENOSYS;
558
559         default:
560                 return ENOSYS;
561         }
562         return ENOSYS;
563 }
564
565
566 int
567 svr4_sys_utime(td, uap)
568         struct thread *td;
569         struct svr4_sys_utime_args *uap;
570 {
571         struct svr4_utimbuf ub;
572         struct timeval tbuf[2], *tp;
573         char *path;
574         int error;
575      
576         if (uap->ubuf != NULL) {
577                 error = copyin(uap->ubuf, &ub, sizeof(ub));
578                 if (error)
579                         return (error);
580                 tbuf[0].tv_sec = ub.actime;
581                 tbuf[0].tv_usec = 0;
582                 tbuf[1].tv_sec = ub.modtime;
583                 tbuf[1].tv_usec = 0;
584                 tp = tbuf;
585         } else
586                 tp = NULL;
587
588         CHECKALTEXIST(td, uap->path, &path);
589         error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE,
590             tp, UIO_SYSSPACE);
591         free(path, M_TEMP);
592         return (error);
593 }
594
595
596 int
597 svr4_sys_utimes(td, uap)
598         struct thread *td;
599         struct svr4_sys_utimes_args *uap;
600 {
601         char *path;
602         int error;
603
604         CHECKALTEXIST(td, uap->path, &path);
605         error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE,
606             uap->tptr, UIO_USERSPACE);
607         free(path, M_TEMP);
608         return (error);
609 }
610
611 static int
612 svr4_to_bsd_pathconf(name)
613         int name;
614 {
615         switch (name) {
616         case SVR4_PC_LINK_MAX:
617                 return _PC_LINK_MAX;
618
619         case SVR4_PC_MAX_CANON:
620                 return _PC_MAX_CANON;
621
622         case SVR4_PC_MAX_INPUT:
623                 return _PC_MAX_INPUT;
624
625         case SVR4_PC_NAME_MAX:
626                 return _PC_NAME_MAX;
627
628         case SVR4_PC_PATH_MAX:
629                 return _PC_PATH_MAX;
630
631         case SVR4_PC_PIPE_BUF:
632                 return _PC_PIPE_BUF;
633
634         case SVR4_PC_NO_TRUNC:
635                 return _PC_NO_TRUNC;
636
637         case SVR4_PC_VDISABLE:
638                 return _PC_VDISABLE;
639
640         case SVR4_PC_CHOWN_RESTRICTED:
641                 return _PC_CHOWN_RESTRICTED;
642         case SVR4_PC_SYNC_IO:
643 #if defined(_PC_SYNC_IO)
644                 return _PC_SYNC_IO;
645 #else
646                 return 0;
647 #endif
648         case SVR4_PC_ASYNC_IO:
649         case SVR4_PC_PRIO_IO:
650                 /* Not supported */
651                 return 0;
652
653         default:
654                 /* Invalid */
655                 return -1;
656         }
657 }
658
659
660 int
661 svr4_sys_pathconf(td, uap)
662         struct thread *td;
663         struct svr4_sys_pathconf_args *uap;
664 {
665         char *path;
666         int error, name;
667
668         name = svr4_to_bsd_pathconf(uap->name);
669
670         switch (name) {
671         case -1:
672                 td->td_retval[0] = -1;
673                 return (EINVAL);
674         case 0:
675                 td->td_retval[0] = 0;
676                 return (0);
677         default:
678                 CHECKALTEXIST(td, uap->path, &path);
679                 error = kern_pathconf(td, path, UIO_SYSSPACE, name, FOLLOW);
680                 free(path, M_TEMP);
681                 return (error);
682         }
683 }
684
685
686 int
687 svr4_sys_fpathconf(td, uap)
688         struct thread *td;
689         struct svr4_sys_fpathconf_args *uap;
690 {
691         register_t      *retval = td->td_retval;
692
693         uap->name = svr4_to_bsd_pathconf(uap->name);
694
695         switch (uap->name) {
696         case -1:
697                 *retval = -1;
698                 return EINVAL;
699         case 0:
700                 *retval = 0;
701                 return 0;
702         default:
703                 return sys_fpathconf(td, (struct fpathconf_args *)uap);
704         }
705 }