1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/errno.h> 30 #include <sys/syscall.h> 31 #include <sys/fcntl.h> 32 #include <sys/stat.h> 33 #include <sys/param.h> 34 #include "compat.h" 35 #include "s5sysmacros.h" 36 37 #define ST_FSTYPSZ 16 /* array size for file system type name */ 38 39 struct ts { 40 long tv_sec; /* seconds */ 41 long tv_nsec; /* nanoseconds */ 42 }; 43 44 struct n_stat { 45 unsigned long st_dev; 46 long st_pad1[3]; /* reserved for network id */ 47 unsigned long st_ino; 48 unsigned long st_mode; 49 unsigned long st_nlink; 50 long st_uid; 51 long st_gid; 52 unsigned long st_rdev; 53 long st_pad2[2]; 54 long st_size; 55 long st_pad3; /* future off_t expansion */ 56 struct ts st_atim; 57 struct ts st_mtim; 58 struct ts st_ctim; 59 long st_blksize; 60 long st_blocks; 61 char st_fstype[ST_FSTYPSZ]; 62 long st_pad4[8]; /* expansion area */ 63 64 }; 65 66 static void cpstatbuf(struct stat *, struct n_stat *); 67 68 int 69 fstat(int fd, struct stat *buf) 70 { 71 return (bc_fstat(fd, buf)); 72 } 73 74 int 75 bc_fstat(int fd, struct stat *buf) 76 { 77 int ret; 78 struct n_stat nb; 79 extern int errno; 80 81 if (buf == 0) { 82 errno = EFAULT; 83 return (-1); 84 } 85 86 if ((ret = _syscall(SYS_fstat, fd, &nb)) == -1) 87 return (ret); 88 89 cpstatbuf(buf, &nb); 90 if (fd_get(fd) != -1) { 91 buf->st_size = getmodsize(buf->st_size, 92 sizeof (struct utmpx), sizeof(struct compat_utmp)); 93 } 94 95 return (ret); 96 } 97 98 int 99 stat_com(int sysnum, char *path, struct stat *buf) 100 { 101 int fd, ret; 102 struct n_stat nb; 103 104 if (strcmp(path, "/etc/mtab") == 0) { 105 /* 106 * stat the real mnttab, or the "parsed" mtab 107 * created by open? 108 * 109 * for now, stat the real mnttab. 110 */ 111 112 /* 113 * fd = open_mnt("/etc/mnttab", "mtab", O_RDONLY); 114 * ret = fstat(fd, buf); 115 * close(fd); 116 * return(ret); 117 */ 118 ret = stat_com(sysnum, "/etc/mnttab", buf); 119 return(ret); 120 } 121 if (strcmp(path, "/etc/fstab") == 0) { 122 fd = open_mnt("/etc/vfstab", "fstab", O_RDONLY); 123 if (fd < 0) 124 ret = -1; 125 else { 126 ret = fstat(fd, buf); 127 close(fd); 128 } 129 return(ret); 130 } 131 if (strcmp(path, "/etc/utmp") == 0 || 132 strcmp(path, "/var/adm/utmp") == 0) { 133 if ((ret = _syscall(sysnum, "/var/adm/utmpx", &nb)) != -1) { 134 cpstatbuf(buf, &nb); 135 buf->st_size = getmodsize(buf->st_size, 136 sizeof(struct utmpx), sizeof(struct compat_utmp)); 137 } 138 return(ret); 139 } 140 if (strcmp(path, "/var/adm/wtmp") == 0) { 141 if ((ret = _syscall(sysnum, "/var/adm/wtmpx", &nb)) != -1) { 142 cpstatbuf(buf, &nb); 143 buf->st_size = getmodsize(buf->st_size, 144 sizeof(struct utmpx), sizeof(struct compat_utmp)); 145 } 146 return(ret); 147 } 148 if (_strstr(path, "/lib/locale/") != 0) { 149 fd = open(path, O_RDONLY); 150 if (fd < 0) 151 ret = -1; 152 else { 153 ret = fstat(fd, buf); 154 close(fd); 155 } 156 return(ret); 157 } 158 159 if ((ret = _syscall(sysnum, path, &nb)) != -1) 160 cpstatbuf(buf, &nb); 161 return(ret); 162 } 163 164 165 /* 166 * Common code to copy xstat buf to BSD style buf 167 */ 168 static void 169 cpstatbuf(struct stat *bsdbuf, struct n_stat *nbuf) 170 { 171 bsdbuf->st_dev = (dev_t) cmpdev(nbuf->st_dev); 172 bsdbuf->st_ino = nbuf->st_ino; 173 bsdbuf->st_mode = (unsigned short) nbuf->st_mode; 174 bsdbuf->st_nlink = (short) nbuf->st_nlink; 175 176 if ((unsigned long)nbuf->st_uid > 0xffff) 177 bsdbuf->st_uid = 60001; /* UID_NOBODY */ 178 else 179 bsdbuf->st_uid = (uid_t) nbuf->st_uid; 180 181 if ((unsigned long)nbuf->st_gid > 0xffff) 182 bsdbuf->st_gid = 60001; /* GID_NOBODY */ 183 else 184 bsdbuf->st_gid = (gid_t) nbuf->st_gid; 185 186 bsdbuf->st_rdev = (dev_t) cmpdev(nbuf->st_rdev); 187 bsdbuf->st_size = nbuf->st_size; 188 bsdbuf->st_atime = nbuf->st_atim.tv_sec; 189 bsdbuf->st_mtime = nbuf->st_mtim.tv_sec; 190 bsdbuf->st_ctime = nbuf->st_ctim.tv_sec; 191 bsdbuf->st_blksize = nbuf->st_blksize; 192 bsdbuf->st_blocks = nbuf->st_blocks; 193 } 194