1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*5c51f124SMoriah Waterland /* All Rights Reserved */ 29*5c51f124SMoriah Waterland 30*5c51f124SMoriah Waterland 31*5c51f124SMoriah Waterland #include <stdio.h> 32*5c51f124SMoriah Waterland #include <string.h> 33*5c51f124SMoriah Waterland #include <errno.h> 34*5c51f124SMoriah Waterland #include <ctype.h> 35*5c51f124SMoriah Waterland #include <sys/types.h> 36*5c51f124SMoriah Waterland #include <sys/stat.h> 37*5c51f124SMoriah Waterland #include <limits.h> 38*5c51f124SMoriah Waterland #include <pkgstrct.h> 39*5c51f124SMoriah Waterland #include <pkginfo.h> 40*5c51f124SMoriah Waterland #include <locale.h> 41*5c51f124SMoriah Waterland #include <libintl.h> 42*5c51f124SMoriah Waterland #include <unistd.h> 43*5c51f124SMoriah Waterland #include <stdlib.h> 44*5c51f124SMoriah Waterland #include <pkglib.h> 45*5c51f124SMoriah Waterland #include <install.h> 46*5c51f124SMoriah Waterland #include <libadm.h> 47*5c51f124SMoriah Waterland #include <libinst.h> 48*5c51f124SMoriah Waterland 49*5c51f124SMoriah Waterland extern char *basedir, *root, *rootlist[], **environ; 50*5c51f124SMoriah Waterland 51*5c51f124SMoriah Waterland /* 52*5c51f124SMoriah Waterland * IMPORTANT NOTE: PLEASE SEE THE DEFINITION OF temp[] BELOW BEFORE 53*5c51f124SMoriah Waterland * CHANGING THE DEFINITION OF PATH_LGTH!!!! 54*5c51f124SMoriah Waterland */ 55*5c51f124SMoriah Waterland 56*5c51f124SMoriah Waterland #define PATH_LGTH 4096 57*5c51f124SMoriah Waterland 58*5c51f124SMoriah Waterland #define MAXPARAMS 256 59*5c51f124SMoriah Waterland #define NRECURS 20 60*5c51f124SMoriah Waterland 61*5c51f124SMoriah Waterland #define MSG_BPARAMC "parametric class specification for <%s> not allowed" 62*5c51f124SMoriah Waterland #define MSG_SRCHLOC "no object for <%s> found in local path" 63*5c51f124SMoriah Waterland #define MSG_SRCHSRCH "no object for <%s> found in search path" 64*5c51f124SMoriah Waterland #define MSG_SRCHROOT "no object for <%s> found in root directory" 65*5c51f124SMoriah Waterland #define MSG_CONTENTS "unable to process contents of object <%s>" 66*5c51f124SMoriah Waterland #define MSG_WRITE "write of entry failed, errno=%d" 67*5c51f124SMoriah Waterland #define MSG_GARBDEFLT "garbled default settings: %s" 68*5c51f124SMoriah Waterland #define MSG_BANG "unknown directive: %s" 69*5c51f124SMoriah Waterland #define MSG_CHDIR "unable to change directory to <%s>" 70*5c51f124SMoriah Waterland #define MSG_INCOMPLETE "processing of <%s> may be incomplete" 71*5c51f124SMoriah Waterland #define MSG_NRECURS "too many levels of include (limit is %d)" 72*5c51f124SMoriah Waterland #define MSG_RDINCLUDE "unable to process include file <%s>, errno=%d" 73*5c51f124SMoriah Waterland #define MSG_IGNINCLUDE "ignoring include file <%s>" 74*5c51f124SMoriah Waterland #define MSG_NODEVICE "device numbers cannot be determined for <%s>" 75*5c51f124SMoriah Waterland 76*5c51f124SMoriah Waterland #define WRN_BADATTR "WARNING: attributes set to %04o %s %s for <%s>" 77*5c51f124SMoriah Waterland #define WRN_BADATTRM "WARNING: attributes set to %s %s %s for <%s>" 78*5c51f124SMoriah Waterland #define WRN_FAKEBD "WARNING: parametric paths may ignore BASEDIR" 79*5c51f124SMoriah Waterland 80*5c51f124SMoriah Waterland #define ERR_TEMP "unable to obtain temporary file resources, errno=%d" 81*5c51f124SMoriah Waterland #define ERR_ENVBUILD "unable to build parameter environment, errno=%d" 82*5c51f124SMoriah Waterland #define ERR_MAXPARAMS "too many parameter definitions (limit is %d)" 83*5c51f124SMoriah Waterland #define ERR_GETCWD "unable to get current directory, errno=%d" 84*5c51f124SMoriah Waterland #define ERR_PATHVAR "cannot resolve all build parameters associated with " \ 85*5c51f124SMoriah Waterland "path <%s>." 86*5c51f124SMoriah Waterland 87*5c51f124SMoriah Waterland static struct cfent entry; 88*5c51f124SMoriah Waterland static FILE *fp, 89*5c51f124SMoriah Waterland *sfp[20]; 90*5c51f124SMoriah Waterland static char *dname[NRECURS], 91*5c51f124SMoriah Waterland *params[256], 92*5c51f124SMoriah Waterland *proto[NRECURS], 93*5c51f124SMoriah Waterland *rootp[NRECURS][16], 94*5c51f124SMoriah Waterland *srchp[NRECURS][16], 95*5c51f124SMoriah Waterland *d_own[NRECURS], 96*5c51f124SMoriah Waterland *d_grp[NRECURS], 97*5c51f124SMoriah Waterland *rdonly[256]; 98*5c51f124SMoriah Waterland static mode_t d_mod[NRECURS]; 99*5c51f124SMoriah Waterland static int nfp = (-1); 100*5c51f124SMoriah Waterland static int nrdonly = 0; 101*5c51f124SMoriah Waterland static int errflg = 0; 102*5c51f124SMoriah Waterland static char *separ = " \t\n, "; 103*5c51f124SMoriah Waterland 104*5c51f124SMoriah Waterland /* libpkg/gpkgmap.c */ 105*5c51f124SMoriah Waterland extern void attrpreset(int mode, char *owner, char *group); 106*5c51f124SMoriah Waterland extern void attrdefault(); 107*5c51f124SMoriah Waterland static char *findfile(char *path, char *local); 108*5c51f124SMoriah Waterland static char *srchroot(char *path, char *copy); 109*5c51f124SMoriah Waterland 110*5c51f124SMoriah Waterland static int popenv(void); 111*5c51f124SMoriah Waterland 112*5c51f124SMoriah Waterland static int doattrib(void); 113*5c51f124SMoriah Waterland static void doinclude(void); 114*5c51f124SMoriah Waterland static void dorsearch(void); 115*5c51f124SMoriah Waterland static void dosearch(void); 116*5c51f124SMoriah Waterland static void error(int flag); 117*5c51f124SMoriah Waterland static void lputenv(char *s); 118*5c51f124SMoriah Waterland static void pushenv(char *file); 119*5c51f124SMoriah Waterland static void translate(register char *pt, register char *copy); 120*5c51f124SMoriah Waterland 121*5c51f124SMoriah Waterland int 122*5c51f124SMoriah Waterland mkpkgmap(char *outfile, char *protofile, char **envparam) 123*5c51f124SMoriah Waterland { 124*5c51f124SMoriah Waterland FILE *tmpfp; 125*5c51f124SMoriah Waterland char *pt, *path, mybuff[PATH_LGTH]; 126*5c51f124SMoriah Waterland char **envsave; 127*5c51f124SMoriah Waterland int c, fakebasedir; 128*5c51f124SMoriah Waterland int i, n; 129*5c51f124SMoriah Waterland 130*5c51f124SMoriah Waterland /* 131*5c51f124SMoriah Waterland * NOTE: THE SIZE OF temp IS HARD CODED INTO CALLS TO fscanf. 132*5c51f124SMoriah Waterland * YOU *MUST* MAKE SURE TO CHANGE THOSE CALLS IF THE SIZE OF temp 133*5c51f124SMoriah Waterland * IS EVER CHANGED!!!!!! 134*5c51f124SMoriah Waterland */ 135*5c51f124SMoriah Waterland char temp[PATH_LGTH]; 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland if ((tmpfp = fopen(outfile, "w")) == NULL) { 138*5c51f124SMoriah Waterland progerr(gettext(ERR_TEMP), errno); 139*5c51f124SMoriah Waterland quit(99); 140*5c51f124SMoriah Waterland } 141*5c51f124SMoriah Waterland envsave = environ; 142*5c51f124SMoriah Waterland environ = params; /* use only local environ */ 143*5c51f124SMoriah Waterland attrdefault(); /* assume no default attributes */ 144*5c51f124SMoriah Waterland 145*5c51f124SMoriah Waterland /* 146*5c51f124SMoriah Waterland * Environment parameters are optional, so variable 147*5c51f124SMoriah Waterland * (envparam[i]) could be NULL. 148*5c51f124SMoriah Waterland */ 149*5c51f124SMoriah Waterland for (i = 0; (envparam[i] != NULL) && 150*5c51f124SMoriah Waterland (pt = strchr(envparam[i], '=')); i++) { 151*5c51f124SMoriah Waterland *pt = '\0'; 152*5c51f124SMoriah Waterland rdonly[nrdonly++] = qstrdup(envparam[i]); 153*5c51f124SMoriah Waterland *pt = '='; 154*5c51f124SMoriah Waterland if (putenv(qstrdup(envparam[i]))) { /* bugid 1090920 */ 155*5c51f124SMoriah Waterland progerr(gettext(ERR_ENVBUILD), errno); 156*5c51f124SMoriah Waterland quit(99); 157*5c51f124SMoriah Waterland } 158*5c51f124SMoriah Waterland if (nrdonly >= MAXPARAMS) { 159*5c51f124SMoriah Waterland progerr(gettext(ERR_MAXPARAMS), MAXPARAMS); 160*5c51f124SMoriah Waterland quit(1); 161*5c51f124SMoriah Waterland } 162*5c51f124SMoriah Waterland } 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland pushenv(protofile); 165*5c51f124SMoriah Waterland errflg = 0; 166*5c51f124SMoriah Waterland again: 167*5c51f124SMoriah Waterland fakebasedir = 0; 168*5c51f124SMoriah Waterland while (!feof(fp)) { 169*5c51f124SMoriah Waterland c = getc(fp); 170*5c51f124SMoriah Waterland while (isspace(c)) 171*5c51f124SMoriah Waterland c = getc(fp); 172*5c51f124SMoriah Waterland 173*5c51f124SMoriah Waterland if (c == '#') { 174*5c51f124SMoriah Waterland do c = getc(fp); while ((c != EOF) && (c != '\n')); 175*5c51f124SMoriah Waterland continue; 176*5c51f124SMoriah Waterland } 177*5c51f124SMoriah Waterland if (c == EOF) 178*5c51f124SMoriah Waterland break; 179*5c51f124SMoriah Waterland 180*5c51f124SMoriah Waterland if (c == '!') { 181*5c51f124SMoriah Waterland /* 182*5c51f124SMoriah Waterland * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO 183*5c51f124SMoriah Waterland * the FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS 184*5c51f124SMoriah Waterland * LINE IF THE SIZE OF fscanf IS EVER CHANGED!!! 185*5c51f124SMoriah Waterland */ 186*5c51f124SMoriah Waterland (void) fscanf(fp, "%4096s", temp); 187*5c51f124SMoriah Waterland 188*5c51f124SMoriah Waterland if (strcmp(temp, "include") == 0) 189*5c51f124SMoriah Waterland doinclude(); 190*5c51f124SMoriah Waterland else if (strcmp(temp, "rsearch") == 0) 191*5c51f124SMoriah Waterland dorsearch(); 192*5c51f124SMoriah Waterland else if (strcmp(temp, "search") == 0) 193*5c51f124SMoriah Waterland dosearch(); 194*5c51f124SMoriah Waterland else if (strcmp(temp, "default") == 0) { 195*5c51f124SMoriah Waterland if (doattrib()) 196*5c51f124SMoriah Waterland break; 197*5c51f124SMoriah Waterland } else if (strchr(temp, '=')) { 198*5c51f124SMoriah Waterland translate(temp, mybuff); 199*5c51f124SMoriah Waterland /* put this into the local environment */ 200*5c51f124SMoriah Waterland lputenv(mybuff); 201*5c51f124SMoriah Waterland (void) fscanf(fp, "%*[^\n]"); /* rest of line */ 202*5c51f124SMoriah Waterland (void) fscanf(fp, "\n"); /* rest of line */ 203*5c51f124SMoriah Waterland } else { 204*5c51f124SMoriah Waterland error(1); 205*5c51f124SMoriah Waterland logerr(gettext(MSG_BANG), temp); 206*5c51f124SMoriah Waterland (void) fscanf(fp, "%*[^\n]"); /* read of line */ 207*5c51f124SMoriah Waterland (void) fscanf(fp, "\n"); /* read of line */ 208*5c51f124SMoriah Waterland } 209*5c51f124SMoriah Waterland continue; 210*5c51f124SMoriah Waterland } 211*5c51f124SMoriah Waterland (void) ungetc(c, fp); 212*5c51f124SMoriah Waterland 213*5c51f124SMoriah Waterland if ((n = gpkgmap(&entry, fp)) < 0) { 214*5c51f124SMoriah Waterland char *errstr; 215*5c51f124SMoriah Waterland 216*5c51f124SMoriah Waterland error(1); 217*5c51f124SMoriah Waterland errstr = getErrstr(); 218*5c51f124SMoriah Waterland logerr(gettext("garbled entry")); 219*5c51f124SMoriah Waterland logerr(gettext("- pathname: %s"), 220*5c51f124SMoriah Waterland (entry.path && *entry.path) ? entry.path : 221*5c51f124SMoriah Waterland "Unknown"); 222*5c51f124SMoriah Waterland logerr(gettext("- problem: %s"), 223*5c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 224*5c51f124SMoriah Waterland break; 225*5c51f124SMoriah Waterland } 226*5c51f124SMoriah Waterland if (n == 0) 227*5c51f124SMoriah Waterland break; /* done with file */ 228*5c51f124SMoriah Waterland 229*5c51f124SMoriah Waterland /* don't allow classname to be parametric */ 230*5c51f124SMoriah Waterland if (entry.ftype != 'i') { 231*5c51f124SMoriah Waterland if (entry.pkg_class[0] == '$') { 232*5c51f124SMoriah Waterland error(1); 233*5c51f124SMoriah Waterland logerr(gettext(MSG_BPARAMC), entry.path); 234*5c51f124SMoriah Waterland } 235*5c51f124SMoriah Waterland } 236*5c51f124SMoriah Waterland 237*5c51f124SMoriah Waterland if (strchr("dxlscbp", entry.ftype)) { 238*5c51f124SMoriah Waterland /* 239*5c51f124SMoriah Waterland * We don't need to search for things without any 240*5c51f124SMoriah Waterland * contents in them. 241*5c51f124SMoriah Waterland */ 242*5c51f124SMoriah Waterland if (strchr("cb", entry.ftype)) { 243*5c51f124SMoriah Waterland if (entry.ainfo.major == BADMAJOR || 244*5c51f124SMoriah Waterland entry.ainfo.minor == BADMINOR) { 245*5c51f124SMoriah Waterland error(1); 246*5c51f124SMoriah Waterland logerr(gettext(MSG_NODEVICE), 247*5c51f124SMoriah Waterland entry.path); 248*5c51f124SMoriah Waterland } 249*5c51f124SMoriah Waterland } 250*5c51f124SMoriah Waterland path = NULL; 251*5c51f124SMoriah Waterland } else { 252*5c51f124SMoriah Waterland path = findfile(entry.path, entry.ainfo.local); 253*5c51f124SMoriah Waterland if (!path) 254*5c51f124SMoriah Waterland continue; 255*5c51f124SMoriah Waterland 256*5c51f124SMoriah Waterland entry.ainfo.local = path; 257*5c51f124SMoriah Waterland if (strchr("fevin?", entry.ftype)) { 258*5c51f124SMoriah Waterland if (cverify(0, &entry.ftype, path, 259*5c51f124SMoriah Waterland &entry.cinfo, 1)) { 260*5c51f124SMoriah Waterland error(1); 261*5c51f124SMoriah Waterland logerr(gettext(MSG_CONTENTS), path); 262*5c51f124SMoriah Waterland } 263*5c51f124SMoriah Waterland } 264*5c51f124SMoriah Waterland } 265*5c51f124SMoriah Waterland 266*5c51f124SMoriah Waterland /* Warn if attributes are not set correctly. */ 267*5c51f124SMoriah Waterland if (!strchr("isl", entry.ftype)) { 268*5c51f124SMoriah Waterland int dowarning = 0; 269*5c51f124SMoriah Waterland int hasbadmode = 0; 270*5c51f124SMoriah Waterland 271*5c51f124SMoriah Waterland if (entry.ainfo.mode == NOMODE) { 272*5c51f124SMoriah Waterland entry.ainfo.mode = CURMODE; 273*5c51f124SMoriah Waterland dowarning = 1; 274*5c51f124SMoriah Waterland hasbadmode = 1; 275*5c51f124SMoriah Waterland } 276*5c51f124SMoriah Waterland 277*5c51f124SMoriah Waterland if (strcmp(entry.ainfo.owner, NOOWNER) == 0) { 278*5c51f124SMoriah Waterland (void) strlcpy(entry.ainfo.owner, CUROWNER, 279*5c51f124SMoriah Waterland sizeof (entry.ainfo.owner)); 280*5c51f124SMoriah Waterland dowarning = 1; 281*5c51f124SMoriah Waterland } 282*5c51f124SMoriah Waterland 283*5c51f124SMoriah Waterland if (strcmp(entry.ainfo.group, NOGROUP) == 0) { 284*5c51f124SMoriah Waterland (void) strlcpy(entry.ainfo.group, CURGROUP, 285*5c51f124SMoriah Waterland sizeof (entry.ainfo.group)); 286*5c51f124SMoriah Waterland dowarning = 1; 287*5c51f124SMoriah Waterland } 288*5c51f124SMoriah Waterland 289*5c51f124SMoriah Waterland 290*5c51f124SMoriah Waterland if (dowarning) { 291*5c51f124SMoriah Waterland if (hasbadmode) 292*5c51f124SMoriah Waterland logerr(gettext(WRN_BADATTRM), 293*5c51f124SMoriah Waterland "?", 294*5c51f124SMoriah Waterland entry.ainfo.owner, 295*5c51f124SMoriah Waterland entry.ainfo.group, 296*5c51f124SMoriah Waterland entry.path); 297*5c51f124SMoriah Waterland else 298*5c51f124SMoriah Waterland logerr(gettext(WRN_BADATTR), 299*5c51f124SMoriah Waterland (int)entry.ainfo.mode, 300*5c51f124SMoriah Waterland entry.ainfo.owner, 301*5c51f124SMoriah Waterland entry.ainfo.group, 302*5c51f124SMoriah Waterland entry.path); 303*5c51f124SMoriah Waterland } 304*5c51f124SMoriah Waterland } 305*5c51f124SMoriah Waterland 306*5c51f124SMoriah Waterland /* 307*5c51f124SMoriah Waterland * Resolve build parameters (initial lower case) in 308*5c51f124SMoriah Waterland * the link and target paths. 309*5c51f124SMoriah Waterland */ 310*5c51f124SMoriah Waterland if (strchr("ls", entry.ftype)) { 311*5c51f124SMoriah Waterland if (!RELATIVE(entry.ainfo.local) || 312*5c51f124SMoriah Waterland PARAMETRIC(entry.ainfo.local)) { 313*5c51f124SMoriah Waterland if (mappath(1, entry.ainfo.local)) { 314*5c51f124SMoriah Waterland error(1); 315*5c51f124SMoriah Waterland logerr(gettext(ERR_PATHVAR), 316*5c51f124SMoriah Waterland entry.ainfo.local); 317*5c51f124SMoriah Waterland break; 318*5c51f124SMoriah Waterland } 319*5c51f124SMoriah Waterland 320*5c51f124SMoriah Waterland canonize(entry.ainfo.local); 321*5c51f124SMoriah Waterland } 322*5c51f124SMoriah Waterland } 323*5c51f124SMoriah Waterland 324*5c51f124SMoriah Waterland /* 325*5c51f124SMoriah Waterland * Warn if top level file or directory is an install 326*5c51f124SMoriah Waterland * parameter 327*5c51f124SMoriah Waterland */ 328*5c51f124SMoriah Waterland if (entry.ftype != 'i') { 329*5c51f124SMoriah Waterland if (entry.path[0] == '$' && isupper(entry.path[1])) 330*5c51f124SMoriah Waterland fakebasedir = 1; 331*5c51f124SMoriah Waterland } 332*5c51f124SMoriah Waterland 333*5c51f124SMoriah Waterland if (mappath(1, entry.path)) { 334*5c51f124SMoriah Waterland error(1); 335*5c51f124SMoriah Waterland logerr(gettext(ERR_PATHVAR), entry.path); 336*5c51f124SMoriah Waterland break; 337*5c51f124SMoriah Waterland } 338*5c51f124SMoriah Waterland 339*5c51f124SMoriah Waterland canonize(entry.path); 340*5c51f124SMoriah Waterland if (ppkgmap(&entry, tmpfp)) { 341*5c51f124SMoriah Waterland error(1); 342*5c51f124SMoriah Waterland logerr(gettext(MSG_WRITE), errno); 343*5c51f124SMoriah Waterland break; 344*5c51f124SMoriah Waterland } 345*5c51f124SMoriah Waterland } 346*5c51f124SMoriah Waterland 347*5c51f124SMoriah Waterland if (fakebasedir) { 348*5c51f124SMoriah Waterland logerr(gettext(WRN_FAKEBD)); 349*5c51f124SMoriah Waterland fakebasedir = 0; 350*5c51f124SMoriah Waterland } 351*5c51f124SMoriah Waterland 352*5c51f124SMoriah Waterland if (popenv()) 353*5c51f124SMoriah Waterland goto again; 354*5c51f124SMoriah Waterland 355*5c51f124SMoriah Waterland (void) fclose(tmpfp); 356*5c51f124SMoriah Waterland environ = envsave; /* restore environment */ 357*5c51f124SMoriah Waterland 358*5c51f124SMoriah Waterland return (errflg ? 1 : 0); 359*5c51f124SMoriah Waterland } 360*5c51f124SMoriah Waterland 361*5c51f124SMoriah Waterland static char * 362*5c51f124SMoriah Waterland findfile(char *path, char *local) 363*5c51f124SMoriah Waterland { 364*5c51f124SMoriah Waterland struct stat statbuf; 365*5c51f124SMoriah Waterland static char host[PATH_MAX]; 366*5c51f124SMoriah Waterland register char *pt; 367*5c51f124SMoriah Waterland char temp[PATH_MAX], *basename; 368*5c51f124SMoriah Waterland int i; 369*5c51f124SMoriah Waterland 370*5c51f124SMoriah Waterland /* 371*5c51f124SMoriah Waterland * map any parameters specified in path to their corresponding values 372*5c51f124SMoriah Waterland * and make sure the path is in its canonical form; any parmeters for 373*5c51f124SMoriah Waterland * which a value is not defined will be left unexpanded. Since this 374*5c51f124SMoriah Waterland * is an actual search for a real file (which will not end up in the 375*5c51f124SMoriah Waterland * package) - we map ALL variables (both build and Install). 376*5c51f124SMoriah Waterland */ 377*5c51f124SMoriah Waterland (void) strlcpy(temp, (local && local[0] ? local : path), sizeof (temp)); 378*5c51f124SMoriah Waterland mappath(0, temp); 379*5c51f124SMoriah Waterland canonize(temp); 380*5c51f124SMoriah Waterland 381*5c51f124SMoriah Waterland *host = '\0'; 382*5c51f124SMoriah Waterland if (rootlist[0] || (basedir && (*temp != '/'))) { 383*5c51f124SMoriah Waterland /* 384*5c51f124SMoriah Waterland * search for path in the pseudo-root/basedir directory; note 385*5c51f124SMoriah Waterland * that package information files should NOT be included in 386*5c51f124SMoriah Waterland * this list 387*5c51f124SMoriah Waterland */ 388*5c51f124SMoriah Waterland if (entry.ftype != 'i') 389*5c51f124SMoriah Waterland return (srchroot(temp, host)); 390*5c51f124SMoriah Waterland } 391*5c51f124SMoriah Waterland 392*5c51f124SMoriah Waterland /* looking for local object file */ 393*5c51f124SMoriah Waterland if (local && *local) { 394*5c51f124SMoriah Waterland basepath(temp, dname[nfp], NULL); 395*5c51f124SMoriah Waterland /* 396*5c51f124SMoriah Waterland * If it equals "/dev/null", that just means it's an empty 397*5c51f124SMoriah Waterland * file. Otherwise, we'll really be writing stuff, so we need 398*5c51f124SMoriah Waterland * to verify the source. 399*5c51f124SMoriah Waterland */ 400*5c51f124SMoriah Waterland if (strcmp(temp, "/dev/null") != 0) { 401*5c51f124SMoriah Waterland if (stat(temp, &statbuf) || 402*5c51f124SMoriah Waterland !(statbuf.st_mode & S_IFREG)) { 403*5c51f124SMoriah Waterland error(1); 404*5c51f124SMoriah Waterland logerr(gettext(MSG_SRCHLOC), path); 405*5c51f124SMoriah Waterland return (NULL); 406*5c51f124SMoriah Waterland } 407*5c51f124SMoriah Waterland } 408*5c51f124SMoriah Waterland (void) strlcpy(host, temp, sizeof (host)); 409*5c51f124SMoriah Waterland return (host); 410*5c51f124SMoriah Waterland } 411*5c51f124SMoriah Waterland 412*5c51f124SMoriah Waterland for (i = 0; rootp[nfp][i]; i++) { 413*5c51f124SMoriah Waterland (void) snprintf(host, sizeof (host), "%s/%s", rootp[nfp][i], 414*5c51f124SMoriah Waterland temp + (*temp == '/' ? 1 : 0)); 415*5c51f124SMoriah Waterland if ((stat(host, &statbuf) == 0) && 416*5c51f124SMoriah Waterland (statbuf.st_mode & S_IFREG)) { 417*5c51f124SMoriah Waterland return (host); 418*5c51f124SMoriah Waterland } 419*5c51f124SMoriah Waterland } 420*5c51f124SMoriah Waterland 421*5c51f124SMoriah Waterland pt = strrchr(temp, '/'); 422*5c51f124SMoriah Waterland if (!pt++) 423*5c51f124SMoriah Waterland pt = temp; 424*5c51f124SMoriah Waterland 425*5c51f124SMoriah Waterland basename = pt; 426*5c51f124SMoriah Waterland 427*5c51f124SMoriah Waterland for (i = 0; srchp[nfp][i]; i++) { 428*5c51f124SMoriah Waterland (void) snprintf(host, sizeof (host), "%s/%s", 429*5c51f124SMoriah Waterland srchp[nfp][i], basename); 430*5c51f124SMoriah Waterland if ((stat(host, &statbuf) == 0) && 431*5c51f124SMoriah Waterland (statbuf.st_mode & S_IFREG)) { 432*5c51f124SMoriah Waterland return (host); 433*5c51f124SMoriah Waterland } 434*5c51f124SMoriah Waterland } 435*5c51f124SMoriah Waterland 436*5c51f124SMoriah Waterland /* check current directory as a last resort */ 437*5c51f124SMoriah Waterland (void) snprintf(host, sizeof (host), "%s/%s", dname[nfp], basename); 438*5c51f124SMoriah Waterland if ((stat(host, &statbuf) == 0) && (statbuf.st_mode & S_IFREG)) 439*5c51f124SMoriah Waterland return (host); 440*5c51f124SMoriah Waterland 441*5c51f124SMoriah Waterland error(1); 442*5c51f124SMoriah Waterland logerr(gettext(MSG_SRCHSRCH), path); 443*5c51f124SMoriah Waterland return (NULL); 444*5c51f124SMoriah Waterland } 445*5c51f124SMoriah Waterland 446*5c51f124SMoriah Waterland static void 447*5c51f124SMoriah Waterland dosearch(void) 448*5c51f124SMoriah Waterland { 449*5c51f124SMoriah Waterland char temp[PATH_MAX], lookpath[PATH_MAX], *pt; 450*5c51f124SMoriah Waterland int n; 451*5c51f124SMoriah Waterland 452*5c51f124SMoriah Waterland (void) fgets(temp, PATH_MAX, fp); 453*5c51f124SMoriah Waterland translate(temp, lookpath); 454*5c51f124SMoriah Waterland 455*5c51f124SMoriah Waterland for (n = 0; srchp[nfp][n]; n++) 456*5c51f124SMoriah Waterland free(srchp[nfp][n]); 457*5c51f124SMoriah Waterland 458*5c51f124SMoriah Waterland n = 0; 459*5c51f124SMoriah Waterland pt = strtok(lookpath, separ); 460*5c51f124SMoriah Waterland if (pt && *pt) { 461*5c51f124SMoriah Waterland do { 462*5c51f124SMoriah Waterland if (*pt != '/') { 463*5c51f124SMoriah Waterland /* make relative path an absolute directory */ 464*5c51f124SMoriah Waterland (void) snprintf(temp, sizeof (temp), 465*5c51f124SMoriah Waterland "%s/%s", dname[nfp], pt); 466*5c51f124SMoriah Waterland pt = temp; 467*5c51f124SMoriah Waterland } 468*5c51f124SMoriah Waterland canonize(pt); 469*5c51f124SMoriah Waterland srchp[nfp][n++] = qstrdup(pt); 470*5c51f124SMoriah Waterland } while (pt = strtok(NULL, separ)); 471*5c51f124SMoriah Waterland srchp[nfp][n] = NULL; 472*5c51f124SMoriah Waterland } 473*5c51f124SMoriah Waterland } 474*5c51f124SMoriah Waterland 475*5c51f124SMoriah Waterland static void 476*5c51f124SMoriah Waterland dorsearch(void) 477*5c51f124SMoriah Waterland { 478*5c51f124SMoriah Waterland char temp[PATH_MAX], lookpath[PATH_MAX], *pt; 479*5c51f124SMoriah Waterland int n; 480*5c51f124SMoriah Waterland 481*5c51f124SMoriah Waterland (void) fgets(temp, PATH_MAX, fp); 482*5c51f124SMoriah Waterland translate(temp, lookpath); 483*5c51f124SMoriah Waterland 484*5c51f124SMoriah Waterland for (n = 0; rootp[nfp][n]; n++) 485*5c51f124SMoriah Waterland free(rootp[nfp][n]); 486*5c51f124SMoriah Waterland 487*5c51f124SMoriah Waterland n = 0; 488*5c51f124SMoriah Waterland pt = strtok(lookpath, separ); 489*5c51f124SMoriah Waterland do { 490*5c51f124SMoriah Waterland if (*pt != '/') { 491*5c51f124SMoriah Waterland /* make relative path an absolute directory */ 492*5c51f124SMoriah Waterland (void) snprintf(temp, sizeof (temp), 493*5c51f124SMoriah Waterland "%s/%s", dname[nfp], pt); 494*5c51f124SMoriah Waterland pt = temp; 495*5c51f124SMoriah Waterland } 496*5c51f124SMoriah Waterland canonize(pt); 497*5c51f124SMoriah Waterland rootp[nfp][n++] = qstrdup(pt); 498*5c51f124SMoriah Waterland } while (pt = strtok(NULL, separ)); 499*5c51f124SMoriah Waterland rootp[nfp][n] = NULL; 500*5c51f124SMoriah Waterland } 501*5c51f124SMoriah Waterland 502*5c51f124SMoriah Waterland /* 503*5c51f124SMoriah Waterland * This function reads the default mode, owner and group from the prototype 504*5c51f124SMoriah Waterland * file and makes that available. 505*5c51f124SMoriah Waterland */ 506*5c51f124SMoriah Waterland static int 507*5c51f124SMoriah Waterland doattrib(void) 508*5c51f124SMoriah Waterland { 509*5c51f124SMoriah Waterland char *pt, attrib[PATH_MAX], *mode_ptr, *owner_ptr, *group_ptr, *eol; 510*5c51f124SMoriah Waterland int mode; 511*5c51f124SMoriah Waterland char owner[ATRSIZ+1], group[ATRSIZ+1], attrib_save[(4*ATRSIZ)]; 512*5c51f124SMoriah Waterland 513*5c51f124SMoriah Waterland (void) fgets(attrib, PATH_MAX, fp); 514*5c51f124SMoriah Waterland 515*5c51f124SMoriah Waterland (void) strlcpy(attrib_save, attrib, sizeof (attrib_save)); 516*5c51f124SMoriah Waterland 517*5c51f124SMoriah Waterland /* 518*5c51f124SMoriah Waterland * Now resolve any variables that may be present. Start on group and 519*5c51f124SMoriah Waterland * move backward since that keeps the resolved string from 520*5c51f124SMoriah Waterland * overwriting any of the other entries. This is required since 521*5c51f124SMoriah Waterland * mapvar() writes the resolved string over the string provided. 522*5c51f124SMoriah Waterland */ 523*5c51f124SMoriah Waterland mode_ptr = strtok(attrib, " \t"); 524*5c51f124SMoriah Waterland owner_ptr = strtok(NULL, " \t"); 525*5c51f124SMoriah Waterland group_ptr = strtok(NULL, " \t\n"); 526*5c51f124SMoriah Waterland eol = strtok(NULL, " \t\n"); 527*5c51f124SMoriah Waterland if (strtok(NULL, " \t\n")) { 528*5c51f124SMoriah Waterland /* extra tokens on the line */ 529*5c51f124SMoriah Waterland error(1); 530*5c51f124SMoriah Waterland logerr(gettext(MSG_GARBDEFLT), (eol) ? eol : 531*5c51f124SMoriah Waterland gettext("unreadable at end of line")); 532*5c51f124SMoriah Waterland return (1); 533*5c51f124SMoriah Waterland } 534*5c51f124SMoriah Waterland 535*5c51f124SMoriah Waterland if (group_ptr && mapvar(1, group_ptr) == 0) 536*5c51f124SMoriah Waterland (void) strncpy(group, group_ptr, ATRSIZ); 537*5c51f124SMoriah Waterland else { 538*5c51f124SMoriah Waterland error(1); 539*5c51f124SMoriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ? 540*5c51f124SMoriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) : 541*5c51f124SMoriah Waterland gettext("unreadable at group")); 542*5c51f124SMoriah Waterland return (1); 543*5c51f124SMoriah Waterland } 544*5c51f124SMoriah Waterland 545*5c51f124SMoriah Waterland if (owner_ptr && mapvar(1, owner_ptr) == 0) 546*5c51f124SMoriah Waterland (void) strncpy(owner, owner_ptr, ATRSIZ); 547*5c51f124SMoriah Waterland else { 548*5c51f124SMoriah Waterland error(1); 549*5c51f124SMoriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ? 550*5c51f124SMoriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) : 551*5c51f124SMoriah Waterland gettext("unreadable at owner")); 552*5c51f124SMoriah Waterland return (1); 553*5c51f124SMoriah Waterland } 554*5c51f124SMoriah Waterland 555*5c51f124SMoriah Waterland /* 556*5c51f124SMoriah Waterland * For mode, don't use scanf, since we want to force an octal 557*5c51f124SMoriah Waterland * interpretation and need to limit the length of the owner and group 558*5c51f124SMoriah Waterland * specifications. 559*5c51f124SMoriah Waterland */ 560*5c51f124SMoriah Waterland if (mode_ptr && mapvar(1, mode_ptr) == 0) 561*5c51f124SMoriah Waterland mode = strtol(mode_ptr, &pt, 8); 562*5c51f124SMoriah Waterland else { 563*5c51f124SMoriah Waterland error(1); 564*5c51f124SMoriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ? 565*5c51f124SMoriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) : 566*5c51f124SMoriah Waterland gettext("unreadable at mode")); 567*5c51f124SMoriah Waterland return (1); 568*5c51f124SMoriah Waterland } 569*5c51f124SMoriah Waterland 570*5c51f124SMoriah Waterland /* free any previous memory from qstrdup */ 571*5c51f124SMoriah Waterland if (d_own[nfp]) 572*5c51f124SMoriah Waterland free(d_own[nfp]); 573*5c51f124SMoriah Waterland if (d_grp[nfp]) 574*5c51f124SMoriah Waterland free(d_grp[nfp]); 575*5c51f124SMoriah Waterland 576*5c51f124SMoriah Waterland d_mod[nfp] = mode; 577*5c51f124SMoriah Waterland d_own[nfp] = qstrdup(owner); 578*5c51f124SMoriah Waterland d_grp[nfp] = qstrdup(group); 579*5c51f124SMoriah Waterland 580*5c51f124SMoriah Waterland attrpreset(d_mod[nfp], d_own[nfp], d_grp[nfp]); 581*5c51f124SMoriah Waterland 582*5c51f124SMoriah Waterland return (0); 583*5c51f124SMoriah Waterland } 584*5c51f124SMoriah Waterland 585*5c51f124SMoriah Waterland static void 586*5c51f124SMoriah Waterland doinclude(void) 587*5c51f124SMoriah Waterland { 588*5c51f124SMoriah Waterland char file[PATH_MAX]; 589*5c51f124SMoriah Waterland char temp[PATH_MAX]; 590*5c51f124SMoriah Waterland 591*5c51f124SMoriah Waterland (void) fgets(temp, PATH_MAX, fp); 592*5c51f124SMoriah Waterland 593*5c51f124SMoriah Waterland /* 594*5c51f124SMoriah Waterland * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO THE 595*5c51f124SMoriah Waterland * FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS LINE IF 596*5c51f124SMoriah Waterland * THE SIZE OF fscanf IS EVER CHANGED!!! 597*5c51f124SMoriah Waterland */ 598*5c51f124SMoriah Waterland (void) sscanf(temp, "%1024s", file); 599*5c51f124SMoriah Waterland 600*5c51f124SMoriah Waterland translate(file, temp); 601*5c51f124SMoriah Waterland canonize(temp); 602*5c51f124SMoriah Waterland 603*5c51f124SMoriah Waterland if (*temp == NULL) 604*5c51f124SMoriah Waterland return; 605*5c51f124SMoriah Waterland else if (*temp != '/') 606*5c51f124SMoriah Waterland (void) snprintf(file, sizeof (file), "%s/%s", dname[nfp], temp); 607*5c51f124SMoriah Waterland else 608*5c51f124SMoriah Waterland (void) strlcpy(file, temp, sizeof (file)); 609*5c51f124SMoriah Waterland 610*5c51f124SMoriah Waterland canonize(file); 611*5c51f124SMoriah Waterland pushenv(file); 612*5c51f124SMoriah Waterland } 613*5c51f124SMoriah Waterland 614*5c51f124SMoriah Waterland /* 615*5c51f124SMoriah Waterland * This does what mappath() does except that it does it for ALL variables 616*5c51f124SMoriah Waterland * using whitespace as a token separator. This is used to resolve search 617*5c51f124SMoriah Waterland * paths and assignment statements. It doesn't effect the build versus 618*5c51f124SMoriah Waterland * install decision made for pkgmap variables. 619*5c51f124SMoriah Waterland */ 620*5c51f124SMoriah Waterland static void 621*5c51f124SMoriah Waterland translate(register char *pt, register char *copy) 622*5c51f124SMoriah Waterland { 623*5c51f124SMoriah Waterland char *pt2, varname[MAX_PKG_PARAM_LENGTH]; 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland token: 626*5c51f124SMoriah Waterland /* eat white space */ 627*5c51f124SMoriah Waterland while (isspace(*pt)) 628*5c51f124SMoriah Waterland pt++; 629*5c51f124SMoriah Waterland while (*pt && !isspace(*pt)) { 630*5c51f124SMoriah Waterland if (*pt == '$') { 631*5c51f124SMoriah Waterland pt2 = varname; 632*5c51f124SMoriah Waterland while (*++pt && !strchr("/= \t\n\r", *pt)) 633*5c51f124SMoriah Waterland *pt2++ = *pt; 634*5c51f124SMoriah Waterland *pt2 = '\0'; 635*5c51f124SMoriah Waterland if (pt2 = getenv(varname)) { 636*5c51f124SMoriah Waterland while (*pt2) 637*5c51f124SMoriah Waterland *copy++ = *pt2++; 638*5c51f124SMoriah Waterland } 639*5c51f124SMoriah Waterland } else 640*5c51f124SMoriah Waterland *copy++ = *pt++; 641*5c51f124SMoriah Waterland } 642*5c51f124SMoriah Waterland if (*pt) { 643*5c51f124SMoriah Waterland *copy++ = ' '; 644*5c51f124SMoriah Waterland goto token; 645*5c51f124SMoriah Waterland } 646*5c51f124SMoriah Waterland *copy = '\0'; 647*5c51f124SMoriah Waterland } 648*5c51f124SMoriah Waterland 649*5c51f124SMoriah Waterland static void 650*5c51f124SMoriah Waterland error(int flag) 651*5c51f124SMoriah Waterland { 652*5c51f124SMoriah Waterland static char *lasterr = NULL; 653*5c51f124SMoriah Waterland 654*5c51f124SMoriah Waterland if (lasterr != proto[nfp]) { 655*5c51f124SMoriah Waterland lasterr = proto[nfp]; 656*5c51f124SMoriah Waterland (void) fprintf(stderr, gettext("ERROR in %s:\n"), lasterr); 657*5c51f124SMoriah Waterland } 658*5c51f124SMoriah Waterland if (flag) 659*5c51f124SMoriah Waterland errflg++; 660*5c51f124SMoriah Waterland } 661*5c51f124SMoriah Waterland 662*5c51f124SMoriah Waterland /* Set up defaults and change to the build directory. */ 663*5c51f124SMoriah Waterland static void 664*5c51f124SMoriah Waterland pushenv(char *file) 665*5c51f124SMoriah Waterland { 666*5c51f124SMoriah Waterland register char *pt; 667*5c51f124SMoriah Waterland static char topdir[PATH_MAX]; 668*5c51f124SMoriah Waterland 669*5c51f124SMoriah Waterland if ((nfp+1) >= NRECURS) { 670*5c51f124SMoriah Waterland error(1); 671*5c51f124SMoriah Waterland logerr(gettext(MSG_NRECURS), NRECURS); 672*5c51f124SMoriah Waterland logerr(gettext(MSG_IGNINCLUDE), file); 673*5c51f124SMoriah Waterland return; 674*5c51f124SMoriah Waterland } 675*5c51f124SMoriah Waterland 676*5c51f124SMoriah Waterland if (strcmp(file, "-") == 0) { 677*5c51f124SMoriah Waterland fp = stdin; 678*5c51f124SMoriah Waterland } else if ((fp = fopen(file, "r")) == NULL) { 679*5c51f124SMoriah Waterland error(1); 680*5c51f124SMoriah Waterland logerr(gettext(MSG_RDINCLUDE), file, errno); 681*5c51f124SMoriah Waterland if (nfp >= 0) { 682*5c51f124SMoriah Waterland logerr(gettext(MSG_IGNINCLUDE), file); 683*5c51f124SMoriah Waterland fp = sfp[nfp]; 684*5c51f124SMoriah Waterland return; 685*5c51f124SMoriah Waterland } else 686*5c51f124SMoriah Waterland quit(1); 687*5c51f124SMoriah Waterland } 688*5c51f124SMoriah Waterland sfp[++nfp] = fp; 689*5c51f124SMoriah Waterland srchp[nfp][0] = NULL; 690*5c51f124SMoriah Waterland rootp[nfp][0] = NULL; 691*5c51f124SMoriah Waterland d_mod[nfp] = (mode_t)(-1); 692*5c51f124SMoriah Waterland d_own[nfp] = NULL; 693*5c51f124SMoriah Waterland d_grp[nfp] = NULL; 694*5c51f124SMoriah Waterland 695*5c51f124SMoriah Waterland if (!nfp) { 696*5c51f124SMoriah Waterland /* upper level proto file */ 697*5c51f124SMoriah Waterland proto[nfp] = file; 698*5c51f124SMoriah Waterland if (file[0] == '/') 699*5c51f124SMoriah Waterland pt = strcpy(topdir, file); 700*5c51f124SMoriah Waterland else { 701*5c51f124SMoriah Waterland /* path is relative to the prototype file specified */ 702*5c51f124SMoriah Waterland pt = getcwd(NULL, PATH_MAX); 703*5c51f124SMoriah Waterland if (pt == NULL) { 704*5c51f124SMoriah Waterland progerr(gettext(ERR_GETCWD), errno); 705*5c51f124SMoriah Waterland quit(99); 706*5c51f124SMoriah Waterland } 707*5c51f124SMoriah Waterland (void) snprintf(topdir, sizeof (topdir), 708*5c51f124SMoriah Waterland "%s/%s", pt, file); 709*5c51f124SMoriah Waterland } 710*5c51f124SMoriah Waterland if (pt = strrchr(topdir, '/')) 711*5c51f124SMoriah Waterland *pt = '\0'; /* should always happen */ 712*5c51f124SMoriah Waterland if (topdir[0] == '\0') 713*5c51f124SMoriah Waterland (void) strlcpy(topdir, "/", sizeof (topdir)); 714*5c51f124SMoriah Waterland dname[nfp] = topdir; 715*5c51f124SMoriah Waterland } else { 716*5c51f124SMoriah Waterland proto[nfp] = qstrdup(file); 717*5c51f124SMoriah Waterland dname[nfp] = qstrdup(file); 718*5c51f124SMoriah Waterland if (pt = strrchr(dname[nfp], '/')) 719*5c51f124SMoriah Waterland *pt = '\0'; 720*5c51f124SMoriah Waterland else { 721*5c51f124SMoriah Waterland /* same directory as the last prototype */ 722*5c51f124SMoriah Waterland free(dname[nfp]); 723*5c51f124SMoriah Waterland dname[nfp] = qstrdup(dname[nfp-1]); 724*5c51f124SMoriah Waterland return; /* no need to canonize() or chdir() */ 725*5c51f124SMoriah Waterland } 726*5c51f124SMoriah Waterland } 727*5c51f124SMoriah Waterland 728*5c51f124SMoriah Waterland canonize(dname[nfp]); 729*5c51f124SMoriah Waterland 730*5c51f124SMoriah Waterland if (chdir(dname[nfp])) { 731*5c51f124SMoriah Waterland error(1); 732*5c51f124SMoriah Waterland logerr(gettext(MSG_CHDIR), dname[nfp]); 733*5c51f124SMoriah Waterland if (!nfp) 734*5c51f124SMoriah Waterland quit(1); /* must be able to cd to upper level */ 735*5c51f124SMoriah Waterland logerr(gettext(MSG_IGNINCLUDE), proto[nfp]); 736*5c51f124SMoriah Waterland (void) popenv(); 737*5c51f124SMoriah Waterland } 738*5c51f124SMoriah Waterland } 739*5c51f124SMoriah Waterland 740*5c51f124SMoriah Waterland /* Restore defaults and return to the prior directory. */ 741*5c51f124SMoriah Waterland static int 742*5c51f124SMoriah Waterland popenv(void) 743*5c51f124SMoriah Waterland { 744*5c51f124SMoriah Waterland int i; 745*5c51f124SMoriah Waterland 746*5c51f124SMoriah Waterland (void) fclose(fp); 747*5c51f124SMoriah Waterland if (nfp) { 748*5c51f124SMoriah Waterland if (proto[nfp]) 749*5c51f124SMoriah Waterland free(proto[nfp]); 750*5c51f124SMoriah Waterland if (dname[nfp]) 751*5c51f124SMoriah Waterland free(dname[nfp]); 752*5c51f124SMoriah Waterland for (i = 0; srchp[nfp][i]; i++) 753*5c51f124SMoriah Waterland free(srchp[nfp][i]); 754*5c51f124SMoriah Waterland for (i = 0; rootp[nfp][i]; i++) 755*5c51f124SMoriah Waterland free(rootp[nfp][i]); 756*5c51f124SMoriah Waterland if (d_own[nfp]) 757*5c51f124SMoriah Waterland free(d_own[nfp]); 758*5c51f124SMoriah Waterland if (d_grp[nfp]) 759*5c51f124SMoriah Waterland free(d_grp[nfp]); 760*5c51f124SMoriah Waterland 761*5c51f124SMoriah Waterland fp = sfp[--nfp]; 762*5c51f124SMoriah Waterland 763*5c51f124SMoriah Waterland if (chdir(dname[nfp])) { 764*5c51f124SMoriah Waterland error(1); 765*5c51f124SMoriah Waterland logerr(gettext(MSG_CHDIR), dname[nfp]); 766*5c51f124SMoriah Waterland logerr(gettext(MSG_INCOMPLETE), proto[nfp]); 767*5c51f124SMoriah Waterland return (popenv()); 768*5c51f124SMoriah Waterland } 769*5c51f124SMoriah Waterland return (1); 770*5c51f124SMoriah Waterland } 771*5c51f124SMoriah Waterland return (0); 772*5c51f124SMoriah Waterland } 773*5c51f124SMoriah Waterland 774*5c51f124SMoriah Waterland /* 775*5c51f124SMoriah Waterland * If this parameter isn't already in place, put it into the local 776*5c51f124SMoriah Waterland * environment. This means that command line directives override prototype 777*5c51f124SMoriah Waterland * file directives. 778*5c51f124SMoriah Waterland */ 779*5c51f124SMoriah Waterland static void 780*5c51f124SMoriah Waterland lputenv(char *s) 781*5c51f124SMoriah Waterland { 782*5c51f124SMoriah Waterland char *pt; 783*5c51f124SMoriah Waterland int i; 784*5c51f124SMoriah Waterland 785*5c51f124SMoriah Waterland pt = strchr(s, '='); 786*5c51f124SMoriah Waterland if (!pt) 787*5c51f124SMoriah Waterland return; 788*5c51f124SMoriah Waterland 789*5c51f124SMoriah Waterland *pt = '\0'; 790*5c51f124SMoriah Waterland for (i = 0; i < nrdonly; i++) { 791*5c51f124SMoriah Waterland if (strcmp(rdonly[i], s) == 0) { 792*5c51f124SMoriah Waterland *pt = '='; 793*5c51f124SMoriah Waterland return; 794*5c51f124SMoriah Waterland } 795*5c51f124SMoriah Waterland } 796*5c51f124SMoriah Waterland *pt = '='; 797*5c51f124SMoriah Waterland 798*5c51f124SMoriah Waterland if (putenv(qstrdup(s))) { 799*5c51f124SMoriah Waterland progerr(gettext(ERR_ENVBUILD), errno); 800*5c51f124SMoriah Waterland quit(99); 801*5c51f124SMoriah Waterland } 802*5c51f124SMoriah Waterland } 803*5c51f124SMoriah Waterland 804*5c51f124SMoriah Waterland static char * 805*5c51f124SMoriah Waterland srchroot(char *path, char *copy) 806*5c51f124SMoriah Waterland { 807*5c51f124SMoriah Waterland struct stat statbuf; 808*5c51f124SMoriah Waterland int i; 809*5c51f124SMoriah Waterland 810*5c51f124SMoriah Waterland i = 0; 811*5c51f124SMoriah Waterland root = rootlist[i++]; 812*5c51f124SMoriah Waterland do { 813*5c51f124SMoriah Waterland /* convert with root & basedir info */ 814*5c51f124SMoriah Waterland cvtpath(path, copy); 815*5c51f124SMoriah Waterland /* make it pretty again */ 816*5c51f124SMoriah Waterland canonize(copy); 817*5c51f124SMoriah Waterland 818*5c51f124SMoriah Waterland if (stat(copy, &statbuf) || !(statbuf.st_mode & S_IFREG)) { 819*5c51f124SMoriah Waterland root = rootlist[i++]; 820*5c51f124SMoriah Waterland continue; /* host source must be a regular file */ 821*5c51f124SMoriah Waterland } 822*5c51f124SMoriah Waterland return (copy); 823*5c51f124SMoriah Waterland } while (root != NULL); 824*5c51f124SMoriah Waterland error(1); 825*5c51f124SMoriah Waterland logerr(gettext(MSG_SRCHROOT), path); 826*5c51f124SMoriah Waterland return (NULL); 827*5c51f124SMoriah Waterland } 828