1 /* $NetBSD: ultrix_pathname.c,v 1.19 2003/08/07 16:30:48 agc Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratory. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * 41 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93 42 * 43 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp 44 */ 45 46 47 /* 48 * Ultrix emulation filesystem-namespace compatibility module. 49 * 50 * Ultrix system calls that examine the filesysten namespace 51 * are implemented here. Each system call has a wrapper that 52 * first checks if the given file exists at a special `emulation' 53 * pathname: the given path, prefixex with '/emul/ultrix', and 54 * if that pathname exists, it is used instead of the providd pathname. 55 * 56 * Used to locate OS-specific files (shared libraries, config files, 57 * etc) used by emul processes at their `normal' pathnames, without 58 * polluting, or conflicting with, the native filesysten namespace. 59 */ 60 61 #include <sys/cdefs.h> 62 __KERNEL_RCSID(0, "$NetBSD: ultrix_pathname.c,v 1.19 2003/08/07 16:30:48 agc Exp $"); 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/namei.h> 67 #include <sys/file.h> 68 #include <sys/filedesc.h> 69 #include <sys/ioctl.h> 70 #include <sys/mount.h> 71 #include <sys/stat.h> 72 #include <sys/vnode.h> 73 #include <sys/sa.h> 74 #include <sys/syscallargs.h> 75 #include <sys/proc.h> 76 77 #include <compat/ultrix/ultrix_syscallargs.h> 78 #include <compat/common/compat_util.h> 79 80 static int ultrixstatfs __P((struct statfs *sp, caddr_t buf)); 81 82 int 83 ultrix_sys_creat(l, v, retval) 84 struct lwp *l; 85 void *v; 86 register_t *retval; 87 { 88 struct ultrix_sys_creat_args *uap = v; 89 struct sys_open_args ap; 90 struct proc *p = l->l_proc; 91 92 caddr_t sg = stackgap_init(p, 0); 93 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 94 95 SCARG(&ap, path) = SCARG(uap, path); 96 SCARG(&ap, flags) = O_WRONLY | O_CREAT | O_TRUNC; 97 SCARG(&ap, mode) = SCARG(uap, mode); 98 99 return (sys_open(l, &ap, retval)); 100 } 101 102 103 int 104 ultrix_sys_access(l, v, retval) 105 struct lwp *l; 106 void *v; 107 register_t *retval; 108 { 109 struct ultrix_sys_access_args *uap = v; 110 struct proc *p = l->l_proc; 111 caddr_t sg = stackgap_init(p, 0); 112 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 113 114 return (sys_access(l, uap, retval)); 115 } 116 117 int 118 ultrix_sys_stat(l, v, retval) 119 struct lwp *l; 120 void *v; 121 register_t *retval; 122 { 123 struct ultrix_sys_stat_args *uap = v; 124 struct proc *p = l->l_proc; 125 caddr_t sg = stackgap_init(p, 0); 126 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 127 128 return (compat_43_sys_stat(l, uap, retval)); 129 } 130 131 int 132 ultrix_sys_lstat(l, v, retval) 133 struct lwp *l; 134 void *v; 135 register_t *retval; 136 { 137 struct ultrix_sys_lstat_args *uap = v; 138 struct proc *p = l->l_proc; 139 caddr_t sg = stackgap_init(p, 0); 140 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 141 142 return (compat_43_sys_lstat(l, uap, retval)); 143 } 144 145 int 146 ultrix_sys_execv(l, v, retval) 147 struct lwp *l; 148 void *v; 149 register_t *retval; 150 { 151 struct ultrix_sys_execv_args /* { 152 syscallarg(const char *) path; 153 syscallarg(char **) argv; 154 } */ *uap = v; 155 struct proc *p = l->l_proc; 156 struct sys_execve_args ap; 157 caddr_t sg; 158 159 sg = stackgap_init(p, 0); 160 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 161 162 SCARG(&ap, path) = SCARG(uap, path); 163 SCARG(&ap, argp) = SCARG(uap, argp); 164 SCARG(&ap, envp) = NULL; 165 166 return (sys_execve(l, &ap, retval)); 167 } 168 169 int 170 ultrix_sys_execve(l, v, retval) 171 struct lwp *l; 172 void *v; 173 register_t *retval; 174 { 175 struct ultrix_sys_execve_args /* { 176 syscallarg(const char *) path; 177 syscallarg(char **) argv; 178 syscallarg(char **) envp; 179 } */ *uap = v; 180 struct proc *p = l->l_proc; 181 struct sys_execve_args ap; 182 caddr_t sg; 183 184 sg = stackgap_init(p, 0); 185 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 186 187 SCARG(&ap, path) = SCARG(uap, path); 188 SCARG(&ap, argp) = SCARG(uap, argp); 189 SCARG(&ap, envp) = SCARG(uap, envp); 190 191 return (sys_execve(l, &ap, retval)); 192 } 193 194 int 195 ultrix_sys_open(l, v, retval) 196 struct lwp *l; 197 void *v; 198 register_t *retval; 199 { 200 struct ultrix_sys_open_args *uap = v; 201 struct proc *p = l->l_proc; 202 int q, r; 203 int noctty; 204 int ret; 205 206 caddr_t sg = stackgap_init(p, 0); 207 208 /* convert open flags into NetBSD flags */ 209 q = SCARG(uap, flags); 210 noctty = q & 0x8000; 211 r = (q & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800)); 212 r |= ((q & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0); 213 r |= ((q & 0x0080) ? O_SHLOCK : 0); 214 r |= ((q & 0x0100) ? O_EXLOCK : 0); 215 r |= ((q & 0x2000) ? O_FSYNC : 0); 216 217 if (r & O_CREAT) 218 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 219 else 220 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 221 SCARG(uap, flags) = r; 222 ret = sys_open(l, (struct sys_open_args *)uap, retval); 223 224 if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { 225 struct filedesc *fdp = p->p_fd; 226 struct file *fp; 227 228 fp = fd_getfile(fdp, *retval); 229 230 /* ignore any error, just give it a try */ 231 if (fp != NULL && fp->f_type == DTYPE_VNODE) 232 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p); 233 } 234 return ret; 235 } 236 237 238 struct ultrix_statfs { 239 long f_type; /* type of info, zero for now */ 240 long f_bsize; /* fundamental file system block size */ 241 long f_blocks; /* total blocks in file system */ 242 long f_bfree; /* free blocks */ 243 long f_bavail; /* free blocks available to non-super-user */ 244 long f_files; /* total file nodes in file system */ 245 long f_ffree; /* free file nodes in fs */ 246 fsid_t f_fsid; /* file system id */ 247 long f_spare[7]; /* spare for later */ 248 }; 249 250 /* 251 * Custruct ultrix statfs result from native. 252 * XXX should this be the same as returned by Ultrix getmnt(2)? 253 * XXX Ultrix predates DEV_BSIZE. Is conversion of disk space from 1k 254 * block units to DEV_BSIZE necessary? 255 */ 256 static int 257 ultrixstatfs(sp, buf) 258 struct statfs *sp; 259 caddr_t buf; 260 { 261 struct ultrix_statfs ssfs; 262 263 memset(&ssfs, 0, sizeof ssfs); 264 ssfs.f_type = 0; 265 ssfs.f_bsize = sp->f_bsize; 266 ssfs.f_blocks = sp->f_blocks; 267 ssfs.f_bfree = sp->f_bfree; 268 ssfs.f_bavail = sp->f_bavail; 269 ssfs.f_files = sp->f_files; 270 ssfs.f_ffree = sp->f_ffree; 271 ssfs.f_fsid = sp->f_fsid; 272 return copyout((caddr_t)&ssfs, buf, sizeof ssfs); 273 } 274 275 276 int 277 ultrix_sys_statfs(l, v, retval) 278 struct lwp *l; 279 void *v; 280 register_t *retval; 281 { 282 struct ultrix_sys_statfs_args *uap = v; 283 struct proc *p = l->l_proc; 284 struct mount *mp; 285 struct statfs *sp; 286 int error; 287 struct nameidata nd; 288 289 caddr_t sg = stackgap_init(p, 0); 290 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 291 292 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 293 if ((error = namei(&nd)) != 0) 294 return (error); 295 296 mp = nd.ni_vp->v_mount; 297 sp = &mp->mnt_stat; 298 vrele(nd.ni_vp); 299 if ((error = VFS_STATFS(mp, sp, p)) != 0) 300 return (error); 301 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 302 return ultrixstatfs(sp, (caddr_t)SCARG(uap, buf)); 303 } 304 305 /* 306 * sys_fstatfs() takes an fd, not a path, and so needs no emul 307 * pathname processing; but it's similar enough to sys_statfs() that 308 * it goes here anyway. 309 */ 310 int 311 ultrix_sys_fstatfs(l, v, retval) 312 struct lwp *l; 313 void *v; 314 register_t *retval; 315 { 316 struct ultrix_sys_fstatfs_args *uap = v; 317 struct proc *p = l->l_proc; 318 struct file *fp; 319 struct mount *mp; 320 struct statfs *sp; 321 int error; 322 323 /* getvnode() will use the descriptor for us */ 324 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 325 return (error); 326 mp = ((struct vnode *)fp->f_data)->v_mount; 327 sp = &mp->mnt_stat; 328 if ((error = VFS_STATFS(mp, sp, p)) != 0) 329 goto out; 330 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 331 error = ultrixstatfs(sp, (caddr_t)SCARG(uap, buf)); 332 out: 333 FILE_UNUSE(fp, p); 334 return (error); 335 } 336 337 int 338 ultrix_sys_mknod(l, v, retval) 339 struct lwp *l; 340 void *v; 341 register_t *retval; 342 { 343 struct ultrix_sys_mknod_args *uap = v; 344 struct proc *p = l->l_proc; 345 346 caddr_t sg = stackgap_init(p, 0); 347 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 348 349 if (S_ISFIFO(SCARG(uap, mode))) 350 return sys_mkfifo(l, uap, retval); 351 352 return sys_mknod(l, (struct sys_mknod_args *)uap, retval); 353 } 354