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 2009 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland 28*5c51f124SMoriah Waterland /* 29*5c51f124SMoriah Waterland * This module contains all the code necessary to establish the key base 30*5c51f124SMoriah Waterland * directories to which the actual components of the package will be 31*5c51f124SMoriah Waterland * installed or removed. -- JST 32*5c51f124SMoriah Waterland */ 33*5c51f124SMoriah Waterland 34*5c51f124SMoriah Waterland #include <stdio.h> 35*5c51f124SMoriah Waterland #include <string.h> 36*5c51f124SMoriah Waterland #include <stdlib.h> 37*5c51f124SMoriah Waterland #include <unistd.h> 38*5c51f124SMoriah Waterland #include <sys/stat.h> /* mkdir() declaration */ 39*5c51f124SMoriah Waterland #include <libintl.h> 40*5c51f124SMoriah Waterland #include <pkglib.h> 41*5c51f124SMoriah Waterland #include <install.h> 42*5c51f124SMoriah Waterland #include <libadm.h> 43*5c51f124SMoriah Waterland #include <libinst.h> 44*5c51f124SMoriah Waterland 45*5c51f124SMoriah Waterland static char *install_root = NULL; 46*5c51f124SMoriah Waterland static int install_root_exists = 0; /* An install root was specified */ 47*5c51f124SMoriah Waterland static int install_root_len; /* strlen(install_root) */ 48*5c51f124SMoriah Waterland static char *orig_basedir = NULL; /* The unadjusted basedir */ 49*5c51f124SMoriah Waterland static char *basedir = NULL; /* basedir (cmb w/ inst rt if req) */ 50*5c51f124SMoriah Waterland static int basedir_exists = 0; /* There are relocatable paths */ 51*5c51f124SMoriah Waterland static char *client_basedir = NULL; 52*5c51f124SMoriah Waterland static int client_basedir_exists = 0; /* Installing from a host */ 53*5c51f124SMoriah Waterland static char *env_cl_bdir = NULL; /* CLIENT_BASEDIR from environment */ 54*5c51f124SMoriah Waterland static int ir_accessed = 0; /* install_root has been used */ 55*5c51f124SMoriah Waterland static int relocatable; /* set_basedir() assumed this */ 56*5c51f124SMoriah Waterland static int partial_inst = 0; /* Installing pkg from partial spool directory */ 57*5c51f124SMoriah Waterland static boolean_t depend_pkginfo_DB = B_FALSE; /* Only update depend/pkginfoDB */ 58*5c51f124SMoriah Waterland static int partial_spool_create = 0; /* Create partial spool dir */ 59*5c51f124SMoriah Waterland 60*5c51f124SMoriah Waterland static int ask_basedir(char *path, int nointeract); 61*5c51f124SMoriah Waterland static char *expand_path(char *path); 62*5c51f124SMoriah Waterland static int set_client_basedir(void); 63*5c51f124SMoriah Waterland static char *fixpath_dup(char *path); 64*5c51f124SMoriah Waterland static int orig_offset_rel; 65*5c51f124SMoriah Waterland 66*5c51f124SMoriah Waterland /* 67*5c51f124SMoriah Waterland * base_sepr and rel_fmt support construction of absolute paths from 68*5c51f124SMoriah Waterland * relative paths. 69*5c51f124SMoriah Waterland */ 70*5c51f124SMoriah Waterland static int base_sepr = 1; /* separator length btwn basedir & path */ 71*5c51f124SMoriah Waterland static char *rel_fmt[] = { "%s%s", "%s/%s" }; 72*5c51f124SMoriah Waterland 73*5c51f124SMoriah Waterland static int eval_valid = 0; /* everything set up to do an eval_path() */ 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland /* libpkg/gpkgmap.c */ 76*5c51f124SMoriah Waterland extern int getmapmode(); 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland #define MSG_IR_REPL "Replacing current install root with %s." 79*5c51f124SMoriah Waterland #define ERR_IRSET "Install_root has already been set to <%s> and used." 80*5c51f124SMoriah Waterland #define ERR_IRNOTABS "Install_root (-R option) requires an absolute " \ 81*5c51f124SMoriah Waterland "pathname: <%s>" 82*5c51f124SMoriah Waterland #define ERR_ALLOCFAILED "insufficient memory in %s" 83*5c51f124SMoriah Waterland #define ERR_ADMIN_INVAL "Invalid basedir entry in admin file." 84*5c51f124SMoriah Waterland #define ERR_PATHNAME "Path name is invalid" 85*5c51f124SMoriah Waterland #define ERR_RELINABS "Relative path <%s> found in absolute package." 86*5c51f124SMoriah Waterland #define ERR_CL_MIS "Constructed CLIENT_BASEDIR <%s> and " \ 87*5c51f124SMoriah Waterland "environment CLIENT_BASEDIR <%s> do not match." 88*5c51f124SMoriah Waterland #define ERR_ASKBD "%s is already installed at %s. Cannot create a " \ 89*5c51f124SMoriah Waterland "duplicate installation at %s." 90*5c51f124SMoriah Waterland #define ERR_NO_CL_BD "Cannot resolve CLIENT_BASEDIR conflicts." 91*5c51f124SMoriah Waterland #define ERR_AMBDIRS "Cannot evaluate path due to ambiguous " \ 92*5c51f124SMoriah Waterland "base directories." 93*5c51f124SMoriah Waterland #define ERR_NODELETE "unable to delete <%s>." 94*5c51f124SMoriah Waterland #define ERR_MKBASE "unable to make directory <%s>." 95*5c51f124SMoriah Waterland #define MSG_REQBASEDIR "Installation of this package requires a base " \ 96*5c51f124SMoriah Waterland "directory." 97*5c51f124SMoriah Waterland 98*5c51f124SMoriah Waterland #define MSG_MUSTEXIST "\\nThe selected base directory <%s> must exist " \ 99*5c51f124SMoriah Waterland "before installation is attempted." 100*5c51f124SMoriah Waterland #define MSG_YORNPRMPT "Do you want this directory created now" 101*5c51f124SMoriah Waterland 102*5c51f124SMoriah Waterland #define MSG_ISAFILE "\\nThe selected base directory <%s> must exist " \ 103*5c51f124SMoriah Waterland "before installation is attempted, but a file " \ 104*5c51f124SMoriah Waterland "already exists in it's place." 105*5c51f124SMoriah Waterland #define MSG_YORNFILE "Do you want the file deleted and the directory " \ 106*5c51f124SMoriah Waterland "created now" 107*5c51f124SMoriah Waterland 108*5c51f124SMoriah Waterland #define MSG_PROMPT "Enter path to package base directory" 109*5c51f124SMoriah Waterland 110*5c51f124SMoriah Waterland #define MSG_HELP "Installation of this package requires that a UNIX " \ 111*5c51f124SMoriah Waterland "directory be available for installation of " \ 112*5c51f124SMoriah Waterland "appropriate software. This directory may be part " \ 113*5c51f124SMoriah Waterland "of any mounted filesystem, or may itself be a " \ 114*5c51f124SMoriah Waterland "mount point. In general, it is unwise to select a " \ 115*5c51f124SMoriah Waterland "base directory which already contains other files " \ 116*5c51f124SMoriah Waterland "and/or directories." 117*5c51f124SMoriah Waterland 118*5c51f124SMoriah Waterland /* 119*5c51f124SMoriah Waterland * Set the install root (-R option). 120*5c51f124SMoriah Waterland */ 121*5c51f124SMoriah Waterland 122*5c51f124SMoriah Waterland int 123*5c51f124SMoriah Waterland set_inst_root(char *path) 124*5c51f124SMoriah Waterland { 125*5c51f124SMoriah Waterland static char tmp_path[PATH_MAX]; 126*5c51f124SMoriah Waterland 127*5c51f124SMoriah Waterland /* 128*5c51f124SMoriah Waterland * If we've already set the install_root but no one has used it 129*5c51f124SMoriah Waterland * yet, we'll complain and allow the change. If it's been used 130*5c51f124SMoriah Waterland * then we'll deny the switch & return failed. 131*5c51f124SMoriah Waterland */ 132*5c51f124SMoriah Waterland if (install_root_exists) 133*5c51f124SMoriah Waterland /* If the two install_roots are different - problem */ 134*5c51f124SMoriah Waterland if (strcmp(install_root, path)) 135*5c51f124SMoriah Waterland /* We are trying to *change* the install_root */ 136*5c51f124SMoriah Waterland if (ir_accessed) { 137*5c51f124SMoriah Waterland ptext(stderr, gettext(ERR_IRSET), path); 138*5c51f124SMoriah Waterland return (0); 139*5c51f124SMoriah Waterland } else { /* !ir_accessed */ 140*5c51f124SMoriah Waterland ptext(stderr, gettext(MSG_IR_REPL), path); 141*5c51f124SMoriah Waterland install_root_exists = 0; /* reset */ 142*5c51f124SMoriah Waterland install_root = NULL; 143*5c51f124SMoriah Waterland } 144*5c51f124SMoriah Waterland 145*5c51f124SMoriah Waterland if (path && *path) { 146*5c51f124SMoriah Waterland if (*path != '/') { 147*5c51f124SMoriah Waterland ptext(stderr, gettext(ERR_IRNOTABS), path); 148*5c51f124SMoriah Waterland return (0); 149*5c51f124SMoriah Waterland } 150*5c51f124SMoriah Waterland 151*5c51f124SMoriah Waterland (void) strlcpy(tmp_path, path, sizeof (tmp_path)); 152*5c51f124SMoriah Waterland 153*5c51f124SMoriah Waterland canonize(tmp_path); 154*5c51f124SMoriah Waterland 155*5c51f124SMoriah Waterland install_root = tmp_path; 156*5c51f124SMoriah Waterland 157*5c51f124SMoriah Waterland install_root_exists = 1; 158*5c51f124SMoriah Waterland 159*5c51f124SMoriah Waterland install_root_len = strlen(install_root); 160*5c51f124SMoriah Waterland 161*5c51f124SMoriah Waterland /* If install_root is '/' then it's trivial. */ 162*5c51f124SMoriah Waterland if (install_root_len == 1) 163*5c51f124SMoriah Waterland install_root_len = 0; 164*5c51f124SMoriah Waterland else 165*5c51f124SMoriah Waterland z_set_zone_root(install_root); 166*5c51f124SMoriah Waterland } else 167*5c51f124SMoriah Waterland install_root_exists = 0; 168*5c51f124SMoriah Waterland 169*5c51f124SMoriah Waterland return (1); 170*5c51f124SMoriah Waterland } 171*5c51f124SMoriah Waterland 172*5c51f124SMoriah Waterland /* 173*5c51f124SMoriah Waterland * This routine returns a path with the correct install_root prepended. 174*5c51f124SMoriah Waterland * if the install_root has been set. NOTE : this allocates memory 175*5c51f124SMoriah Waterland * which will need to be freed at some point. 176*5c51f124SMoriah Waterland */ 177*5c51f124SMoriah Waterland char * 178*5c51f124SMoriah Waterland fixpath(char *path) 179*5c51f124SMoriah Waterland { 180*5c51f124SMoriah Waterland register char *npath_ptr, *ir_ptr; 181*5c51f124SMoriah Waterland char *npath = NULL; 182*5c51f124SMoriah Waterland 183*5c51f124SMoriah Waterland if (path && *path) { 184*5c51f124SMoriah Waterland if (install_root_exists) { 185*5c51f124SMoriah Waterland if ((npath = 186*5c51f124SMoriah Waterland calloc(1, strlen(path) + install_root_len + 187*5c51f124SMoriah Waterland 1)) == NULL) { 188*5c51f124SMoriah Waterland progerr(gettext(ERR_ALLOCFAILED), "fixpath()"); 189*5c51f124SMoriah Waterland quit(99); 190*5c51f124SMoriah Waterland } 191*5c51f124SMoriah Waterland 192*5c51f124SMoriah Waterland npath_ptr = npath; 193*5c51f124SMoriah Waterland ir_ptr = get_inst_root(); 194*5c51f124SMoriah Waterland 195*5c51f124SMoriah Waterland while (*ir_ptr) /* for every char in install_root */ 196*5c51f124SMoriah Waterland *npath_ptr++ = *ir_ptr++; /* copy it */ 197*5c51f124SMoriah Waterland 198*5c51f124SMoriah Waterland /* 199*5c51f124SMoriah Waterland * If install_root == "/", a concatenation will 200*5c51f124SMoriah Waterland * result in a return value of "//...", same goes 201*5c51f124SMoriah Waterland * for an install_root ending in '/'. So we back 202*5c51f124SMoriah Waterland * over a trailing '/' if it's there. 203*5c51f124SMoriah Waterland */ 204*5c51f124SMoriah Waterland if (*(npath_ptr - 1) == '/') 205*5c51f124SMoriah Waterland npath_ptr--; 206*5c51f124SMoriah Waterland 207*5c51f124SMoriah Waterland if (strcmp(path, "/")) 208*5c51f124SMoriah Waterland (void) strcpy(npath_ptr, path); 209*5c51f124SMoriah Waterland } else 210*5c51f124SMoriah Waterland /* 211*5c51f124SMoriah Waterland * If there's no install root & no client_basedir, 212*5c51f124SMoriah Waterland * then return the path 213*5c51f124SMoriah Waterland */ 214*5c51f124SMoriah Waterland npath = strdup(path); 215*5c51f124SMoriah Waterland } else 216*5c51f124SMoriah Waterland /* 217*5c51f124SMoriah Waterland * If there's no path specified, return the install root 218*5c51f124SMoriah Waterland * since no matter what happens, this is where the 219*5c51f124SMoriah Waterland * path will have to start. 220*5c51f124SMoriah Waterland */ 221*5c51f124SMoriah Waterland if (install_root_exists) 222*5c51f124SMoriah Waterland npath = strdup(get_inst_root()); 223*5c51f124SMoriah Waterland 224*5c51f124SMoriah Waterland return (npath); 225*5c51f124SMoriah Waterland } 226*5c51f124SMoriah Waterland 227*5c51f124SMoriah Waterland /* 228*5c51f124SMoriah Waterland * This routine does what fixpath() does except it's for high-volume 229*5c51f124SMoriah Waterland * stuff restricted to the instvol() function. By using 230*5c51f124SMoriah Waterland * pathdup() and pathalloc() memory fragmentation is reduced. Also, the 231*5c51f124SMoriah Waterland * memory allocated by pathdup() and pathalloc() gets freed at the end 232*5c51f124SMoriah Waterland * of each volume installed. 233*5c51f124SMoriah Waterland */ 234*5c51f124SMoriah Waterland char * 235*5c51f124SMoriah Waterland fixpath_dup(char *path) 236*5c51f124SMoriah Waterland { 237*5c51f124SMoriah Waterland register char *npath_ptr, *ir_ptr; 238*5c51f124SMoriah Waterland char *npath = NULL; 239*5c51f124SMoriah Waterland 240*5c51f124SMoriah Waterland if (path && *path) { 241*5c51f124SMoriah Waterland if (install_root_exists) { 242*5c51f124SMoriah Waterland npath = pathalloc(strlen(path) + install_root_len + 1); 243*5c51f124SMoriah Waterland 244*5c51f124SMoriah Waterland npath_ptr = npath; 245*5c51f124SMoriah Waterland ir_ptr = get_inst_root(); 246*5c51f124SMoriah Waterland 247*5c51f124SMoriah Waterland while (*ir_ptr) /* for every char in install_root */ 248*5c51f124SMoriah Waterland *npath_ptr++ = *ir_ptr++; /* copy it */ 249*5c51f124SMoriah Waterland 250*5c51f124SMoriah Waterland /* 251*5c51f124SMoriah Waterland * If install_root == "/", a concatenation will 252*5c51f124SMoriah Waterland * result in a return value of "//...", same goes 253*5c51f124SMoriah Waterland * for an install_root ending in '/'. So we back 254*5c51f124SMoriah Waterland * over a trailing '/' if it's there. 255*5c51f124SMoriah Waterland */ 256*5c51f124SMoriah Waterland if (*(npath_ptr - 1) == '/') 257*5c51f124SMoriah Waterland npath_ptr--; 258*5c51f124SMoriah Waterland 259*5c51f124SMoriah Waterland if (strcmp(path, "/")) 260*5c51f124SMoriah Waterland (void) strcpy(npath_ptr, path); 261*5c51f124SMoriah Waterland } else 262*5c51f124SMoriah Waterland /* 263*5c51f124SMoriah Waterland * If there's no install root & no client_basedir, 264*5c51f124SMoriah Waterland * then return the path 265*5c51f124SMoriah Waterland */ 266*5c51f124SMoriah Waterland npath = pathdup(path); 267*5c51f124SMoriah Waterland } else 268*5c51f124SMoriah Waterland /* 269*5c51f124SMoriah Waterland * If there's no path specified, return the install root 270*5c51f124SMoriah Waterland * since no matter what happens, this is where the 271*5c51f124SMoriah Waterland * path will have to start. 272*5c51f124SMoriah Waterland */ 273*5c51f124SMoriah Waterland if (install_root_exists) 274*5c51f124SMoriah Waterland npath = pathdup(get_inst_root()); 275*5c51f124SMoriah Waterland 276*5c51f124SMoriah Waterland return (npath); 277*5c51f124SMoriah Waterland } 278*5c51f124SMoriah Waterland 279*5c51f124SMoriah Waterland /* 280*5c51f124SMoriah Waterland * This returns a pointer to a static name. This could be abused. 281*5c51f124SMoriah Waterland * -- JST (1993-07-21) 282*5c51f124SMoriah Waterland */ 283*5c51f124SMoriah Waterland char * 284*5c51f124SMoriah Waterland get_inst_root(void) 285*5c51f124SMoriah Waterland { 286*5c51f124SMoriah Waterland ir_accessed = 1; /* we can't change it now */ 287*5c51f124SMoriah Waterland return (install_root); 288*5c51f124SMoriah Waterland } 289*5c51f124SMoriah Waterland 290*5c51f124SMoriah Waterland /* 291*5c51f124SMoriah Waterland * This routine takes path and removes install_root from the path 292*5c51f124SMoriah Waterland * if it has already been prepended. If install_root is not prepended to 293*5c51f124SMoriah Waterland * path or install_root is '/' or path == NULL then path is returned 294*5c51f124SMoriah Waterland * as is. If the resulting path is somehow relative, a corrupt 295*5c51f124SMoriah Waterland * package name error is raised and the program quits. NOTE : This 296*5c51f124SMoriah Waterland * function usually returns a pointer into the original path 297*5c51f124SMoriah Waterland * argument. It doesn't allocate new memory. This is possible, 298*5c51f124SMoriah Waterland * of course, because the path being returned is guaranteed to 299*5c51f124SMoriah Waterland * be a subset of the original argument unless basedir = '/' in 300*5c51f124SMoriah Waterland * which case a pointer to a static "/" is returned. See 301*5c51f124SMoriah Waterland * orig_path() below if you want to be handed a new copy of the 302*5c51f124SMoriah Waterland * return value. 303*5c51f124SMoriah Waterland */ 304*5c51f124SMoriah Waterland char * 305*5c51f124SMoriah Waterland orig_path_ptr(char *path) 306*5c51f124SMoriah Waterland { 307*5c51f124SMoriah Waterland char *retv = NULL; 308*5c51f124SMoriah Waterland 309*5c51f124SMoriah Waterland if (path && *path) { /* as long as we got an argument */ 310*5c51f124SMoriah Waterland if (!install_root_exists) /* if no install_root */ 311*5c51f124SMoriah Waterland retv = path; /* path unchanged */ 312*5c51f124SMoriah Waterland 313*5c51f124SMoriah Waterland /* 314*5c51f124SMoriah Waterland * Otherwise, if install_root is really prepended to the path 315*5c51f124SMoriah Waterland * then remove it dealing appropriately with special cases. 316*5c51f124SMoriah Waterland */ 317*5c51f124SMoriah Waterland else if (strncmp(path, install_root, install_root_len) == 0) { 318*5c51f124SMoriah Waterland retv = path + install_root_len; 319*5c51f124SMoriah Waterland if (*retv == NULL) 320*5c51f124SMoriah Waterland retv = "/"; 321*5c51f124SMoriah Waterland 322*5c51f124SMoriah Waterland /* 323*5c51f124SMoriah Waterland * The result will be relative if install_root = '/'. 324*5c51f124SMoriah Waterland * If the basedir path was built legally, then moving 325*5c51f124SMoriah Waterland * the pointer back one character will make it 326*5c51f124SMoriah Waterland * absolute. If that fails then the path we got was 327*5c51f124SMoriah Waterland * incorrectly constructed in the first place. 328*5c51f124SMoriah Waterland */ 329*5c51f124SMoriah Waterland else if (*retv != '/') { 330*5c51f124SMoriah Waterland retv--; 331*5c51f124SMoriah Waterland if (*retv != '/') { 332*5c51f124SMoriah Waterland progerr(gettext(ERR_PATHNAME)); 333*5c51f124SMoriah Waterland quit(99); 334*5c51f124SMoriah Waterland } 335*5c51f124SMoriah Waterland } 336*5c51f124SMoriah Waterland } else 337*5c51f124SMoriah Waterland retv = path; /* All else failing, return path. */ 338*5c51f124SMoriah Waterland 339*5c51f124SMoriah Waterland canonize(retv); 340*5c51f124SMoriah Waterland } 341*5c51f124SMoriah Waterland 342*5c51f124SMoriah Waterland return (retv); 343*5c51f124SMoriah Waterland } 344*5c51f124SMoriah Waterland 345*5c51f124SMoriah Waterland /* 346*5c51f124SMoriah Waterland * This function does the same as orig_path_ptr() except that it mallocs 347*5c51f124SMoriah Waterland * new space and provides a new copy of the original basedir path which 348*5c51f124SMoriah Waterland * needs to be free()'d one way or another later. 349*5c51f124SMoriah Waterland */ 350*5c51f124SMoriah Waterland char * 351*5c51f124SMoriah Waterland orig_path(char *path) 352*5c51f124SMoriah Waterland { 353*5c51f124SMoriah Waterland char *retv; 354*5c51f124SMoriah Waterland 355*5c51f124SMoriah Waterland retv = orig_path_ptr(path); 356*5c51f124SMoriah Waterland 357*5c51f124SMoriah Waterland return ((retv == NULL) ? retv : strdup(retv)); 358*5c51f124SMoriah Waterland } 359*5c51f124SMoriah Waterland 360*5c51f124SMoriah Waterland /* 361*5c51f124SMoriah Waterland * This function lets us hold onto the environment's version of 362*5c51f124SMoriah Waterland * CLIENT_BASEDIR for later review by set_client_basedir(). 363*5c51f124SMoriah Waterland */ 364*5c51f124SMoriah Waterland void 365*5c51f124SMoriah Waterland set_env_cbdir() 366*5c51f124SMoriah Waterland { 367*5c51f124SMoriah Waterland register char *cb_ptr; 368*5c51f124SMoriah Waterland 369*5c51f124SMoriah Waterland cb_ptr = getenv("CLIENT_BASEDIR"); 370*5c51f124SMoriah Waterland 371*5c51f124SMoriah Waterland if (cb_ptr && *cb_ptr) { 372*5c51f124SMoriah Waterland env_cl_bdir = strdup(cb_ptr); 373*5c51f124SMoriah Waterland canonize(env_cl_bdir); 374*5c51f124SMoriah Waterland } 375*5c51f124SMoriah Waterland } 376*5c51f124SMoriah Waterland 377*5c51f124SMoriah Waterland /* ask for the basedir */ 378*5c51f124SMoriah Waterland static int 379*5c51f124SMoriah Waterland ask_basedir(char *path, int nointeract) 380*5c51f124SMoriah Waterland { 381*5c51f124SMoriah Waterland int n; 382*5c51f124SMoriah Waterland 383*5c51f124SMoriah Waterland if (nointeract) { 384*5c51f124SMoriah Waterland progerr(gettext(MSG_REQBASEDIR)); 385*5c51f124SMoriah Waterland return (5); 386*5c51f124SMoriah Waterland } else { 387*5c51f124SMoriah Waterland path[0] = '\0'; 388*5c51f124SMoriah Waterland if (n = ckpath(path, P_ABSOLUTE|P_DIR|P_WRITE, 389*5c51f124SMoriah Waterland basedir, NULL, gettext(MSG_HELP), 390*5c51f124SMoriah Waterland gettext(MSG_PROMPT))) 391*5c51f124SMoriah Waterland return (n); /* FAIL */ 392*5c51f124SMoriah Waterland orig_basedir = 393*5c51f124SMoriah Waterland expand_path(path); 394*5c51f124SMoriah Waterland } 395*5c51f124SMoriah Waterland return (0); 396*5c51f124SMoriah Waterland } 397*5c51f124SMoriah Waterland 398*5c51f124SMoriah Waterland /* 399*5c51f124SMoriah Waterland * Set the basedir and client_basedir based on install root and config 400*5c51f124SMoriah Waterland * files. It returns 0 if all OK otherwise returns the error code base 401*5c51f124SMoriah Waterland * appropriate to the problem. 402*5c51f124SMoriah Waterland */ 403*5c51f124SMoriah Waterland int 404*5c51f124SMoriah Waterland set_basedirs(int reloc, char *adm_basedir, char *pkginst, int nointeract) 405*5c51f124SMoriah Waterland { 406*5c51f124SMoriah Waterland char path[PATH_MAX]; 407*5c51f124SMoriah Waterland int n; 408*5c51f124SMoriah Waterland 409*5c51f124SMoriah Waterland relocatable = reloc; 410*5c51f124SMoriah Waterland 411*5c51f124SMoriah Waterland /* 412*5c51f124SMoriah Waterland * If there are no relocatable files basedir is probably meaningless 413*5c51f124SMoriah Waterland * so we skip ahead to the simple tests. Otherwise we do the twisted 414*5c51f124SMoriah Waterland * stuff below. The BASEDIR is set based on the following heirarchy : 415*5c51f124SMoriah Waterland * 1. The entry in the admin file 416*5c51f124SMoriah Waterland * 2. The entry in the pkginfo file delivered on the medium 417*5c51f124SMoriah Waterland * 3. The entry in the already installed pkginfo file 418*5c51f124SMoriah Waterland * 4. ask 419*5c51f124SMoriah Waterland * If it's not a relocatable package, we go with whatever seems 420*5c51f124SMoriah Waterland * reasonable; if it's relocatable and we've exhausted our 421*5c51f124SMoriah Waterland * options, we ask. 422*5c51f124SMoriah Waterland */ 423*5c51f124SMoriah Waterland if (reloc) { 424*5c51f124SMoriah Waterland int is_adm_basedir = (adm_basedir && *adm_basedir); 425*5c51f124SMoriah Waterland int is_update = 0; 426*5c51f124SMoriah Waterland int is_ask = 0; 427*5c51f124SMoriah Waterland 428*5c51f124SMoriah Waterland if (is_adm_basedir) { 429*5c51f124SMoriah Waterland if (strcmp(adm_basedir, "update") == 0) { 430*5c51f124SMoriah Waterland is_update = 1; 431*5c51f124SMoriah Waterland is_ask = 1; 432*5c51f124SMoriah Waterland } else if (strcmp(adm_basedir, "ask") == 0) 433*5c51f124SMoriah Waterland is_ask = 1; 434*5c51f124SMoriah Waterland } 435*5c51f124SMoriah Waterland 436*5c51f124SMoriah Waterland /* 437*5c51f124SMoriah Waterland * If there's a BASEDIR in the admin file & it's a valid 438*5c51f124SMoriah Waterland * absolute pathname, use it. 439*5c51f124SMoriah Waterland */ 440*5c51f124SMoriah Waterland if (is_adm_basedir && strchr("/$", *adm_basedir)) 441*5c51f124SMoriah Waterland orig_basedir = expand_path(adm_basedir); 442*5c51f124SMoriah Waterland 443*5c51f124SMoriah Waterland /* If admin says 'ask regardless', ask and continue */ 444*5c51f124SMoriah Waterland else if (is_adm_basedir && is_ask) { 445*5c51f124SMoriah Waterland if (n = ask_basedir(path, nointeract)) 446*5c51f124SMoriah Waterland return (n); 447*5c51f124SMoriah Waterland if (is_update && 448*5c51f124SMoriah Waterland strcmp(orig_basedir, 449*5c51f124SMoriah Waterland (basedir = getenv("BASEDIR"))) != 0) { 450*5c51f124SMoriah Waterland progerr(gettext(ERR_ASKBD), 451*5c51f124SMoriah Waterland getenv("PKG"), basedir, orig_basedir); 452*5c51f124SMoriah Waterland quit(4); 453*5c51f124SMoriah Waterland } 454*5c51f124SMoriah Waterland } 455*5c51f124SMoriah Waterland /* 456*5c51f124SMoriah Waterland * If it isn't the only other valid option, 457*5c51f124SMoriah Waterland * namely 'default', quit FAIL. 458*5c51f124SMoriah Waterland */ 459*5c51f124SMoriah Waterland else if (is_adm_basedir && 460*5c51f124SMoriah Waterland strcmp(adm_basedir, "default") != 0) { 461*5c51f124SMoriah Waterland progerr(gettext(ERR_ADMIN_INVAL)); 462*5c51f124SMoriah Waterland return (1); 463*5c51f124SMoriah Waterland 464*5c51f124SMoriah Waterland /* 465*5c51f124SMoriah Waterland * OK, the admin file has no preference, so we go to the 466*5c51f124SMoriah Waterland * other sources. 467*5c51f124SMoriah Waterland */ 468*5c51f124SMoriah Waterland } else { 469*5c51f124SMoriah Waterland /* 470*5c51f124SMoriah Waterland * Check to see if BASEDIR is set in the environment 471*5c51f124SMoriah Waterland * (probably from the pkginfo file on the installation 472*5c51f124SMoriah Waterland * medium). 473*5c51f124SMoriah Waterland */ 474*5c51f124SMoriah Waterland basedir = getenv("BASEDIR"); 475*5c51f124SMoriah Waterland if (basedir && *basedir) 476*5c51f124SMoriah Waterland orig_basedir = expand_path(basedir); 477*5c51f124SMoriah Waterland else { 478*5c51f124SMoriah Waterland /* 479*5c51f124SMoriah Waterland * Check to see if the package BASEDIR was 480*5c51f124SMoriah Waterland * already defined during a previous 481*5c51f124SMoriah Waterland * installation of this package instance. The 482*5c51f124SMoriah Waterland * function below looks for an installed 483*5c51f124SMoriah Waterland * pkginfo file and scans it. 484*5c51f124SMoriah Waterland */ 485*5c51f124SMoriah Waterland basedir = pkgparam(pkginst, "BASEDIR"); 486*5c51f124SMoriah Waterland if (basedir && *basedir) 487*5c51f124SMoriah Waterland orig_basedir = expand_path(basedir); 488*5c51f124SMoriah Waterland else if (n = ask_basedir(path, nointeract)) 489*5c51f124SMoriah Waterland return (n); 490*5c51f124SMoriah Waterland } 491*5c51f124SMoriah Waterland } 492*5c51f124SMoriah Waterland } else { /* not relocatable */ 493*5c51f124SMoriah Waterland /* 494*5c51f124SMoriah Waterland * Since all paths are absolute the only reason to have a 495*5c51f124SMoriah Waterland * basedir is if there's an install root meaning there's 496*5c51f124SMoriah Waterland * really a basedir relative to this host or this package is 497*5c51f124SMoriah Waterland * absolute only because it's sparse in which case we're 498*5c51f124SMoriah Waterland * interested in the prior basedir. So we next check for a 499*5c51f124SMoriah Waterland * prior basedir and then an install root. 500*5c51f124SMoriah Waterland */ 501*5c51f124SMoriah Waterland basedir = pkgparam(pkginst, "BASEDIR"); 502*5c51f124SMoriah Waterland if (basedir && *basedir) 503*5c51f124SMoriah Waterland orig_basedir = expand_path(basedir); 504*5c51f124SMoriah Waterland 505*5c51f124SMoriah Waterland else if (install_root_exists) 506*5c51f124SMoriah Waterland /* 507*5c51f124SMoriah Waterland * If we have a basedir *only because* 508*5c51f124SMoriah Waterland * we have an install_root, we need to 509*5c51f124SMoriah Waterland * set orig_basedir to '/' to simplify 510*5c51f124SMoriah Waterland * later attempts to force 511*5c51f124SMoriah Waterland * client_basedir. 512*5c51f124SMoriah Waterland */ 513*5c51f124SMoriah Waterland orig_basedir = "/"; 514*5c51f124SMoriah Waterland else { 515*5c51f124SMoriah Waterland eval_valid++; /* we can run eval_path() now */ 516*5c51f124SMoriah Waterland return (0); /* fixpath below unnecessary */ 517*5c51f124SMoriah Waterland } 518*5c51f124SMoriah Waterland } 519*5c51f124SMoriah Waterland 520*5c51f124SMoriah Waterland basedir_exists = 1; 521*5c51f124SMoriah Waterland 522*5c51f124SMoriah Waterland basedir = fixpath(orig_basedir); 523*5c51f124SMoriah Waterland 524*5c51f124SMoriah Waterland /* 525*5c51f124SMoriah Waterland * If basedir == "/" then there's no need for a "/" between 526*5c51f124SMoriah Waterland * it and the rest of the path. 527*5c51f124SMoriah Waterland */ 528*5c51f124SMoriah Waterland if (strcmp(basedir, "/") == 0) 529*5c51f124SMoriah Waterland base_sepr = 0; 530*5c51f124SMoriah Waterland 531*5c51f124SMoriah Waterland if (set_client_basedir() == 0) { 532*5c51f124SMoriah Waterland progerr(gettext(ERR_NO_CL_BD)); 533*5c51f124SMoriah Waterland return (1); 534*5c51f124SMoriah Waterland } 535*5c51f124SMoriah Waterland 536*5c51f124SMoriah Waterland eval_valid++; /* we've confirmed the validity of everything */ 537*5c51f124SMoriah Waterland 538*5c51f124SMoriah Waterland return (0); 539*5c51f124SMoriah Waterland } 540*5c51f124SMoriah Waterland 541*5c51f124SMoriah Waterland /* 542*5c51f124SMoriah Waterland * Make a directory from a path and all necessary directories above it as 543*5c51f124SMoriah Waterland * needed. 544*5c51f124SMoriah Waterland */ 545*5c51f124SMoriah Waterland int 546*5c51f124SMoriah Waterland mkpath(char *p) 547*5c51f124SMoriah Waterland { 548*5c51f124SMoriah Waterland char *pt; 549*5c51f124SMoriah Waterland 550*5c51f124SMoriah Waterland /* if entire path exists, return o.k. */ 551*5c51f124SMoriah Waterland 552*5c51f124SMoriah Waterland if (access(p, F_OK) == 0) { 553*5c51f124SMoriah Waterland return (0); 554*5c51f124SMoriah Waterland } 555*5c51f124SMoriah Waterland 556*5c51f124SMoriah Waterland /* entire path not there - check components and create */ 557*5c51f124SMoriah Waterland 558*5c51f124SMoriah Waterland pt = (*p == '/') ? p+1 : p; 559*5c51f124SMoriah Waterland do { 560*5c51f124SMoriah Waterland if (pt = strchr(pt, '/')) { 561*5c51f124SMoriah Waterland *pt = '\0'; 562*5c51f124SMoriah Waterland } 563*5c51f124SMoriah Waterland if ((access(p, F_OK) != 0) && (mkdir(p, 0755) != 0)) { 564*5c51f124SMoriah Waterland return (-1); 565*5c51f124SMoriah Waterland } 566*5c51f124SMoriah Waterland if (pt) { 567*5c51f124SMoriah Waterland *pt++ = '/'; 568*5c51f124SMoriah Waterland } 569*5c51f124SMoriah Waterland } while (pt); 570*5c51f124SMoriah Waterland 571*5c51f124SMoriah Waterland return (0); 572*5c51f124SMoriah Waterland } 573*5c51f124SMoriah Waterland 574*5c51f124SMoriah Waterland /* This makes the required base directory if necessary */ 575*5c51f124SMoriah Waterland void 576*5c51f124SMoriah Waterland mkbasedir(int flag, char *basedir) 577*5c51f124SMoriah Waterland { 578*5c51f124SMoriah Waterland char ans[MAX_INPUT]; 579*5c51f124SMoriah Waterland int n; 580*5c51f124SMoriah Waterland 581*5c51f124SMoriah Waterland /* 582*5c51f124SMoriah Waterland * If a base directory is called for but there's no such directory on 583*5c51f124SMoriah Waterland * the system, deal with that issue. 584*5c51f124SMoriah Waterland */ 585*5c51f124SMoriah Waterland if (is_a_basedir() && isdir(basedir)) { 586*5c51f124SMoriah Waterland if (flag) { /* Interaction is OK. */ 587*5c51f124SMoriah Waterland /* 588*5c51f124SMoriah Waterland * If there's a non-directory object in the way, ask. 589*5c51f124SMoriah Waterland */ 590*5c51f124SMoriah Waterland if (access(basedir, F_OK) == 0) { 591*5c51f124SMoriah Waterland ptext(stderr, gettext(MSG_ISAFILE), basedir); 592*5c51f124SMoriah Waterland 593*5c51f124SMoriah Waterland if (n = ckyorn(ans, NULL, NULL, NULL, 594*5c51f124SMoriah Waterland gettext(MSG_YORNFILE))) 595*5c51f124SMoriah Waterland quit(n); 596*5c51f124SMoriah Waterland if (strchr("yY", *ans) == NULL) 597*5c51f124SMoriah Waterland quit(3); 598*5c51f124SMoriah Waterland 599*5c51f124SMoriah Waterland /* 600*5c51f124SMoriah Waterland * It isn't a directory, so we'll just unlink 601*5c51f124SMoriah Waterland * it. 602*5c51f124SMoriah Waterland */ 603*5c51f124SMoriah Waterland if (unlink(basedir) == -1) { 604*5c51f124SMoriah Waterland progerr(gettext(ERR_NODELETE), 605*5c51f124SMoriah Waterland basedir); 606*5c51f124SMoriah Waterland quit(99); 607*5c51f124SMoriah Waterland } 608*5c51f124SMoriah Waterland 609*5c51f124SMoriah Waterland } else { 610*5c51f124SMoriah Waterland ptext(stderr, gettext(MSG_MUSTEXIST), basedir); 611*5c51f124SMoriah Waterland 612*5c51f124SMoriah Waterland if (n = ckyorn(ans, NULL, NULL, NULL, 613*5c51f124SMoriah Waterland gettext(MSG_YORNPRMPT))) 614*5c51f124SMoriah Waterland quit(n); 615*5c51f124SMoriah Waterland if (strchr("yY", *ans) == NULL) 616*5c51f124SMoriah Waterland quit(3); 617*5c51f124SMoriah Waterland } 618*5c51f124SMoriah Waterland } 619*5c51f124SMoriah Waterland 620*5c51f124SMoriah Waterland if (access(basedir, F_OK) == 0 || mkpath(basedir)) { 621*5c51f124SMoriah Waterland progerr(gettext(ERR_MKBASE), basedir); 622*5c51f124SMoriah Waterland quit(99); 623*5c51f124SMoriah Waterland } 624*5c51f124SMoriah Waterland } 625*5c51f124SMoriah Waterland } 626*5c51f124SMoriah Waterland 627*5c51f124SMoriah Waterland /* 628*5c51f124SMoriah Waterland * Create a client_basedir if it is appropriate. If all goes well, resulting 629*5c51f124SMoriah Waterland * in either a valid client_basedir or a valid lack thereof, it returns 1. 630*5c51f124SMoriah Waterland * If there is an irreconcileable conflict, it returns 0. 631*5c51f124SMoriah Waterland */ 632*5c51f124SMoriah Waterland static int 633*5c51f124SMoriah Waterland set_client_basedir(void) 634*5c51f124SMoriah Waterland { 635*5c51f124SMoriah Waterland if (install_root_exists) { 636*5c51f124SMoriah Waterland if (basedir_exists) 637*5c51f124SMoriah Waterland client_basedir = strdup(orig_basedir); 638*5c51f124SMoriah Waterland else 639*5c51f124SMoriah Waterland client_basedir = "/"; 640*5c51f124SMoriah Waterland client_basedir_exists = 1; 641*5c51f124SMoriah Waterland } 642*5c51f124SMoriah Waterland 643*5c51f124SMoriah Waterland /* 644*5c51f124SMoriah Waterland * In response to an agreement associated with bug report #1133956, 645*5c51f124SMoriah Waterland * CLIENT_BASEDIR will be defined in all cases where BASEDIR is 646*5c51f124SMoriah Waterland * defined until the on1094 release. For on1094 delete the else if 647*5c51f124SMoriah Waterland * and associated expressions below. -- JST (6/25/1993) 648*5c51f124SMoriah Waterland */ 649*5c51f124SMoriah Waterland else if (basedir_exists) { 650*5c51f124SMoriah Waterland client_basedir = strdup(basedir); 651*5c51f124SMoriah Waterland client_basedir_exists = 1; 652*5c51f124SMoriah Waterland } 653*5c51f124SMoriah Waterland 654*5c51f124SMoriah Waterland /* 655*5c51f124SMoriah Waterland * At this point we may or may not have a client_basedir defined. Now 656*5c51f124SMoriah Waterland * we need to check for one in the environment & make sure it syncs 657*5c51f124SMoriah Waterland * up with prior findings. If there's no other client_basedir defined, 658*5c51f124SMoriah Waterland * the environment defines it. 659*5c51f124SMoriah Waterland */ 660*5c51f124SMoriah Waterland if (env_cl_bdir && *env_cl_bdir) { 661*5c51f124SMoriah Waterland if (client_basedir_exists) { 662*5c51f124SMoriah Waterland /* If the two client basedirs mismatch, return fail */ 663*5c51f124SMoriah Waterland if (strcmp(client_basedir, env_cl_bdir)) { 664*5c51f124SMoriah Waterland ptext(stderr, gettext(ERR_CL_MIS), 665*5c51f124SMoriah Waterland client_basedir, env_cl_bdir); 666*5c51f124SMoriah Waterland return (0); 667*5c51f124SMoriah Waterland } 668*5c51f124SMoriah Waterland } else { 669*5c51f124SMoriah Waterland client_basedir = env_cl_bdir; 670*5c51f124SMoriah Waterland client_basedir_exists = 1; 671*5c51f124SMoriah Waterland } 672*5c51f124SMoriah Waterland } 673*5c51f124SMoriah Waterland 674*5c51f124SMoriah Waterland return (1); 675*5c51f124SMoriah Waterland } 676*5c51f124SMoriah Waterland 677*5c51f124SMoriah Waterland static char * 678*5c51f124SMoriah Waterland expand_path(char *path) 679*5c51f124SMoriah Waterland { 680*5c51f124SMoriah Waterland char path_buf[PATH_MAX]; 681*5c51f124SMoriah Waterland 682*5c51f124SMoriah Waterland if (!path || !*path) 683*5c51f124SMoriah Waterland return (path); 684*5c51f124SMoriah Waterland 685*5c51f124SMoriah Waterland (void) strlcpy(path_buf, path, sizeof (path_buf)); 686*5c51f124SMoriah Waterland mappath(getmapmode(), path_buf); 687*5c51f124SMoriah Waterland canonize(path_buf); 688*5c51f124SMoriah Waterland 689*5c51f124SMoriah Waterland return (qstrdup(path_buf)); 690*5c51f124SMoriah Waterland } 691*5c51f124SMoriah Waterland 692*5c51f124SMoriah Waterland char * 693*5c51f124SMoriah Waterland get_basedir(void) 694*5c51f124SMoriah Waterland { 695*5c51f124SMoriah Waterland return (basedir); 696*5c51f124SMoriah Waterland } 697*5c51f124SMoriah Waterland 698*5c51f124SMoriah Waterland char * 699*5c51f124SMoriah Waterland get_client_basedir(void) 700*5c51f124SMoriah Waterland { 701*5c51f124SMoriah Waterland return (client_basedir); 702*5c51f124SMoriah Waterland } 703*5c51f124SMoriah Waterland 704*5c51f124SMoriah Waterland /* 705*5c51f124SMoriah Waterland * This function returns the basedir that is appropriate for this package's 706*5c51f124SMoriah Waterland * pkginfo file. 707*5c51f124SMoriah Waterland */ 708*5c51f124SMoriah Waterland char * 709*5c51f124SMoriah Waterland get_info_basedir(void) 710*5c51f124SMoriah Waterland { 711*5c51f124SMoriah Waterland if (install_root_exists) 712*5c51f124SMoriah Waterland return (client_basedir); 713*5c51f124SMoriah Waterland else if (basedir_exists) 714*5c51f124SMoriah Waterland return (basedir); 715*5c51f124SMoriah Waterland else 716*5c51f124SMoriah Waterland return (NULL); 717*5c51f124SMoriah Waterland } 718*5c51f124SMoriah Waterland 719*5c51f124SMoriah Waterland int 720*5c51f124SMoriah Waterland is_an_inst_root(void) 721*5c51f124SMoriah Waterland { 722*5c51f124SMoriah Waterland return (install_root_exists); 723*5c51f124SMoriah Waterland } 724*5c51f124SMoriah Waterland 725*5c51f124SMoriah Waterland int 726*5c51f124SMoriah Waterland is_a_basedir(void) 727*5c51f124SMoriah Waterland { 728*5c51f124SMoriah Waterland return (basedir_exists); 729*5c51f124SMoriah Waterland } 730*5c51f124SMoriah Waterland 731*5c51f124SMoriah Waterland int 732*5c51f124SMoriah Waterland is_relocatable(void) 733*5c51f124SMoriah Waterland { 734*5c51f124SMoriah Waterland return (relocatable); 735*5c51f124SMoriah Waterland } 736*5c51f124SMoriah Waterland 737*5c51f124SMoriah Waterland int 738*5c51f124SMoriah Waterland is_a_cl_basedir(void) 739*5c51f124SMoriah Waterland { 740*5c51f124SMoriah Waterland return (client_basedir_exists); 741*5c51f124SMoriah Waterland } 742*5c51f124SMoriah Waterland 743*5c51f124SMoriah Waterland /* 744*5c51f124SMoriah Waterland * Since calls to putparam() become valid long after much of the above 745*5c51f124SMoriah Waterland * code has run, this routine allows the insertion of these key 746*5c51f124SMoriah Waterland * environment variables without passing a bunch of pointers. 747*5c51f124SMoriah Waterland */ 748*5c51f124SMoriah Waterland void 749*5c51f124SMoriah Waterland put_path_params(void) 750*5c51f124SMoriah Waterland { 751*5c51f124SMoriah Waterland if (install_root_exists) 752*5c51f124SMoriah Waterland putparam("PKG_INSTALL_ROOT", get_inst_root()); 753*5c51f124SMoriah Waterland 754*5c51f124SMoriah Waterland if (basedir_exists) 755*5c51f124SMoriah Waterland putparam("BASEDIR", basedir); 756*5c51f124SMoriah Waterland 757*5c51f124SMoriah Waterland if (client_basedir_exists) 758*5c51f124SMoriah Waterland putparam("CLIENT_BASEDIR", client_basedir); 759*5c51f124SMoriah Waterland } 760*5c51f124SMoriah Waterland 761*5c51f124SMoriah Waterland /* 762*5c51f124SMoriah Waterland * This fills three pointers and a buffer which contains the longest 763*5c51f124SMoriah Waterland * possible path (with install_root and basedir prepended. The pointers 764*5c51f124SMoriah Waterland * are to the subpaths within the string. This was added so that the 765*5c51f124SMoriah Waterland * eptlist could be produced with all relevant paths defined without 766*5c51f124SMoriah Waterland * repeated calls and string scans. For example, given a path of 767*5c51f124SMoriah Waterland * haberdasher/crute we may return 768*5c51f124SMoriah Waterland * 769*5c51f124SMoriah Waterland * server_ptr -----> /export/root/client1/opt/SUNWhab/haberdasher/crute 770*5c51f124SMoriah Waterland * | | 771*5c51f124SMoriah Waterland * client_ptr --------------------------- | 772*5c51f124SMoriah Waterland * map_ptr ------------------------------------------- 773*5c51f124SMoriah Waterland * 774*5c51f124SMoriah Waterland * We construct the new path based upon the established environment 775*5c51f124SMoriah Waterland * and the type of path that was passed. Here are the possibilities: 776*5c51f124SMoriah Waterland * 777*5c51f124SMoriah Waterland * | | relative path | absolute path | 778*5c51f124SMoriah Waterland * | --------------------------------|---------------|---------------| 779*5c51f124SMoriah Waterland * | is_an_inst_root | 1 | 2 | 780*5c51f124SMoriah Waterland * V ! an_inst_root && is_a_basedir | 1 | 3 | 781*5c51f124SMoriah Waterland * ! an_inst_root && ! a_basedir | X | 3 | 782*5c51f124SMoriah Waterland * 783*5c51f124SMoriah Waterland * METHOD 784*5c51f124SMoriah Waterland * 1. Prepend the basedir to the path (the basedir is guaranteed to exist 785*5c51f124SMoriah Waterland * whenever there's an install_root). 786*5c51f124SMoriah Waterland * 787*5c51f124SMoriah Waterland * 2. Prepend the install_root (not the basedir) to the path 788*5c51f124SMoriah Waterland * 789*5c51f124SMoriah Waterland * 3. Return the path as unchanged. 790*5c51f124SMoriah Waterland * 791*5c51f124SMoriah Waterland * X. THIS CAN'T HAPPEN 792*5c51f124SMoriah Waterland */ 793*5c51f124SMoriah Waterland int 794*5c51f124SMoriah Waterland eval_path(char **server_ptr, char **client_ptr, char **map_ptr, char *path) 795*5c51f124SMoriah Waterland { 796*5c51f124SMoriah Waterland static int client_offset; 797*5c51f124SMoriah Waterland static int offsets_valid, retcode; 798*5c51f124SMoriah Waterland int path_size; 799*5c51f124SMoriah Waterland 800*5c51f124SMoriah Waterland if (!offsets_valid) { 801*5c51f124SMoriah Waterland /* 802*5c51f124SMoriah Waterland * This is the offset from the beginning of the evaluated 803*5c51f124SMoriah Waterland * path to the start of the relative path. Note that we 804*5c51f124SMoriah Waterland * are accounting for the '/' inserted between the 805*5c51f124SMoriah Waterland * basedir and the path with the '+ 1'. If there is a 806*5c51f124SMoriah Waterland * relative path, then there is always a basedir. The 807*5c51f124SMoriah Waterland * only way this will come up '0' is if this is an 808*5c51f124SMoriah Waterland * absolute package. 809*5c51f124SMoriah Waterland */ 810*5c51f124SMoriah Waterland orig_offset_rel = (is_a_basedir()) ? (strlen(basedir) + 811*5c51f124SMoriah Waterland base_sepr) : 0; 812*5c51f124SMoriah Waterland 813*5c51f124SMoriah Waterland /* 814*5c51f124SMoriah Waterland * This is the position of the client-relative path 815*5c51f124SMoriah Waterland * in that it points to the '/' beginning the base 816*5c51f124SMoriah Waterland * directory or the absolute path. Once the basedir has 817*5c51f124SMoriah Waterland * been afixed, the path is absolute. For that reason, 818*5c51f124SMoriah Waterland * the client path is the same thing as the original path 819*5c51f124SMoriah Waterland * if it were absolute. 820*5c51f124SMoriah Waterland */ 821*5c51f124SMoriah Waterland client_offset = (is_an_inst_root()) ? install_root_len : 0; 822*5c51f124SMoriah Waterland 823*5c51f124SMoriah Waterland offsets_valid = 1; 824*5c51f124SMoriah Waterland } 825*5c51f124SMoriah Waterland 826*5c51f124SMoriah Waterland /* 827*5c51f124SMoriah Waterland * If we've evaluated the base directory and come up trumps, 828*5c51f124SMoriah Waterland * then we can procede with this operation, otherwise, the 829*5c51f124SMoriah Waterland * available data is too ambiguous to resolve the issue. 830*5c51f124SMoriah Waterland */ 831*5c51f124SMoriah Waterland if (eval_valid) { 832*5c51f124SMoriah Waterland if (RELATIVE(path)) { 833*5c51f124SMoriah Waterland if (relocatable) { 834*5c51f124SMoriah Waterland /* 835*5c51f124SMoriah Waterland * Figure out how long our buffer will 836*5c51f124SMoriah Waterland * have to be. 837*5c51f124SMoriah Waterland */ 838*5c51f124SMoriah Waterland path_size = orig_offset_rel + strlen(path); 839*5c51f124SMoriah Waterland 840*5c51f124SMoriah Waterland (*server_ptr) = pathalloc(path_size); 841*5c51f124SMoriah Waterland 842*5c51f124SMoriah Waterland *client_ptr = *server_ptr + client_offset; 843*5c51f124SMoriah Waterland 844*5c51f124SMoriah Waterland if (map_ptr) 845*5c51f124SMoriah Waterland *map_ptr = *server_ptr + 846*5c51f124SMoriah Waterland orig_offset_rel; 847*5c51f124SMoriah Waterland 848*5c51f124SMoriah Waterland /* LINTED warning: variable format specifier */ 849*5c51f124SMoriah Waterland (void) snprintf(*server_ptr, path_size+1, 850*5c51f124SMoriah Waterland rel_fmt[base_sepr], basedir, path); 851*5c51f124SMoriah Waterland } else { 852*5c51f124SMoriah Waterland ptext(stderr, gettext(ERR_RELINABS), path); 853*5c51f124SMoriah Waterland retcode = 0; 854*5c51f124SMoriah Waterland } 855*5c51f124SMoriah Waterland } else { /* NOT RELATIVE */ 856*5c51f124SMoriah Waterland *server_ptr = fixpath_dup(path); 857*5c51f124SMoriah Waterland 858*5c51f124SMoriah Waterland if ((*client_ptr = *server_ptr + client_offset) == NULL) 859*5c51f124SMoriah Waterland *client_ptr = "/"; 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland if (map_ptr) 862*5c51f124SMoriah Waterland *map_ptr = *client_ptr; 863*5c51f124SMoriah Waterland } 864*5c51f124SMoriah Waterland 865*5c51f124SMoriah Waterland retcode = 1; 866*5c51f124SMoriah Waterland } else { 867*5c51f124SMoriah Waterland ptext(stderr, gettext(ERR_AMBDIRS)); 868*5c51f124SMoriah Waterland retcode = 0; 869*5c51f124SMoriah Waterland } 870*5c51f124SMoriah Waterland 871*5c51f124SMoriah Waterland return (retcode); 872*5c51f124SMoriah Waterland } 873*5c51f124SMoriah Waterland 874*5c51f124SMoriah Waterland void 875*5c51f124SMoriah Waterland export_client_env(char *root_path) 876*5c51f124SMoriah Waterland { 877*5c51f124SMoriah Waterland char *inst_release_path; 878*5c51f124SMoriah Waterland char *key; 879*5c51f124SMoriah Waterland char *value; 880*5c51f124SMoriah Waterland FILE *inst_fp; 881*5c51f124SMoriah Waterland size_t len; 882*5c51f124SMoriah Waterland 883*5c51f124SMoriah Waterland /* 884*5c51f124SMoriah Waterland * Put the variables found in a clients INST_RELEASE file into the 885*5c51f124SMoriah Waterland * package environment so procedure scripts can know what 886*5c51f124SMoriah Waterland * release/version/revision a client is running. Also this function 887*5c51f124SMoriah Waterland * doesn't return state since the INST_RELEASE file may not exist in 888*5c51f124SMoriah Waterland * some package installation environments 889*5c51f124SMoriah Waterland */ 890*5c51f124SMoriah Waterland 891*5c51f124SMoriah Waterland len = strlen(root_path) + strlen(INST_RELEASE) + 2; 892*5c51f124SMoriah Waterland 893*5c51f124SMoriah Waterland inst_release_path = (char *)malloc(len); 894*5c51f124SMoriah Waterland 895*5c51f124SMoriah Waterland key = (char *)malloc(PATH_MAX); 896*5c51f124SMoriah Waterland 897*5c51f124SMoriah Waterland (void) snprintf(inst_release_path, len, "%s/%s", root_path, 898*5c51f124SMoriah Waterland INST_RELEASE); 899*5c51f124SMoriah Waterland 900*5c51f124SMoriah Waterland if ((inst_fp = fopen(inst_release_path, "r")) != NULL) { 901*5c51f124SMoriah Waterland while (value = fpkgparam(inst_fp, key)) { 902*5c51f124SMoriah Waterland if (strcmp(key, "OS") == 0) { 903*5c51f124SMoriah Waterland putparam("PKG_CLIENT_OS", value); 904*5c51f124SMoriah Waterland } else if (strcmp(key, "VERSION") == 0) { 905*5c51f124SMoriah Waterland putparam("PKG_CLIENT_VERSION", value); 906*5c51f124SMoriah Waterland } else if (strcmp(key, "REV") == 0) { 907*5c51f124SMoriah Waterland putparam("PKG_CLIENT_REVISION", value); 908*5c51f124SMoriah Waterland } 909*5c51f124SMoriah Waterland *key = '\0'; 910*5c51f124SMoriah Waterland } 911*5c51f124SMoriah Waterland (void) fclose(inst_fp); 912*5c51f124SMoriah Waterland } 913*5c51f124SMoriah Waterland free(inst_release_path); 914*5c51f124SMoriah Waterland free(key); 915*5c51f124SMoriah Waterland } 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland /* 918*5c51f124SMoriah Waterland * Increment variable indicating the installation is from a partially spooled 919*5c51f124SMoriah Waterland * package. 920*5c51f124SMoriah Waterland */ 921*5c51f124SMoriah Waterland void 922*5c51f124SMoriah Waterland set_partial_inst(void) 923*5c51f124SMoriah Waterland { 924*5c51f124SMoriah Waterland partial_inst++; 925*5c51f124SMoriah Waterland } 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland /* 928*5c51f124SMoriah Waterland * Return variable indicating that the installation is from a partially spooled 929*5c51f124SMoriah Waterland * package. 930*5c51f124SMoriah Waterland * Returns: !0 for true 931*5c51f124SMoriah Waterland * 0 for false 932*5c51f124SMoriah Waterland */ 933*5c51f124SMoriah Waterland int 934*5c51f124SMoriah Waterland is_partial_inst(void) 935*5c51f124SMoriah Waterland { 936*5c51f124SMoriah Waterland return (partial_inst); 937*5c51f124SMoriah Waterland } 938*5c51f124SMoriah Waterland 939*5c51f124SMoriah Waterland /* 940*5c51f124SMoriah Waterland * Increment variable indicating that only the depend and pkginfo DB's are to be 941*5c51f124SMoriah Waterland * updated 942*5c51f124SMoriah Waterland */ 943*5c51f124SMoriah Waterland 944*5c51f124SMoriah Waterland void 945*5c51f124SMoriah Waterland set_depend_pkginfo_DB(boolean_t a_setting) 946*5c51f124SMoriah Waterland { 947*5c51f124SMoriah Waterland depend_pkginfo_DB = a_setting; 948*5c51f124SMoriah Waterland } 949*5c51f124SMoriah Waterland 950*5c51f124SMoriah Waterland /* 951*5c51f124SMoriah Waterland * Return variable indicating that the installation only updates the depend 952*5c51f124SMoriah Waterland * and pkginfo DB's. 953*5c51f124SMoriah Waterland * Returns: !0 for true 954*5c51f124SMoriah Waterland * 0 for false 955*5c51f124SMoriah Waterland */ 956*5c51f124SMoriah Waterland 957*5c51f124SMoriah Waterland boolean_t 958*5c51f124SMoriah Waterland is_depend_pkginfo_DB(void) 959*5c51f124SMoriah Waterland { 960*5c51f124SMoriah Waterland return (depend_pkginfo_DB); 961*5c51f124SMoriah Waterland } 962*5c51f124SMoriah Waterland 963*5c51f124SMoriah Waterland /* 964*5c51f124SMoriah Waterland * Increment variable indicating that packages should not be spooled in 965*5c51f124SMoriah Waterland * var/sadm/pkg/<pkgabbrev>/save/pspool/ 966*5c51f124SMoriah Waterland */ 967*5c51f124SMoriah Waterland void 968*5c51f124SMoriah Waterland disable_spool_create(void) 969*5c51f124SMoriah Waterland { 970*5c51f124SMoriah Waterland partial_spool_create++; 971*5c51f124SMoriah Waterland } 972*5c51f124SMoriah Waterland 973*5c51f124SMoriah Waterland /* 974*5c51f124SMoriah Waterland * Return variable indicating whether or not the partial spool directory 975*5c51f124SMoriah Waterland * should be created. 976*5c51f124SMoriah Waterland * Returns: 1 for true 977*5c51f124SMoriah Waterland * 0 for false 978*5c51f124SMoriah Waterland */ 979*5c51f124SMoriah Waterland int 980*5c51f124SMoriah Waterland is_spool_create(void) 981*5c51f124SMoriah Waterland { 982*5c51f124SMoriah Waterland return (partial_spool_create); 983*5c51f124SMoriah Waterland } 984