1*10d63b7dSRichard Lowe /* 2*10d63b7dSRichard Lowe * CDDL HEADER START 3*10d63b7dSRichard Lowe * 4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the 5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License"). 6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License. 7*10d63b7dSRichard Lowe * 8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions 11*10d63b7dSRichard Lowe * and limitations under the License. 12*10d63b7dSRichard Lowe * 13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*10d63b7dSRichard Lowe * 19*10d63b7dSRichard Lowe * CDDL HEADER END 20*10d63b7dSRichard Lowe */ 21*10d63b7dSRichard Lowe /* 22*10d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23*10d63b7dSRichard Lowe * Use is subject to license terms. 24*10d63b7dSRichard Lowe */ 25*10d63b7dSRichard Lowe 26*10d63b7dSRichard Lowe 27*10d63b7dSRichard Lowe #include <stdlib.h> 28*10d63b7dSRichard Lowe #include <string.h> 29*10d63b7dSRichard Lowe 30*10d63b7dSRichard Lowe #include <vroot/vroot.h> 31*10d63b7dSRichard Lowe #include <vroot/args.h> 32*10d63b7dSRichard Lowe 33*10d63b7dSRichard Lowe #include <string.h> 34*10d63b7dSRichard Lowe #include <sys/param.h> 35*10d63b7dSRichard Lowe #include <sys/file.h> 36*10d63b7dSRichard Lowe 37*10d63b7dSRichard Lowe typedef struct { 38*10d63b7dSRichard Lowe short init; 39*10d63b7dSRichard Lowe pathpt vector; 40*10d63b7dSRichard Lowe const char *env_var; 41*10d63b7dSRichard Lowe } vroot_patht; 42*10d63b7dSRichard Lowe 43*10d63b7dSRichard Lowe typedef struct { 44*10d63b7dSRichard Lowe vroot_patht vroot; 45*10d63b7dSRichard Lowe vroot_patht path; 46*10d63b7dSRichard Lowe char full_path[MAXPATHLEN+1]; 47*10d63b7dSRichard Lowe char *vroot_start; 48*10d63b7dSRichard Lowe char *path_start; 49*10d63b7dSRichard Lowe char *filename_start; 50*10d63b7dSRichard Lowe int scan_vroot_first; 51*10d63b7dSRichard Lowe int cpp_style_path; 52*10d63b7dSRichard Lowe } vroot_datat, *vroot_datapt; 53*10d63b7dSRichard Lowe 54*10d63b7dSRichard Lowe static vroot_datat vroot_data= { 55*10d63b7dSRichard Lowe { 0, NULL, "VIRTUAL_ROOT"}, 56*10d63b7dSRichard Lowe { 0, NULL, "PATH"}, 57*10d63b7dSRichard Lowe "", NULL, NULL, NULL, 0, 1}; 58*10d63b7dSRichard Lowe 59*10d63b7dSRichard Lowe void 60*10d63b7dSRichard Lowe add_dir_to_path(const char *path, register pathpt *pointer, register int position) 61*10d63b7dSRichard Lowe { 62*10d63b7dSRichard Lowe register int size= 0; 63*10d63b7dSRichard Lowe register int length; 64*10d63b7dSRichard Lowe register char *name; 65*10d63b7dSRichard Lowe register pathcellpt p; 66*10d63b7dSRichard Lowe pathpt new_path; 67*10d63b7dSRichard Lowe 68*10d63b7dSRichard Lowe if (*pointer != NULL) { 69*10d63b7dSRichard Lowe for (p= &((*pointer)[0]); p->path != NULL; p++, size++); 70*10d63b7dSRichard Lowe if (position < 0) 71*10d63b7dSRichard Lowe position= size;} 72*10d63b7dSRichard Lowe else 73*10d63b7dSRichard Lowe if (position < 0) 74*10d63b7dSRichard Lowe position= 0; 75*10d63b7dSRichard Lowe if (position >= size) { 76*10d63b7dSRichard Lowe new_path= (pathpt)calloc((unsigned)(position+2), sizeof(pathcellt)); 77*10d63b7dSRichard Lowe if (*pointer != NULL) { 78*10d63b7dSRichard Lowe memcpy((char *)new_path,(char *)(*pointer), size*sizeof(pathcellt)); 79*10d63b7dSRichard Lowe free((char *)(*pointer));}; 80*10d63b7dSRichard Lowe *pointer= new_path;}; 81*10d63b7dSRichard Lowe length= strlen(path); 82*10d63b7dSRichard Lowe name= (char *)malloc((unsigned)(length+1)); 83*10d63b7dSRichard Lowe (void)strcpy(name, path); 84*10d63b7dSRichard Lowe if ((*pointer)[position].path != NULL) 85*10d63b7dSRichard Lowe free((*pointer)[position].path); 86*10d63b7dSRichard Lowe (*pointer)[position].path= name; 87*10d63b7dSRichard Lowe (*pointer)[position].length= length; 88*10d63b7dSRichard Lowe } 89*10d63b7dSRichard Lowe 90*10d63b7dSRichard Lowe pathpt 91*10d63b7dSRichard Lowe parse_path_string(register char *string, register int remove_slash) 92*10d63b7dSRichard Lowe { 93*10d63b7dSRichard Lowe register char *p; 94*10d63b7dSRichard Lowe pathpt result= NULL; 95*10d63b7dSRichard Lowe 96*10d63b7dSRichard Lowe if (string != NULL) 97*10d63b7dSRichard Lowe for (; 1; string= p+1) { 98*10d63b7dSRichard Lowe if (p= strchr(string, ':')) *p= 0; 99*10d63b7dSRichard Lowe if ((remove_slash == 1) && !strcmp(string, "/")) 100*10d63b7dSRichard Lowe add_dir_to_path("", &result, -1); 101*10d63b7dSRichard Lowe else 102*10d63b7dSRichard Lowe add_dir_to_path(string, &result, -1); 103*10d63b7dSRichard Lowe if (p) *p= ':'; 104*10d63b7dSRichard Lowe else return(result);}; 105*10d63b7dSRichard Lowe return((pathpt)NULL); 106*10d63b7dSRichard Lowe } 107*10d63b7dSRichard Lowe 108*10d63b7dSRichard Lowe const char * 109*10d63b7dSRichard Lowe get_vroot_name(void) 110*10d63b7dSRichard Lowe { 111*10d63b7dSRichard Lowe return(vroot_data.vroot.env_var); 112*10d63b7dSRichard Lowe } 113*10d63b7dSRichard Lowe 114*10d63b7dSRichard Lowe const char * 115*10d63b7dSRichard Lowe get_path_name(void) 116*10d63b7dSRichard Lowe { 117*10d63b7dSRichard Lowe return(vroot_data.path.env_var); 118*10d63b7dSRichard Lowe } 119*10d63b7dSRichard Lowe 120*10d63b7dSRichard Lowe void 121*10d63b7dSRichard Lowe flush_path_cache(void) 122*10d63b7dSRichard Lowe { 123*10d63b7dSRichard Lowe vroot_data.path.init= 0; 124*10d63b7dSRichard Lowe } 125*10d63b7dSRichard Lowe 126*10d63b7dSRichard Lowe void 127*10d63b7dSRichard Lowe flush_vroot_cache(void) 128*10d63b7dSRichard Lowe { 129*10d63b7dSRichard Lowe vroot_data.vroot.init= 0; 130*10d63b7dSRichard Lowe } 131*10d63b7dSRichard Lowe 132*10d63b7dSRichard Lowe void 133*10d63b7dSRichard Lowe scan_path_first(void) 134*10d63b7dSRichard Lowe { 135*10d63b7dSRichard Lowe vroot_data.scan_vroot_first= 0; 136*10d63b7dSRichard Lowe } 137*10d63b7dSRichard Lowe 138*10d63b7dSRichard Lowe void 139*10d63b7dSRichard Lowe scan_vroot_first(void) 140*10d63b7dSRichard Lowe { 141*10d63b7dSRichard Lowe vroot_data.scan_vroot_first= 1; 142*10d63b7dSRichard Lowe } 143*10d63b7dSRichard Lowe 144*10d63b7dSRichard Lowe void 145*10d63b7dSRichard Lowe set_path_style(int style) 146*10d63b7dSRichard Lowe { 147*10d63b7dSRichard Lowe vroot_data.cpp_style_path= style; 148*10d63b7dSRichard Lowe } 149*10d63b7dSRichard Lowe 150*10d63b7dSRichard Lowe char * 151*10d63b7dSRichard Lowe get_vroot_path(register char **vroot, register char **path, register char **filename) 152*10d63b7dSRichard Lowe { 153*10d63b7dSRichard Lowe if (vroot != NULL) { 154*10d63b7dSRichard Lowe if ((*vroot= vroot_data.vroot_start) == NULL) 155*10d63b7dSRichard Lowe if ((*vroot= vroot_data.path_start) == NULL) 156*10d63b7dSRichard Lowe *vroot= vroot_data.filename_start;}; 157*10d63b7dSRichard Lowe if (path != NULL) { 158*10d63b7dSRichard Lowe if ((*path= vroot_data.path_start) == NULL) 159*10d63b7dSRichard Lowe *path= vroot_data.filename_start;}; 160*10d63b7dSRichard Lowe if (filename != NULL) 161*10d63b7dSRichard Lowe *filename= vroot_data.filename_start; 162*10d63b7dSRichard Lowe return(vroot_data.full_path); 163*10d63b7dSRichard Lowe } 164*10d63b7dSRichard Lowe 165*10d63b7dSRichard Lowe void 166*10d63b7dSRichard Lowe translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw) 167*10d63b7dSRichard Lowe { 168*10d63b7dSRichard Lowe register pathcellt *vp; 169*10d63b7dSRichard Lowe pathcellt *pp; 170*10d63b7dSRichard Lowe register pathcellt *pp1; 171*10d63b7dSRichard Lowe register char *p; 172*10d63b7dSRichard Lowe int flags[256]; 173*10d63b7dSRichard Lowe 174*10d63b7dSRichard Lowe /* Setup path to use */ 175*10d63b7dSRichard Lowe if (rw == rw_write) 176*10d63b7dSRichard Lowe pp1= NULL; /* Do not use path when writing */ 177*10d63b7dSRichard Lowe else { 178*10d63b7dSRichard Lowe if (path_vector == VROOT_DEFAULT) { 179*10d63b7dSRichard Lowe if (!vroot_data.path.init) { 180*10d63b7dSRichard Lowe vroot_data.path.init= 1; 181*10d63b7dSRichard Lowe vroot_data.path.vector= parse_path_string(getenv(vroot_data.path.env_var), 0);}; 182*10d63b7dSRichard Lowe path_vector= vroot_data.path.vector;}; 183*10d63b7dSRichard Lowe pp1= path_vector == NULL ? NULL : &(path_vector)[0];}; 184*10d63b7dSRichard Lowe 185*10d63b7dSRichard Lowe /* Setup vroot to use */ 186*10d63b7dSRichard Lowe if (vroot_vector == VROOT_DEFAULT) { 187*10d63b7dSRichard Lowe if (!vroot_data.vroot.init) { 188*10d63b7dSRichard Lowe vroot_data.vroot.init= 1; 189*10d63b7dSRichard Lowe vroot_data.vroot.vector= parse_path_string(getenv(vroot_data.vroot.env_var), 1);}; 190*10d63b7dSRichard Lowe vroot_vector= vroot_data.vroot.vector;}; 191*10d63b7dSRichard Lowe vp= vroot_vector == NULL ? NULL : &(vroot_vector)[0]; 192*10d63b7dSRichard Lowe 193*10d63b7dSRichard Lowe /* Setup to remember pieces */ 194*10d63b7dSRichard Lowe vroot_data.vroot_start= NULL; 195*10d63b7dSRichard Lowe vroot_data.path_start= NULL; 196*10d63b7dSRichard Lowe vroot_data.filename_start= NULL; 197*10d63b7dSRichard Lowe 198*10d63b7dSRichard Lowe int flen = strlen(filename); 199*10d63b7dSRichard Lowe if(flen >= MAXPATHLEN) { 200*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 201*10d63b7dSRichard Lowe return; 202*10d63b7dSRichard Lowe } 203*10d63b7dSRichard Lowe 204*10d63b7dSRichard Lowe switch ((vp ?1:0) + (pp1 ? 2:0)) { 205*10d63b7dSRichard Lowe case 0: /* No path. No vroot. */ 206*10d63b7dSRichard Lowe use_name: 207*10d63b7dSRichard Lowe (void)strcpy(vroot_data.full_path, filename); 208*10d63b7dSRichard Lowe vroot_data.filename_start= vroot_data.full_path; 209*10d63b7dSRichard Lowe (void)(*thunk)(vroot_data.full_path); 210*10d63b7dSRichard Lowe return; 211*10d63b7dSRichard Lowe case 1: /* No path. Vroot */ 212*10d63b7dSRichard Lowe if (filename[0] != '/') goto use_name; 213*10d63b7dSRichard Lowe for (; vp->path != NULL; vp++) { 214*10d63b7dSRichard Lowe if((1 + flen + vp->length) >= MAXPATHLEN) { 215*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 216*10d63b7dSRichard Lowe continue; 217*10d63b7dSRichard Lowe } 218*10d63b7dSRichard Lowe p= vroot_data.full_path; 219*10d63b7dSRichard Lowe (void)strcpy(vroot_data.vroot_start= p, vp->path); 220*10d63b7dSRichard Lowe p+= vp->length; 221*10d63b7dSRichard Lowe (void)strcpy(vroot_data.filename_start= p, filename); 222*10d63b7dSRichard Lowe if ((*thunk)(vroot_data.full_path)) return;}; 223*10d63b7dSRichard Lowe (void)strcpy(vroot_data.full_path, filename); 224*10d63b7dSRichard Lowe return; 225*10d63b7dSRichard Lowe case 2: /* Path. No vroot. */ 226*10d63b7dSRichard Lowe if (vroot_data.cpp_style_path) { 227*10d63b7dSRichard Lowe if (filename[0] == '/') goto use_name; 228*10d63b7dSRichard Lowe } else { 229*10d63b7dSRichard Lowe if (strchr(filename, '/') != NULL) goto use_name; 230*10d63b7dSRichard Lowe }; 231*10d63b7dSRichard Lowe for (; pp1->path != NULL; pp1++) { 232*10d63b7dSRichard Lowe p= vroot_data.full_path; 233*10d63b7dSRichard Lowe if((1 + flen + pp1->length) >= MAXPATHLEN) { 234*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 235*10d63b7dSRichard Lowe continue; 236*10d63b7dSRichard Lowe } 237*10d63b7dSRichard Lowe if (vroot_data.cpp_style_path) { 238*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, pp1->path); 239*10d63b7dSRichard Lowe p+= pp1->length; 240*10d63b7dSRichard Lowe *p++= '/'; 241*10d63b7dSRichard Lowe } else { 242*10d63b7dSRichard Lowe if (pp1->length != 0) { 243*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, 244*10d63b7dSRichard Lowe pp1->path); 245*10d63b7dSRichard Lowe p+= pp1->length; 246*10d63b7dSRichard Lowe *p++= '/'; 247*10d63b7dSRichard Lowe }; 248*10d63b7dSRichard Lowe }; 249*10d63b7dSRichard Lowe (void)strcpy(vroot_data.filename_start= p, filename); 250*10d63b7dSRichard Lowe if ((*thunk)(vroot_data.full_path)) return;}; 251*10d63b7dSRichard Lowe (void)strcpy(vroot_data.full_path, filename); 252*10d63b7dSRichard Lowe return; 253*10d63b7dSRichard Lowe case 3: { /* Path. Vroot. */ 254*10d63b7dSRichard Lowe int *rel_path, path_len= 1; 255*10d63b7dSRichard Lowe if (vroot_data.scan_vroot_first == 0) { 256*10d63b7dSRichard Lowe for (pp= pp1; pp->path != NULL; pp++) path_len++; 257*10d63b7dSRichard Lowe rel_path= flags; 258*10d63b7dSRichard Lowe for (path_len-= 2; path_len >= 0; path_len--) rel_path[path_len]= 0; 259*10d63b7dSRichard Lowe for (; vp->path != NULL; vp++) 260*10d63b7dSRichard Lowe for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) { 261*10d63b7dSRichard Lowe int len = 0; 262*10d63b7dSRichard Lowe if (rel_path[path_len] == 1) continue; 263*10d63b7dSRichard Lowe if (pp->path[0] != '/') rel_path[path_len]= 1; 264*10d63b7dSRichard Lowe p= vroot_data.full_path; 265*10d63b7dSRichard Lowe if ((filename[0] == '/') || (pp->path[0] == '/')) { 266*10d63b7dSRichard Lowe if(vp->length >= MAXPATHLEN) { 267*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 268*10d63b7dSRichard Lowe continue; 269*10d63b7dSRichard Lowe } 270*10d63b7dSRichard Lowe (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length; 271*10d63b7dSRichard Lowe len += vp->length; 272*10d63b7dSRichard Lowe }; 273*10d63b7dSRichard Lowe if (vroot_data.cpp_style_path) { 274*10d63b7dSRichard Lowe if (filename[0] != '/') { 275*10d63b7dSRichard Lowe if(1 + len + pp->length >= MAXPATHLEN) { 276*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 277*10d63b7dSRichard Lowe continue; 278*10d63b7dSRichard Lowe } 279*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; 280*10d63b7dSRichard Lowe *p++= '/'; 281*10d63b7dSRichard Lowe len += 1 + pp->length; 282*10d63b7dSRichard Lowe }; 283*10d63b7dSRichard Lowe } else { 284*10d63b7dSRichard Lowe if (strchr(filename, '/') == NULL) { 285*10d63b7dSRichard Lowe if (pp->length != 0) { 286*10d63b7dSRichard Lowe if(1 + len + pp->length >= MAXPATHLEN) { 287*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 288*10d63b7dSRichard Lowe continue; 289*10d63b7dSRichard Lowe } 290*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, 291*10d63b7dSRichard Lowe pp->path); 292*10d63b7dSRichard Lowe p+= pp->length; 293*10d63b7dSRichard Lowe *p++= '/'; 294*10d63b7dSRichard Lowe len += 1 + pp->length; 295*10d63b7dSRichard Lowe } 296*10d63b7dSRichard Lowe } 297*10d63b7dSRichard Lowe }; 298*10d63b7dSRichard Lowe (void)strcpy(vroot_data.filename_start= p, filename); 299*10d63b7dSRichard Lowe if ((*thunk)(vroot_data.full_path)) return;};} 300*10d63b7dSRichard Lowe else { pathcellt *vp1= vp; 301*10d63b7dSRichard Lowe for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) 302*10d63b7dSRichard Lowe for (vp= vp1; vp->path != NULL; vp++) { 303*10d63b7dSRichard Lowe int len = 0; 304*10d63b7dSRichard Lowe p= vroot_data.full_path; 305*10d63b7dSRichard Lowe if ((filename[0] == '/') || (pp->path[0] == '/')) { 306*10d63b7dSRichard Lowe if(vp->length >= MAXPATHLEN) { 307*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 308*10d63b7dSRichard Lowe continue; 309*10d63b7dSRichard Lowe } 310*10d63b7dSRichard Lowe (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length; 311*10d63b7dSRichard Lowe len += vp->length; 312*10d63b7dSRichard Lowe } 313*10d63b7dSRichard Lowe if (vroot_data.cpp_style_path) { 314*10d63b7dSRichard Lowe if (filename[0] != '/') { 315*10d63b7dSRichard Lowe if(1 + len + pp->length >= MAXPATHLEN) { 316*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 317*10d63b7dSRichard Lowe continue; 318*10d63b7dSRichard Lowe } 319*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; 320*10d63b7dSRichard Lowe *p++= '/'; 321*10d63b7dSRichard Lowe len += 1 + pp->length; 322*10d63b7dSRichard Lowe } 323*10d63b7dSRichard Lowe } else { 324*10d63b7dSRichard Lowe if (strchr(filename, '/') == NULL) { 325*10d63b7dSRichard Lowe if(1 + len + pp->length >= MAXPATHLEN) { 326*10d63b7dSRichard Lowe errno = ENAMETOOLONG; 327*10d63b7dSRichard Lowe continue; 328*10d63b7dSRichard Lowe } 329*10d63b7dSRichard Lowe (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; 330*10d63b7dSRichard Lowe *p++= '/'; 331*10d63b7dSRichard Lowe len += 1 + pp->length; 332*10d63b7dSRichard Lowe } 333*10d63b7dSRichard Lowe } 334*10d63b7dSRichard Lowe (void)strcpy(vroot_data.filename_start= p, filename); 335*10d63b7dSRichard Lowe if ((*thunk)(vroot_data.full_path)) return;};}; 336*10d63b7dSRichard Lowe (void)strcpy(vroot_data.full_path, filename); 337*10d63b7dSRichard Lowe return;};}; 338*10d63b7dSRichard Lowe } 339