ibcs2_util.c revision 139799
1139799Simp/*- 211394Sswallace * Copyright (c) 1994 Christos Zoulas 311394Sswallace * Copyright (c) 1995 Frank van der Linden 411394Sswallace * Copyright (c) 1995 Scott Bartram 511394Sswallace * All rights reserved. 611394Sswallace * 711394Sswallace * Redistribution and use in source and binary forms, with or without 811394Sswallace * modification, are permitted provided that the following conditions 911394Sswallace * are met: 1011394Sswallace * 1. Redistributions of source code must retain the above copyright 1111394Sswallace * notice, this list of conditions and the following disclaimer. 1211394Sswallace * 2. Redistributions in binary form must reproduce the above copyright 1311394Sswallace * notice, this list of conditions and the following disclaimer in the 1411394Sswallace * documentation and/or other materials provided with the distribution. 1511394Sswallace * 3. The name of the author may not be used to endorse or promote products 1611394Sswallace * derived from this software without specific prior written permission 1711394Sswallace * 1811394Sswallace * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1911394Sswallace * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2011394Sswallace * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2111394Sswallace * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2211394Sswallace * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2311394Sswallace * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2411394Sswallace * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2511394Sswallace * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2611394Sswallace * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2711394Sswallace * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811394Sswallace * 2911394Sswallace * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp 3011394Sswallace */ 3111394Sswallace 32115684Sobrien#include <sys/cdefs.h> 33115684Sobrien__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_util.c 139799 2005-01-06 23:22:04Z imp $"); 34115684Sobrien 3511394Sswallace#include <sys/param.h> 3611394Sswallace#include <sys/systm.h> 3711394Sswallace#include <sys/namei.h> 3811394Sswallace#include <sys/malloc.h> 3911394Sswallace#include <sys/vnode.h> 4011394Sswallace 4111397Sswallace#include <i386/ibcs2/ibcs2_util.h> 4211394Sswallace 4354655Seivind 4411414Sswallaceconst char ibcs2_emul_path[] = "/compat/ibcs2"; 4511394Sswallace 4611394Sswallace/* 4711394Sswallace * Search an alternate path before passing pathname arguments on 4872091Sasmodai * to system calls. Useful for keeping a separate 'emulation tree'. 4911394Sswallace * 5011394Sswallace * If cflag is set, we check if an attempt can be made to create 5111394Sswallace * the named file, i.e. we check if the directory it should 5211394Sswallace * be in exists. 5311394Sswallace */ 5411394Sswallaceint 5583366Sjulianibcs2_emul_find(td, sgp, prefix, path, pbuf, cflag) 5683366Sjulian struct thread *td; 5711394Sswallace caddr_t *sgp; /* Pointer to stackgap memory */ 5811394Sswallace const char *prefix; 5911394Sswallace char *path; 6011394Sswallace char **pbuf; 6111394Sswallace int cflag; 6211394Sswallace{ 6311394Sswallace struct nameidata nd; 6411394Sswallace struct nameidata ndroot; 6511394Sswallace struct vattr vat; 6611394Sswallace struct vattr vatroot; 6711394Sswallace int error; 6811394Sswallace char *ptr, *buf, *cp; 6911394Sswallace size_t sz, len; 7011394Sswallace 71111119Simp buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 7211394Sswallace *pbuf = path; 7311394Sswallace 7411394Sswallace for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++) 7511394Sswallace continue; 7611394Sswallace 7711394Sswallace sz = MAXPATHLEN - (ptr - buf); 7811394Sswallace 7911394Sswallace /* 8011394Sswallace * If sgp is not given then the path is already in kernel space 8111394Sswallace */ 8211394Sswallace if (sgp == NULL) 8311394Sswallace error = copystr(path, ptr, sz, &len); 8411394Sswallace else 8511394Sswallace error = copyinstr(path, ptr, sz, &len); 8611394Sswallace 8711394Sswallace if (error) { 8811394Sswallace free(buf, M_TEMP); 8911394Sswallace return error; 9011394Sswallace } 9111394Sswallace 9211394Sswallace if (*ptr != '/') { 9311394Sswallace free(buf, M_TEMP); 9411394Sswallace return EINVAL; 9511394Sswallace } 9611394Sswallace 9711394Sswallace /* 9811394Sswallace * We know that there is a / somewhere in this pathname. 9911394Sswallace * Search backwards for it, to find the file's parent dir 10011394Sswallace * to see if it exists in the alternate tree. If it does, 10111394Sswallace * and we want to create a file (cflag is set). We don't 10211394Sswallace * need to worry about the root comparison in this case. 10311394Sswallace */ 10411394Sswallace 10511394Sswallace if (cflag) { 10611394Sswallace for (cp = &ptr[len] - 1; *cp != '/'; cp--); 10711394Sswallace *cp = '\0'; 10811394Sswallace 10983366Sjulian NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 11011394Sswallace 11111394Sswallace if ((error = namei(&nd)) != 0) { 11211394Sswallace free(buf, M_TEMP); 11311394Sswallace return error; 11411394Sswallace } 11511394Sswallace 11611394Sswallace *cp = '/'; 11711394Sswallace } 11811394Sswallace else { 11983366Sjulian NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 12011394Sswallace 12111394Sswallace if ((error = namei(&nd)) != 0) { 12211394Sswallace free(buf, M_TEMP); 12311394Sswallace return error; 12411394Sswallace } 12511394Sswallace 12611394Sswallace /* 12711394Sswallace * We now compare the vnode of the ibcs2_root to the one 12811394Sswallace * vnode asked. If they resolve to be the same, then we 12911394Sswallace * ignore the match so that the real root gets used. 13011394Sswallace * This avoids the problem of traversing "../.." to find the 13111394Sswallace * root directory and never finding it, because "/" resolves 13211394Sswallace * to the emulation root directory. This is expensive :-( 13311394Sswallace */ 13418027Sbde NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ibcs2_emul_path, 13583366Sjulian td); 13611394Sswallace 13711394Sswallace if ((error = namei(&ndroot)) != 0) { 13811394Sswallace /* Cannot happen! */ 13911394Sswallace free(buf, M_TEMP); 14054655Seivind NDFREE(&nd, NDF_ONLY_PNBUF); 14111394Sswallace vrele(nd.ni_vp); 14211394Sswallace return error; 14311394Sswallace } 14411394Sswallace 14591406Sjhb if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) { 14611394Sswallace goto done; 14711394Sswallace } 14811394Sswallace 14991406Sjhb if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td)) 15071699Sjhb != 0) { 15111394Sswallace goto done; 15211394Sswallace } 15311394Sswallace 15411394Sswallace if (vat.va_fsid == vatroot.va_fsid && 15511394Sswallace vat.va_fileid == vatroot.va_fileid) { 15611394Sswallace error = ENOENT; 15711394Sswallace goto done; 15811394Sswallace } 15911394Sswallace 16011394Sswallace } 16111394Sswallace if (sgp == NULL) 16211394Sswallace *pbuf = buf; 16311394Sswallace else { 16411394Sswallace sz = &ptr[len] - buf; 165121016Stjr if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL) 166121016Stjr error = copyout(buf, *pbuf, sz); 167121016Stjr else 168121016Stjr error = ENAMETOOLONG; 16911394Sswallace free(buf, M_TEMP); 17011394Sswallace } 17111394Sswallace 17211394Sswallace 17311394Sswallacedone: 17454655Seivind NDFREE(&nd, NDF_ONLY_PNBUF); 17511394Sswallace vrele(nd.ni_vp); 17654655Seivind if (!cflag) { 17754655Seivind NDFREE(&ndroot, NDF_ONLY_PNBUF); 17811394Sswallace vrele(ndroot.ni_vp); 17954655Seivind } 18011394Sswallace return error; 18111394Sswallace} 182