Deleted Added
full compact
ibcs2_util.c (139799) ibcs2_util.c (141488)
1/*-
2 * Copyright (c) 1994 Christos Zoulas
3 * Copyright (c) 1995 Frank van der Linden
4 * Copyright (c) 1995 Scott Bartram
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 16 unchanged lines hidden (view full) ---

25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp
30 */
31
32#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1994 Christos Zoulas
3 * Copyright (c) 1995 Frank van der Linden
4 * Copyright (c) 1995 Scott Bartram
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 16 unchanged lines hidden (view full) ---

25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_util.c 139799 2005-01-06 23:22:04Z imp $");
33__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_util.c 141488 2005-02-07 22:02:18Z jhb $");
34
35#include <sys/param.h>
36#include <sys/systm.h>
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/namei.h>
38#include <sys/malloc.h>
39#include <sys/vnode.h>
37#include <sys/syscallsubr.h>
40
41#include <i386/ibcs2/ibcs2_util.h>
42
43
44const char ibcs2_emul_path[] = "/compat/ibcs2";
45
46/*
47 * Search an alternate path before passing pathname arguments on
48 * to system calls. Useful for keeping a separate 'emulation tree'.
49 *
50 * If cflag is set, we check if an attempt can be made to create
51 * the named file, i.e. we check if the directory it should
52 * be in exists.
53 */
54int
38
39#include <i386/ibcs2/ibcs2_util.h>
40
41
42const char ibcs2_emul_path[] = "/compat/ibcs2";
43
44/*
45 * Search an alternate path before passing pathname arguments on
46 * to system calls. Useful for keeping a separate 'emulation tree'.
47 *
48 * If cflag is set, we check if an attempt can be made to create
49 * the named file, i.e. we check if the directory it should
50 * be in exists.
51 */
52int
55ibcs2_emul_find(td, sgp, prefix, path, pbuf, cflag)
56 struct thread *td;
57 caddr_t *sgp; /* Pointer to stackgap memory */
58 const char *prefix;
59 char *path;
60 char **pbuf;
61 int cflag;
53ibcs2_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
54 char **pbuf, int cflag)
62{
55{
63 struct nameidata nd;
64 struct nameidata ndroot;
65 struct vattr vat;
66 struct vattr vatroot;
67 int error;
68 char *ptr, *buf, *cp;
69 size_t sz, len;
70
56
71 buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
72 *pbuf = path;
73
74 for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
75 continue;
76
77 sz = MAXPATHLEN - (ptr - buf);
78
79 /*
80 * If sgp is not given then the path is already in kernel space
81 */
82 if (sgp == NULL)
83 error = copystr(path, ptr, sz, &len);
84 else
85 error = copyinstr(path, ptr, sz, &len);
86
87 if (error) {
88 free(buf, M_TEMP);
89 return error;
90 }
91
92 if (*ptr != '/') {
93 free(buf, M_TEMP);
94 return EINVAL;
95 }
96
97 /*
98 * We know that there is a / somewhere in this pathname.
99 * Search backwards for it, to find the file's parent dir
100 * to see if it exists in the alternate tree. If it does,
101 * and we want to create a file (cflag is set). We don't
102 * need to worry about the root comparison in this case.
103 */
104
105 if (cflag) {
106 for (cp = &ptr[len] - 1; *cp != '/'; cp--);
107 *cp = '\0';
108
109 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
110
111 if ((error = namei(&nd)) != 0) {
112 free(buf, M_TEMP);
113 return error;
114 }
115
116 *cp = '/';
117 }
118 else {
119 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td);
120
121 if ((error = namei(&nd)) != 0) {
122 free(buf, M_TEMP);
123 return error;
124 }
125
126 /*
127 * We now compare the vnode of the ibcs2_root to the one
128 * vnode asked. If they resolve to be the same, then we
129 * ignore the match so that the real root gets used.
130 * This avoids the problem of traversing "../.." to find the
131 * root directory and never finding it, because "/" resolves
132 * to the emulation root directory. This is expensive :-(
133 */
134 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, ibcs2_emul_path,
135 td);
136
137 if ((error = namei(&ndroot)) != 0) {
138 /* Cannot happen! */
139 free(buf, M_TEMP);
140 NDFREE(&nd, NDF_ONLY_PNBUF);
141 vrele(nd.ni_vp);
142 return error;
143 }
144
145 if ((error = VOP_GETATTR(nd.ni_vp, &vat, td->td_ucred, td)) != 0) {
146 goto done;
147 }
148
149 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td->td_ucred, td))
150 != 0) {
151 goto done;
152 }
153
154 if (vat.va_fsid == vatroot.va_fsid &&
155 vat.va_fileid == vatroot.va_fileid) {
156 error = ENOENT;
157 goto done;
158 }
159
160 }
161 if (sgp == NULL)
162 *pbuf = buf;
163 else {
164 sz = &ptr[len] - buf;
165 if ((*pbuf = stackgap_alloc(sgp, sz + 1)) != NULL)
166 error = copyout(buf, *pbuf, sz);
167 else
168 error = ENAMETOOLONG;
169 free(buf, M_TEMP);
170 }
171
172
173done:
174 NDFREE(&nd, NDF_ONLY_PNBUF);
175 vrele(nd.ni_vp);
176 if (!cflag) {
177 NDFREE(&ndroot, NDF_ONLY_PNBUF);
178 vrele(ndroot.ni_vp);
179 }
180 return error;
57 return (kern_alternate_path(td, ibcs2_emul_path, path, pathseg, pbuf,
58 cflag));
181}
59}