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.
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.
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]
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 #include <vroot/vroot.h>
31 #include <vroot/args.h>
34 #include <sys/param.h>
46 char full_path
[MAXPATHLEN
+1];
52 } vroot_datat
, *vroot_datapt
;
54 static vroot_datat vroot_data
= {
55 { 0, NULL
, "VIRTUAL_ROOT"},
57 "", NULL
, NULL
, NULL
, 0, 1};
60 add_dir_to_path(const char *path
, register pathpt
*pointer
, register int position
)
65 register pathcellpt p
;
68 if (*pointer
!= NULL
) {
69 for (p
= &((*pointer
)[0]); p
->path
!= NULL
; p
++, size
++);
75 if (position
>= size
) {
76 new_path
= (pathpt
)calloc((unsigned)(position
+2), sizeof(pathcellt
));
77 if (*pointer
!= NULL
) {
78 memcpy((char *)new_path
,(char *)(*pointer
), size
*sizeof(pathcellt
));
79 free((char *)(*pointer
));};
82 name
= (char *)malloc((unsigned)(length
+1));
83 (void)strcpy(name
, path
);
84 if ((*pointer
)[position
].path
!= NULL
)
85 free((*pointer
)[position
].path
);
86 (*pointer
)[position
].path
= name
;
87 (*pointer
)[position
].length
= length
;
91 parse_path_string(register char *string
, register int remove_slash
)
97 for (; 1; string
= p
+1) {
98 if (p
= strchr(string
, ':')) *p
= 0;
99 if ((remove_slash
== 1) && !strcmp(string
, "/"))
100 add_dir_to_path("", &result
, -1);
102 add_dir_to_path(string
, &result
, -1);
104 else return(result
);};
105 return((pathpt
)NULL
);
111 return(vroot_data
.vroot
.env_var
);
117 return(vroot_data
.path
.env_var
);
121 flush_path_cache(void)
123 vroot_data
.path
.init
= 0;
127 flush_vroot_cache(void)
129 vroot_data
.vroot
.init
= 0;
133 scan_path_first(void)
135 vroot_data
.scan_vroot_first
= 0;
139 scan_vroot_first(void)
141 vroot_data
.scan_vroot_first
= 1;
145 set_path_style(int style
)
147 vroot_data
.cpp_style_path
= style
;
151 get_vroot_path(register char **vroot
, register char **path
, register char **filename
)
154 if ((*vroot
= vroot_data
.vroot_start
) == NULL
)
155 if ((*vroot
= vroot_data
.path_start
) == NULL
)
156 *vroot
= vroot_data
.filename_start
;};
158 if ((*path
= vroot_data
.path_start
) == NULL
)
159 *path
= vroot_data
.filename_start
;};
160 if (filename
!= NULL
)
161 *filename
= vroot_data
.filename_start
;
162 return(vroot_data
.full_path
);
166 translate_with_thunk(register char *filename
, int (*thunk
) (char *), pathpt path_vector
, pathpt vroot_vector
, rwt rw
)
168 register pathcellt
*vp
;
170 register pathcellt
*pp1
;
174 /* Setup path to use */
176 pp1
= NULL
; /* Do not use path when writing */
178 if (path_vector
== VROOT_DEFAULT
) {
179 if (!vroot_data
.path
.init
) {
180 vroot_data
.path
.init
= 1;
181 vroot_data
.path
.vector
= parse_path_string(getenv(vroot_data
.path
.env_var
), 0);};
182 path_vector
= vroot_data
.path
.vector
;};
183 pp1
= path_vector
== NULL
? NULL
: &(path_vector
)[0];};
185 /* Setup vroot to use */
186 if (vroot_vector
== VROOT_DEFAULT
) {
187 if (!vroot_data
.vroot
.init
) {
188 vroot_data
.vroot
.init
= 1;
189 vroot_data
.vroot
.vector
= parse_path_string(getenv(vroot_data
.vroot
.env_var
), 1);};
190 vroot_vector
= vroot_data
.vroot
.vector
;};
191 vp
= vroot_vector
== NULL
? NULL
: &(vroot_vector
)[0];
193 /* Setup to remember pieces */
194 vroot_data
.vroot_start
= NULL
;
195 vroot_data
.path_start
= NULL
;
196 vroot_data
.filename_start
= NULL
;
198 int flen
= strlen(filename
);
199 if(flen
>= MAXPATHLEN
) {
200 errno
= ENAMETOOLONG
;
204 switch ((vp
?1:0) + (pp1
? 2:0)) {
205 case 0: /* No path. No vroot. */
207 (void)strcpy(vroot_data
.full_path
, filename
);
208 vroot_data
.filename_start
= vroot_data
.full_path
;
209 (void)(*thunk
)(vroot_data
.full_path
);
211 case 1: /* No path. Vroot */
212 if (filename
[0] != '/') goto use_name
;
213 for (; vp
->path
!= NULL
; vp
++) {
214 if((1 + flen
+ vp
->length
) >= MAXPATHLEN
) {
215 errno
= ENAMETOOLONG
;
218 p
= vroot_data
.full_path
;
219 (void)strcpy(vroot_data
.vroot_start
= p
, vp
->path
);
221 (void)strcpy(vroot_data
.filename_start
= p
, filename
);
222 if ((*thunk
)(vroot_data
.full_path
)) return;};
223 (void)strcpy(vroot_data
.full_path
, filename
);
225 case 2: /* Path. No vroot. */
226 if (vroot_data
.cpp_style_path
) {
227 if (filename
[0] == '/') goto use_name
;
229 if (strchr(filename
, '/') != NULL
) goto use_name
;
231 for (; pp1
->path
!= NULL
; pp1
++) {
232 p
= vroot_data
.full_path
;
233 if((1 + flen
+ pp1
->length
) >= MAXPATHLEN
) {
234 errno
= ENAMETOOLONG
;
237 if (vroot_data
.cpp_style_path
) {
238 (void)strcpy(vroot_data
.path_start
= p
, pp1
->path
);
242 if (pp1
->length
!= 0) {
243 (void)strcpy(vroot_data
.path_start
= p
,
249 (void)strcpy(vroot_data
.filename_start
= p
, filename
);
250 if ((*thunk
)(vroot_data
.full_path
)) return;};
251 (void)strcpy(vroot_data
.full_path
, filename
);
253 case 3: { /* Path. Vroot. */
254 int *rel_path
, path_len
= 1;
255 if (vroot_data
.scan_vroot_first
== 0) {
256 for (pp
= pp1
; pp
->path
!= NULL
; pp
++) path_len
++;
258 for (path_len
-= 2; path_len
>= 0; path_len
--) rel_path
[path_len
]= 0;
259 for (; vp
->path
!= NULL
; vp
++)
260 for (pp
= pp1
, path_len
= 0; pp
->path
!= NULL
; pp
++, path_len
++) {
262 if (rel_path
[path_len
] == 1) continue;
263 if (pp
->path
[0] != '/') rel_path
[path_len
]= 1;
264 p
= vroot_data
.full_path
;
265 if ((filename
[0] == '/') || (pp
->path
[0] == '/')) {
266 if(vp
->length
>= MAXPATHLEN
) {
267 errno
= ENAMETOOLONG
;
270 (void)strcpy(vroot_data
.vroot_start
= p
, vp
->path
); p
+= vp
->length
;
273 if (vroot_data
.cpp_style_path
) {
274 if (filename
[0] != '/') {
275 if(1 + len
+ pp
->length
>= MAXPATHLEN
) {
276 errno
= ENAMETOOLONG
;
279 (void)strcpy(vroot_data
.path_start
= p
, pp
->path
); p
+= pp
->length
;
281 len
+= 1 + pp
->length
;
284 if (strchr(filename
, '/') == NULL
) {
285 if (pp
->length
!= 0) {
286 if(1 + len
+ pp
->length
>= MAXPATHLEN
) {
287 errno
= ENAMETOOLONG
;
290 (void)strcpy(vroot_data
.path_start
= p
,
294 len
+= 1 + pp
->length
;
298 (void)strcpy(vroot_data
.filename_start
= p
, filename
);
299 if ((*thunk
)(vroot_data
.full_path
)) return;};}
300 else { pathcellt
*vp1
= vp
;
301 for (pp
= pp1
, path_len
= 0; pp
->path
!= NULL
; pp
++, path_len
++)
302 for (vp
= vp1
; vp
->path
!= NULL
; vp
++) {
304 p
= vroot_data
.full_path
;
305 if ((filename
[0] == '/') || (pp
->path
[0] == '/')) {
306 if(vp
->length
>= MAXPATHLEN
) {
307 errno
= ENAMETOOLONG
;
310 (void)strcpy(vroot_data
.vroot_start
= p
, vp
->path
); p
+= vp
->length
;
313 if (vroot_data
.cpp_style_path
) {
314 if (filename
[0] != '/') {
315 if(1 + len
+ pp
->length
>= MAXPATHLEN
) {
316 errno
= ENAMETOOLONG
;
319 (void)strcpy(vroot_data
.path_start
= p
, pp
->path
); p
+= pp
->length
;
321 len
+= 1 + pp
->length
;
324 if (strchr(filename
, '/') == NULL
) {
325 if(1 + len
+ pp
->length
>= MAXPATHLEN
) {
326 errno
= ENAMETOOLONG
;
329 (void)strcpy(vroot_data
.path_start
= p
, pp
->path
); p
+= pp
->length
;
331 len
+= 1 + pp
->length
;
334 (void)strcpy(vroot_data
.filename_start
= p
, filename
);
335 if ((*thunk
)(vroot_data
.full_path
)) return;};};
336 (void)strcpy(vroot_data
.full_path
, filename
);