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 /* 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 <locale.h> 34*5c51f124SMoriah Waterland #include <libintl.h> 35*5c51f124SMoriah Waterland #include <dirent.h> 36*5c51f124SMoriah Waterland #include <pkgstrct.h> 37*5c51f124SMoriah Waterland #include <pkgdev.h> 38*5c51f124SMoriah Waterland #include <pkglocs.h> 39*5c51f124SMoriah Waterland #include <archives.h> 40*5c51f124SMoriah Waterland #include <errno.h> 41*5c51f124SMoriah Waterland #include <fcntl.h> 42*5c51f124SMoriah Waterland #include <sys/stat.h> 43*5c51f124SMoriah Waterland #include <sys/param.h> 44*5c51f124SMoriah Waterland #include <stdlib.h> 45*5c51f124SMoriah Waterland #include <unistd.h> 46*5c51f124SMoriah Waterland #include <assert.h> 47*5c51f124SMoriah Waterland #include <wait.h> 48*5c51f124SMoriah Waterland 49*5c51f124SMoriah Waterland /* 50*5c51f124SMoriah Waterland * libinstzones includes 51*5c51f124SMoriah Waterland */ 52*5c51f124SMoriah Waterland 53*5c51f124SMoriah Waterland #include <instzones_api.h> 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland /* 56*5c51f124SMoriah Waterland * consolidation pkg command library includes 57*5c51f124SMoriah Waterland */ 58*5c51f124SMoriah Waterland 59*5c51f124SMoriah Waterland #include <pkglib.h> 60*5c51f124SMoriah Waterland #include <pkgweb.h> 61*5c51f124SMoriah Waterland 62*5c51f124SMoriah Waterland /* 63*5c51f124SMoriah Waterland * local pkg command library includes 64*5c51f124SMoriah Waterland */ 65*5c51f124SMoriah Waterland 66*5c51f124SMoriah Waterland #include <install.h> 67*5c51f124SMoriah Waterland #include <libinst.h> 68*5c51f124SMoriah Waterland #include <libadm.h> 69*5c51f124SMoriah Waterland #include <dryrun.h> 70*5c51f124SMoriah Waterland #include <messages.h> 71*5c51f124SMoriah Waterland 72*5c51f124SMoriah Waterland /* 73*5c51f124SMoriah Waterland * pkginstall local includes 74*5c51f124SMoriah Waterland */ 75*5c51f124SMoriah Waterland 76*5c51f124SMoriah Waterland #include "pkginstall.h" 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland extern int pkgverbose; 79*5c51f124SMoriah Waterland extern fsblkcnt_t pkgmap_blks; /* main.c */ 80*5c51f124SMoriah Waterland 81*5c51f124SMoriah Waterland extern struct pkgdev pkgdev; 82*5c51f124SMoriah Waterland 83*5c51f124SMoriah Waterland extern char tmpdir[]; 84*5c51f124SMoriah Waterland extern char pkgbin[]; 85*5c51f124SMoriah Waterland extern char instdir[]; 86*5c51f124SMoriah Waterland extern char saveSpoolInstallDir[]; 87*5c51f124SMoriah Waterland extern char *pkginst; 88*5c51f124SMoriah Waterland 89*5c51f124SMoriah Waterland extern int dbchg; 90*5c51f124SMoriah Waterland extern int nosetuid; 91*5c51f124SMoriah Waterland extern int nocnflct; 92*5c51f124SMoriah Waterland extern int warnflag; 93*5c51f124SMoriah Waterland 94*5c51f124SMoriah Waterland #define DMRG_DONE -1 95*5c51f124SMoriah Waterland 96*5c51f124SMoriah Waterland #define ck_efile(s, p) \ 97*5c51f124SMoriah Waterland ((p->cinfo.modtime >= 0) && \ 98*5c51f124SMoriah Waterland p->ainfo.local && \ 99*5c51f124SMoriah Waterland cverify(0, &p->ftype, s, &p->cinfo, 1)) 100*5c51f124SMoriah Waterland 101*5c51f124SMoriah Waterland static int eocflag; 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland /* 104*5c51f124SMoriah Waterland * The variable below indicates that fix_attributes() will be inadequate 105*5c51f124SMoriah Waterland * because a replacement was permitted. 106*5c51f124SMoriah Waterland */ 107*5c51f124SMoriah Waterland static int repl_permitted = 0; 108*5c51f124SMoriah Waterland 109*5c51f124SMoriah Waterland static int domerg(struct cfextra **extlist, int part, int nparts, 110*5c51f124SMoriah Waterland int myclass, char **srcp, char **dstp, 111*5c51f124SMoriah Waterland char **r_updated, char **r_skipped, 112*5c51f124SMoriah Waterland char **r_anyPathLocal); 113*5c51f124SMoriah Waterland static void endofclass(struct cfextra **extlist, int myclass, 114*5c51f124SMoriah Waterland int ckflag, VFP_T **a_cfVfp, VFP_T **a_cfTmpVfp); 115*5c51f124SMoriah Waterland static int fix_attributes(struct cfextra **, int); 116*5c51f124SMoriah Waterland static int dir_is_populated(char *dirpath); 117*5c51f124SMoriah Waterland static boolean_t absolutepath(char *path); 118*5c51f124SMoriah Waterland static boolean_t parametricpath(char *path, char **relocpath); 119*5c51f124SMoriah Waterland 120*5c51f124SMoriah Waterland /* Used to keep track of the entries in extlist that are regular files. */ 121*5c51f124SMoriah Waterland struct reg_files { 122*5c51f124SMoriah Waterland struct reg_files *next; 123*5c51f124SMoriah Waterland int val; 124*5c51f124SMoriah Waterland }; 125*5c51f124SMoriah Waterland static struct reg_files *regfiles_head = NULL; 126*5c51f124SMoriah Waterland 127*5c51f124SMoriah Waterland /* 128*5c51f124SMoriah Waterland * This is the function that actually installs one volume (usually that's 129*5c51f124SMoriah Waterland * all there is). Upon entry, the extlist is entirely correct: 130*5c51f124SMoriah Waterland * 131*5c51f124SMoriah Waterland * 1. It contains only those files which are to be installed 132*5c51f124SMoriah Waterland * from all volumes. 133*5c51f124SMoriah Waterland * 2. The mode bits in the ainfo structure for each file are set 134*5c51f124SMoriah Waterland * correctly in accordance with administrative defaults. 135*5c51f124SMoriah Waterland * 3. mstat.setuid/setgid reflect what the status *was* before 136*5c51f124SMoriah Waterland * pkgdbmerg() processed compliance. 137*5c51f124SMoriah Waterland */ 138*5c51f124SMoriah Waterland void 139*5c51f124SMoriah Waterland instvol(struct cfextra **extlist, char *srcinst, int part, 140*5c51f124SMoriah Waterland int nparts, VFP_T **a_cfVfp, VFP_T **a_cfTmpVfp, 141*5c51f124SMoriah Waterland char **r_updated, char **r_skipped, 142*5c51f124SMoriah Waterland char *a_zoneName) 143*5c51f124SMoriah Waterland { 144*5c51f124SMoriah Waterland FILE *listfp; 145*5c51f124SMoriah Waterland char *updated = (char *)NULL; 146*5c51f124SMoriah Waterland char *skipped = (char *)NULL; 147*5c51f124SMoriah Waterland char *anyPathLocal = (char *)NULL; 148*5c51f124SMoriah Waterland char *relocpath = (char *)NULL; 149*5c51f124SMoriah Waterland char *dstp; 150*5c51f124SMoriah Waterland char *listfile; 151*5c51f124SMoriah Waterland char *srcp; 152*5c51f124SMoriah Waterland char *pspool_loc; 153*5c51f124SMoriah Waterland char scrpt_dst[PATH_MAX]; 154*5c51f124SMoriah Waterland int count; 155*5c51f124SMoriah Waterland int entryidx; /* array of current package objects */ 156*5c51f124SMoriah Waterland int n; 157*5c51f124SMoriah Waterland int nc = 0; 158*5c51f124SMoriah Waterland int pass; /* pass count through the for loop. */ 159*5c51f124SMoriah Waterland int tcount; 160*5c51f124SMoriah Waterland struct cfent *ept; 161*5c51f124SMoriah Waterland struct cfextra *ext; 162*5c51f124SMoriah Waterland struct mergstat *mstat; 163*5c51f124SMoriah Waterland struct reg_files *rfp = NULL; 164*5c51f124SMoriah Waterland 165*5c51f124SMoriah Waterland /* 166*5c51f124SMoriah Waterland * r_updated and r_skipped are optional parameters that can be passed in 167*5c51f124SMoriah Waterland * by the caller if the caller wants to know if any objects are either 168*5c51f124SMoriah Waterland * updated or skipped. Do not initialize either r_updated or r_skipped; 169*5c51f124SMoriah Waterland * the call to instvol could be cumulative and any previous update or 170*5c51f124SMoriah Waterland * skipped indication must not be disturbed - these flags are only set, 171*5c51f124SMoriah Waterland * they must never be reset. These flags are "char *" pointers so that 172*5c51f124SMoriah Waterland * the object that was skipped or updated can be displayed in debugging 173*5c51f124SMoriah Waterland * output. 174*5c51f124SMoriah Waterland */ 175*5c51f124SMoriah Waterland 176*5c51f124SMoriah Waterland if (part == 1) { 177*5c51f124SMoriah Waterland pkgvolume(&pkgdev, srcinst, part, nparts); 178*5c51f124SMoriah Waterland } 179*5c51f124SMoriah Waterland 180*5c51f124SMoriah Waterland tcount = 0; 181*5c51f124SMoriah Waterland nc = cl_getn(); 182*5c51f124SMoriah Waterland 183*5c51f124SMoriah Waterland /* 184*5c51f124SMoriah Waterland * For each class in this volume, install those files. 185*5c51f124SMoriah Waterland * 186*5c51f124SMoriah Waterland * NOTE : This loop index may be decremented by code below forcing a 187*5c51f124SMoriah Waterland * second trip through for the same class. This happens only when a 188*5c51f124SMoriah Waterland * class is split between an archive and the tree. Examples would be 189*5c51f124SMoriah Waterland * old WOS packages and the occasional class containing dynamic 190*5c51f124SMoriah Waterland * libraries which require special treatment. 191*5c51f124SMoriah Waterland */ 192*5c51f124SMoriah Waterland 193*5c51f124SMoriah Waterland if (is_depend_pkginfo_DB() == B_FALSE) { 194*5c51f124SMoriah Waterland int classidx; /* the current class */ 195*5c51f124SMoriah Waterland 196*5c51f124SMoriah Waterland for (classidx = 0; classidx < nc; classidx++) { 197*5c51f124SMoriah Waterland int pass_relative = 0; 198*5c51f124SMoriah Waterland int rel_init = 0; 199*5c51f124SMoriah Waterland 200*5c51f124SMoriah Waterland eocflag = count = pass = 0; 201*5c51f124SMoriah Waterland listfp = (FILE *)0; 202*5c51f124SMoriah Waterland listfile = NULL; 203*5c51f124SMoriah Waterland 204*5c51f124SMoriah Waterland /* Now what do we pass to the class action script */ 205*5c51f124SMoriah Waterland 206*5c51f124SMoriah Waterland if (cl_pthrel(classidx) == REL_2_CAS) { 207*5c51f124SMoriah Waterland pass_relative = 1; 208*5c51f124SMoriah Waterland } 209*5c51f124SMoriah Waterland 210*5c51f124SMoriah Waterland for (;;) { 211*5c51f124SMoriah Waterland if (!tcount++) { 212*5c51f124SMoriah Waterland /* first file to install */ 213*5c51f124SMoriah Waterland if (a_zoneName == (char *)NULL) { 214*5c51f124SMoriah Waterland echo(MSG_INS_N_N, part, nparts); 215*5c51f124SMoriah Waterland } else { 216*5c51f124SMoriah Waterland echo(MSG_INS_N_N_LZ, part, nparts, 217*5c51f124SMoriah Waterland a_zoneName); 218*5c51f124SMoriah Waterland } 219*5c51f124SMoriah Waterland } 220*5c51f124SMoriah Waterland 221*5c51f124SMoriah Waterland /* 222*5c51f124SMoriah Waterland * If there's an install class action script and no 223*5c51f124SMoriah Waterland * list file has been created yet, create that file 224*5c51f124SMoriah Waterland * and provide the pointer in listfp. 225*5c51f124SMoriah Waterland */ 226*5c51f124SMoriah Waterland if (cl_iscript(classidx) && !listfp) { 227*5c51f124SMoriah Waterland /* create list file */ 228*5c51f124SMoriah Waterland putparam("TMPDIR", tmpdir); 229*5c51f124SMoriah Waterland listfile = tempnam(tmpdir, "list"); 230*5c51f124SMoriah Waterland if ((listfp = fopen(listfile, "w")) == NULL) { 231*5c51f124SMoriah Waterland progerr(ERR_WTMPFILE, listfile); 232*5c51f124SMoriah Waterland quit(99); 233*5c51f124SMoriah Waterland } 234*5c51f124SMoriah Waterland } 235*5c51f124SMoriah Waterland 236*5c51f124SMoriah Waterland /* 237*5c51f124SMoriah Waterland * The following function goes through the package 238*5c51f124SMoriah Waterland * object list returning the array index of the next 239*5c51f124SMoriah Waterland * regular file. If it encounters a directory, 240*5c51f124SMoriah Waterland * symlink, named pipe or device, it just creates it. 241*5c51f124SMoriah Waterland */ 242*5c51f124SMoriah Waterland 243*5c51f124SMoriah Waterland entryidx = domerg(extlist, (pass++ ? 0 : part), nparts, 244*5c51f124SMoriah Waterland classidx, &srcp, &dstp, &updated, &skipped, 245*5c51f124SMoriah Waterland &anyPathLocal); 246*5c51f124SMoriah Waterland 247*5c51f124SMoriah Waterland /* Evaluate the return code */ 248*5c51f124SMoriah Waterland if (entryidx == DMRG_DONE) { 249*5c51f124SMoriah Waterland /* 250*5c51f124SMoriah Waterland * Set ept to the first entry in extlist 251*5c51f124SMoriah Waterland * which is guaranteed to exist so 252*5c51f124SMoriah Waterland * later checks against ept->ftype are 253*5c51f124SMoriah Waterland * not compared to NULL. 254*5c51f124SMoriah Waterland */ 255*5c51f124SMoriah Waterland ext = extlist[0]; 256*5c51f124SMoriah Waterland ept = &(ext->cf_ent); 257*5c51f124SMoriah Waterland break; /* no more entries to process */ 258*5c51f124SMoriah Waterland } 259*5c51f124SMoriah Waterland 260*5c51f124SMoriah Waterland ext = extlist[entryidx]; 261*5c51f124SMoriah Waterland ept = &(ext->cf_ent); 262*5c51f124SMoriah Waterland mstat = &(ext->mstat); 263*5c51f124SMoriah Waterland 264*5c51f124SMoriah Waterland /* 265*5c51f124SMoriah Waterland * If not installing from a partially spooled package 266*5c51f124SMoriah Waterland * (the "save/pspool" area), and the file contents can 267*5c51f124SMoriah Waterland * be changed (type is 'e' or 'v'), and the class is not 268*5c51f124SMoriah Waterland * "none": copy the file from the package (in pristine 269*5c51f124SMoriah Waterland * state with no actions performed) into the appropriate 270*5c51f124SMoriah Waterland * location in the packages destination "save/pspool" 271*5c51f124SMoriah Waterland * area. 272*5c51f124SMoriah Waterland */ 273*5c51f124SMoriah Waterland 274*5c51f124SMoriah Waterland if ((!is_partial_inst()) && 275*5c51f124SMoriah Waterland ((ept->ftype == 'e') || (ept->ftype == 'v')) && 276*5c51f124SMoriah Waterland (strcmp(ept->pkg_class, "none") != 0)) { 277*5c51f124SMoriah Waterland 278*5c51f124SMoriah Waterland if (absolutepath(ext->map_path) == B_TRUE && 279*5c51f124SMoriah Waterland parametricpath(ext->cf_ent.ainfo.local, 280*5c51f124SMoriah Waterland &relocpath) == B_FALSE) { 281*5c51f124SMoriah Waterland pspool_loc = ROOT; 282*5c51f124SMoriah Waterland } else { 283*5c51f124SMoriah Waterland pspool_loc = RELOC; 284*5c51f124SMoriah Waterland } 285*5c51f124SMoriah Waterland 286*5c51f124SMoriah Waterland n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 287*5c51f124SMoriah Waterland saveSpoolInstallDir, pspool_loc, 288*5c51f124SMoriah Waterland relocpath ? relocpath : ext->map_path); 289*5c51f124SMoriah Waterland 290*5c51f124SMoriah Waterland if (n >= PATH_MAX) { 291*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, 292*5c51f124SMoriah Waterland saveSpoolInstallDir, 293*5c51f124SMoriah Waterland ext->map_path); 294*5c51f124SMoriah Waterland quit(99); 295*5c51f124SMoriah Waterland } 296*5c51f124SMoriah Waterland 297*5c51f124SMoriah Waterland /* copy, preserve source file mode */ 298*5c51f124SMoriah Waterland 299*5c51f124SMoriah Waterland if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) { 300*5c51f124SMoriah Waterland warnflag++; 301*5c51f124SMoriah Waterland } 302*5c51f124SMoriah Waterland } 303*5c51f124SMoriah Waterland 304*5c51f124SMoriah Waterland /* 305*5c51f124SMoriah Waterland * If this isn't writeable anyway, it's not going 306*5c51f124SMoriah Waterland * into the list file. Only count it if it's going 307*5c51f124SMoriah Waterland * into the list file. 308*5c51f124SMoriah Waterland */ 309*5c51f124SMoriah Waterland if (is_fs_writeable(ext->cf_ent.path, 310*5c51f124SMoriah Waterland &(ext->fsys_value))) 311*5c51f124SMoriah Waterland count++; 312*5c51f124SMoriah Waterland 313*5c51f124SMoriah Waterland pkgvolume(&pkgdev, srcinst, part, nparts); 314*5c51f124SMoriah Waterland 315*5c51f124SMoriah Waterland /* 316*5c51f124SMoriah Waterland * If source verification is OK for this class, make 317*5c51f124SMoriah Waterland * sure the source we're passing to the class action 318*5c51f124SMoriah Waterland * script is useable. 319*5c51f124SMoriah Waterland */ 320*5c51f124SMoriah Waterland if (cl_svfy(classidx) != NOVERIFY) { 321*5c51f124SMoriah Waterland if (cl_iscript(classidx) || 322*5c51f124SMoriah Waterland ((ept->ftype == 'e') || 323*5c51f124SMoriah Waterland (ept->ftype == 'n'))) { 324*5c51f124SMoriah Waterland if (ck_efile(srcp, ept)) { 325*5c51f124SMoriah Waterland progerr(ERR_CORRUPT, 326*5c51f124SMoriah Waterland srcp); 327*5c51f124SMoriah Waterland logerr(getErrbufAddr()); 328*5c51f124SMoriah Waterland warnflag++; 329*5c51f124SMoriah Waterland continue; 330*5c51f124SMoriah Waterland } 331*5c51f124SMoriah Waterland } 332*5c51f124SMoriah Waterland } 333*5c51f124SMoriah Waterland 334*5c51f124SMoriah Waterland /* 335*5c51f124SMoriah Waterland * If there's a class action script for this class, 336*5c51f124SMoriah Waterland * just collect names in a temporary file 337*5c51f124SMoriah Waterland * that will be used as the stdin when the 338*5c51f124SMoriah Waterland * class action script is invoked. 339*5c51f124SMoriah Waterland */ 340*5c51f124SMoriah Waterland 341*5c51f124SMoriah Waterland if ((cl_iscript(classidx)) && 342*5c51f124SMoriah Waterland ((is_fs_writeable(ept->path, 343*5c51f124SMoriah Waterland &(ext->fsys_value))))) { 344*5c51f124SMoriah Waterland if (pass_relative) { 345*5c51f124SMoriah Waterland if (!rel_init) { 346*5c51f124SMoriah Waterland (void) fputs(instdir, listfp); 347*5c51f124SMoriah Waterland (void) putc('\n', listfp); 348*5c51f124SMoriah Waterland rel_init++; 349*5c51f124SMoriah Waterland } 350*5c51f124SMoriah Waterland (void) fputs(ext->map_path, listfp); 351*5c51f124SMoriah Waterland (void) putc('\n', listfp); 352*5c51f124SMoriah Waterland } else { 353*5c51f124SMoriah Waterland (void) fputs(srcp ? 354*5c51f124SMoriah Waterland srcp : "/dev/null", listfp); 355*5c51f124SMoriah Waterland (void) putc(' ', listfp); 356*5c51f124SMoriah Waterland (void) fputs(dstp, listfp); 357*5c51f124SMoriah Waterland (void) putc('\n', listfp); 358*5c51f124SMoriah Waterland } 359*5c51f124SMoriah Waterland /* 360*5c51f124SMoriah Waterland * Note which entries in extlist are regular 361*5c51f124SMoriah Waterland * files to be installed via the class action 362*5c51f124SMoriah Waterland * script. 363*5c51f124SMoriah Waterland */ 364*5c51f124SMoriah Waterland if (regfiles_head == NULL) { 365*5c51f124SMoriah Waterland assert(rfp == NULL); 366*5c51f124SMoriah Waterland regfiles_head = 367*5c51f124SMoriah Waterland malloc(sizeof (struct reg_files)); 368*5c51f124SMoriah Waterland if (regfiles_head == NULL) { 369*5c51f124SMoriah Waterland progerr(ERR_MEMORY, errno); 370*5c51f124SMoriah Waterland quit(99); 371*5c51f124SMoriah Waterland } 372*5c51f124SMoriah Waterland regfiles_head->next = NULL; 373*5c51f124SMoriah Waterland regfiles_head->val = entryidx; 374*5c51f124SMoriah Waterland rfp = regfiles_head; 375*5c51f124SMoriah Waterland } else { 376*5c51f124SMoriah Waterland assert(rfp != NULL); 377*5c51f124SMoriah Waterland rfp->next = 378*5c51f124SMoriah Waterland malloc(sizeof (struct reg_files)); 379*5c51f124SMoriah Waterland if (rfp->next == NULL) { 380*5c51f124SMoriah Waterland progerr(ERR_MEMORY, errno); 381*5c51f124SMoriah Waterland quit(99); 382*5c51f124SMoriah Waterland } 383*5c51f124SMoriah Waterland rfp = rfp->next; 384*5c51f124SMoriah Waterland rfp->next = NULL; 385*5c51f124SMoriah Waterland rfp->val = entryidx; 386*5c51f124SMoriah Waterland } 387*5c51f124SMoriah Waterland 388*5c51f124SMoriah Waterland /* 389*5c51f124SMoriah Waterland * A warning message about unwritable targets 390*5c51f124SMoriah Waterland * in a class may be appropriate here. 391*5c51f124SMoriah Waterland */ 392*5c51f124SMoriah Waterland continue; 393*5c51f124SMoriah Waterland } 394*5c51f124SMoriah Waterland 395*5c51f124SMoriah Waterland /* 396*5c51f124SMoriah Waterland * If not installing from a partially spooled package 397*5c51f124SMoriah Waterland * (the "save/pspool" area), and the file contents can 398*5c51f124SMoriah Waterland * be changed (type is 'e' or 'v') and the class 399*5c51f124SMoriah Waterland * identifier is not "none": copy the file from the 400*5c51f124SMoriah Waterland * package (in pristine state with no actions performed) 401*5c51f124SMoriah Waterland * into the appropriate location in the packages 402*5c51f124SMoriah Waterland * destination "save/pspool" area. 403*5c51f124SMoriah Waterland */ 404*5c51f124SMoriah Waterland 405*5c51f124SMoriah Waterland if ((!is_partial_inst()) && 406*5c51f124SMoriah Waterland ((ept->ftype == 'e') || (ept->ftype == 'v') && 407*5c51f124SMoriah Waterland (strcmp(ept->pkg_class, "none") != 0))) { 408*5c51f124SMoriah Waterland 409*5c51f124SMoriah Waterland if (absolutepath(ext->map_path) == B_TRUE && 410*5c51f124SMoriah Waterland parametricpath(ext->cf_ent.ainfo.local, 411*5c51f124SMoriah Waterland &relocpath) == B_FALSE) { 412*5c51f124SMoriah Waterland pspool_loc = ROOT; 413*5c51f124SMoriah Waterland } else { 414*5c51f124SMoriah Waterland pspool_loc = RELOC; 415*5c51f124SMoriah Waterland } 416*5c51f124SMoriah Waterland 417*5c51f124SMoriah Waterland n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 418*5c51f124SMoriah Waterland saveSpoolInstallDir, pspool_loc, 419*5c51f124SMoriah Waterland relocpath ? relocpath : ext->map_path); 420*5c51f124SMoriah Waterland 421*5c51f124SMoriah Waterland if (n >= PATH_MAX) { 422*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, 423*5c51f124SMoriah Waterland saveSpoolInstallDir, 424*5c51f124SMoriah Waterland ext->map_path); 425*5c51f124SMoriah Waterland quit(99); 426*5c51f124SMoriah Waterland } 427*5c51f124SMoriah Waterland 428*5c51f124SMoriah Waterland /* copy, preserve source file mode */ 429*5c51f124SMoriah Waterland 430*5c51f124SMoriah Waterland if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) { 431*5c51f124SMoriah Waterland warnflag++; 432*5c51f124SMoriah Waterland } 433*5c51f124SMoriah Waterland } 434*5c51f124SMoriah Waterland 435*5c51f124SMoriah Waterland /* 436*5c51f124SMoriah Waterland * There are several tests here to determine 437*5c51f124SMoriah Waterland * how we're going to deal with objects 438*5c51f124SMoriah Waterland * intended for remote read-only filesystems. 439*5c51f124SMoriah Waterland * We don't use is_served() because this may be 440*5c51f124SMoriah Waterland * a server. We're actually interested in if 441*5c51f124SMoriah Waterland * it's *really* remote and *really* not 442*5c51f124SMoriah Waterland * writeable. 443*5c51f124SMoriah Waterland */ 444*5c51f124SMoriah Waterland 445*5c51f124SMoriah Waterland n = is_remote_fs(ept->path, &(ext->fsys_value)); 446*5c51f124SMoriah Waterland if ((n != 0) && 447*5c51f124SMoriah Waterland !is_fs_writeable(ept->path, 448*5c51f124SMoriah Waterland &(ext->fsys_value))) { 449*5c51f124SMoriah Waterland 450*5c51f124SMoriah Waterland /* 451*5c51f124SMoriah Waterland * Don't change the file, we can't write 452*5c51f124SMoriah Waterland * to it anyway. 453*5c51f124SMoriah Waterland */ 454*5c51f124SMoriah Waterland 455*5c51f124SMoriah Waterland mstat->attrchg = 0; 456*5c51f124SMoriah Waterland mstat->contchg = 0; 457*5c51f124SMoriah Waterland 458*5c51f124SMoriah Waterland /* 459*5c51f124SMoriah Waterland * If it's currently mounted, we can 460*5c51f124SMoriah Waterland * at least test it for existence. 461*5c51f124SMoriah Waterland */ 462*5c51f124SMoriah Waterland 463*5c51f124SMoriah Waterland if (is_mounted(ept->path, &(ext->fsys_value))) { 464*5c51f124SMoriah Waterland if (!isfile(NULL, dstp)) { 465*5c51f124SMoriah Waterland echo(MSG_IS_PRESENT, dstp); 466*5c51f124SMoriah Waterland } else { 467*5c51f124SMoriah Waterland echo(WRN_INSTVOL_NONE, dstp); 468*5c51f124SMoriah Waterland } 469*5c51f124SMoriah Waterland } else { 470*5c51f124SMoriah Waterland char *server_host; 471*5c51f124SMoriah Waterland 472*5c51f124SMoriah Waterland server_host = get_server_host( 473*5c51f124SMoriah Waterland ext->fsys_value); 474*5c51f124SMoriah Waterland 475*5c51f124SMoriah Waterland /* If not, we're just stuck. */ 476*5c51f124SMoriah Waterland echo(WRN_INSTVOL_NOVERIFY, 477*5c51f124SMoriah Waterland dstp, server_host); 478*5c51f124SMoriah Waterland } 479*5c51f124SMoriah Waterland 480*5c51f124SMoriah Waterland continue; 481*5c51f124SMoriah Waterland } 482*5c51f124SMoriah Waterland 483*5c51f124SMoriah Waterland /* echo output destination name */ 484*5c51f124SMoriah Waterland 485*5c51f124SMoriah Waterland echo("%s", dstp); 486*5c51f124SMoriah Waterland 487*5c51f124SMoriah Waterland /* 488*5c51f124SMoriah Waterland * if no source then no need to copy/verify 489*5c51f124SMoriah Waterland */ 490*5c51f124SMoriah Waterland 491*5c51f124SMoriah Waterland if (srcp == (char *)NULL) { 492*5c51f124SMoriah Waterland continue; 493*5c51f124SMoriah Waterland } 494*5c51f124SMoriah Waterland 495*5c51f124SMoriah Waterland /* 496*5c51f124SMoriah Waterland * If doing a partial installation (creating a 497*5c51f124SMoriah Waterland * non-global zone), extra steps need to be taken: 498*5c51f124SMoriah Waterland * 499*5c51f124SMoriah Waterland * 1) if the file is not type 'e' and not type 'v' and 500*5c51f124SMoriah Waterland * the class is "none": then the file must already 501*5c51f124SMoriah Waterland * exist (as a result of the initial non-global zone 502*5c51f124SMoriah Waterland * installation which caused all non-e/v files to be 503*5c51f124SMoriah Waterland * copied from the global zone to the non-global 504*5c51f124SMoriah Waterland * zone). If this is the case, verify that the file 505*5c51f124SMoriah Waterland * exists and has the correct attributes. 506*5c51f124SMoriah Waterland * 507*5c51f124SMoriah Waterland * 2) if the file is not type 'e' and not type 'v' 508*5c51f124SMoriah Waterland * and the class is NOT "none", *OR* if the file is 509*5c51f124SMoriah Waterland * type 'e' or type 'v': then check to see if the 510*5c51f124SMoriah Waterland * file is located in an area inherited from the 511*5c51f124SMoriah Waterland * global zone. If so, then there is no ability to 512*5c51f124SMoriah Waterland * change the file since inherited file systems are 513*5c51f124SMoriah Waterland * "read only" - just verify that the file exists and 514*5c51f124SMoriah Waterland * verify attributes only if not 'e' or 'v'. 515*5c51f124SMoriah Waterland */ 516*5c51f124SMoriah Waterland 517*5c51f124SMoriah Waterland if (is_partial_inst() != 0) { 518*5c51f124SMoriah Waterland 519*5c51f124SMoriah Waterland /* 520*5c51f124SMoriah Waterland * determine if the destination package is in an 521*5c51f124SMoriah Waterland * area inherited from the global zone 522*5c51f124SMoriah Waterland */ 523*5c51f124SMoriah Waterland 524*5c51f124SMoriah Waterland n = pkgMatchInherited(srcp, dstp, 525*5c51f124SMoriah Waterland get_inst_root(), ept->ainfo.mode, 526*5c51f124SMoriah Waterland ept->cinfo.modtime, ept->ftype, 527*5c51f124SMoriah Waterland ept->cinfo.cksum); 528*5c51f124SMoriah Waterland 529*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_PARTIAL_INST, 530*5c51f124SMoriah Waterland srcp ? srcp : "", dstp ? dstp: "", 531*5c51f124SMoriah Waterland ((get_inst_root()) && 532*5c51f124SMoriah Waterland (strcmp(get_inst_root(), "/") != 0)) ? 533*5c51f124SMoriah Waterland get_inst_root() : "", 534*5c51f124SMoriah Waterland ept->ainfo.mode, ept->cinfo.modtime, 535*5c51f124SMoriah Waterland ept->ftype, ept->cinfo.cksum, n); 536*5c51f124SMoriah Waterland 537*5c51f124SMoriah Waterland /* 538*5c51f124SMoriah Waterland * if not type 'e|v' and class 'none', then the 539*5c51f124SMoriah Waterland * file must already exist. 540*5c51f124SMoriah Waterland */ 541*5c51f124SMoriah Waterland 542*5c51f124SMoriah Waterland if ((ept->ftype != 'e') && 543*5c51f124SMoriah Waterland (ept->ftype != 'v') && 544*5c51f124SMoriah Waterland (strcmp(cl_nam(ept->pkg_class_idx), 545*5c51f124SMoriah Waterland "none") == 0)) { 546*5c51f124SMoriah Waterland 547*5c51f124SMoriah Waterland /* 548*5c51f124SMoriah Waterland * if the file is in a space inherited 549*5c51f124SMoriah Waterland * from the global zone, and if the 550*5c51f124SMoriah Waterland * contents or attributes are incorrect, 551*5c51f124SMoriah Waterland * then generate a warning that the 552*5c51f124SMoriah Waterland * global zone file contents and/or file 553*5c51f124SMoriah Waterland * attributes have been modified and 554*5c51f124SMoriah Waterland * that the modifications are extended 555*5c51f124SMoriah Waterland * to the non-global zone (inherited 556*5c51f124SMoriah Waterland * from the global zone). 557*5c51f124SMoriah Waterland */ 558*5c51f124SMoriah Waterland 559*5c51f124SMoriah Waterland if (n == 0) { 560*5c51f124SMoriah Waterland /* is file changed? */ 561*5c51f124SMoriah Waterland n = finalck(ept, 1, 1, B_TRUE); 562*5c51f124SMoriah Waterland 563*5c51f124SMoriah Waterland /* no - ok - continue */ 564*5c51f124SMoriah Waterland if (n == 0) { 565*5c51f124SMoriah Waterland continue; 566*5c51f124SMoriah Waterland } 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland /* output warning message */ 569*5c51f124SMoriah Waterland logerr(NOTE_INSTVOL_FINALCKFAIL, 570*5c51f124SMoriah Waterland pkginst, ext->map_path, 571*5c51f124SMoriah Waterland a_zoneName, ept->path); 572*5c51f124SMoriah Waterland continue; 573*5c51f124SMoriah Waterland } else if (!finalck(ept, 1, 1, 574*5c51f124SMoriah Waterland B_FALSE)) { 575*5c51f124SMoriah Waterland /* 576*5c51f124SMoriah Waterland * non-e/v file of class "none" 577*5c51f124SMoriah Waterland * not inherited from the global 578*5c51f124SMoriah Waterland * zone: verify file already 579*5c51f124SMoriah Waterland * exists:everything checks here 580*5c51f124SMoriah Waterland */ 581*5c51f124SMoriah Waterland mstat->attrchg = 0; 582*5c51f124SMoriah Waterland mstat->contchg = 0; 583*5c51f124SMoriah Waterland } 584*5c51f124SMoriah Waterland continue; 585*5c51f124SMoriah Waterland } 586*5c51f124SMoriah Waterland 587*5c51f124SMoriah Waterland /* 588*5c51f124SMoriah Waterland * non-e/v file with class action script, or 589*5c51f124SMoriah Waterland * e/v file: if the file is in an area inherited 590*5c51f124SMoriah Waterland * from the global zone, then no need (or the 591*5c51f124SMoriah Waterland * ability) to update just accept the file as is 592*5c51f124SMoriah Waterland */ 593*5c51f124SMoriah Waterland 594*5c51f124SMoriah Waterland if (n == B_TRUE) { 595*5c51f124SMoriah Waterland /* 596*5c51f124SMoriah Waterland * the object is in an area inherited 597*5c51f124SMoriah Waterland * from the global zone and the objects 598*5c51f124SMoriah Waterland * attributes are verified 599*5c51f124SMoriah Waterland */ 600*5c51f124SMoriah Waterland 601*5c51f124SMoriah Waterland mstat->attrchg = 0; 602*5c51f124SMoriah Waterland mstat->contchg = 0; 603*5c51f124SMoriah Waterland 604*5c51f124SMoriah Waterland /* NOTE: package object skipped */ 605*5c51f124SMoriah Waterland 606*5c51f124SMoriah Waterland if (skipped == (char *)NULL) { 607*5c51f124SMoriah Waterland skipped = dstp; 608*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 609*5c51f124SMoriah Waterland skipped); 610*5c51f124SMoriah Waterland } 611*5c51f124SMoriah Waterland continue; 612*5c51f124SMoriah Waterland } 613*5c51f124SMoriah Waterland } 614*5c51f124SMoriah Waterland 615*5c51f124SMoriah Waterland /* 616*5c51f124SMoriah Waterland * Copy from source media to target path and fix file 617*5c51f124SMoriah Waterland * mode and permission now in case installation halted. 618*5c51f124SMoriah Waterland */ 619*5c51f124SMoriah Waterland 620*5c51f124SMoriah Waterland if (z_path_is_inherited(dstp, ept->ftype, 621*5c51f124SMoriah Waterland get_inst_root()) == B_FALSE) { 622*5c51f124SMoriah Waterland 623*5c51f124SMoriah Waterland /* 624*5c51f124SMoriah Waterland * If the filesystem is read-only don't attempt 625*5c51f124SMoriah Waterland * to copy a file. Just check that the content 626*5c51f124SMoriah Waterland * and attributes of the file are correct. 627*5c51f124SMoriah Waterland * 628*5c51f124SMoriah Waterland * Normally this doesn't happen, because files, 629*5c51f124SMoriah Waterland * which don't change, are not returned by 630*5c51f124SMoriah Waterland * domerg(). However when installing a patch in 631*5c51f124SMoriah Waterland * a sparse zone, which was already installed 632*5c51f124SMoriah Waterland * in global zone with -G option, NGZ's 633*5c51f124SMoriah Waterland * contents db still contains the old record 634*5c51f124SMoriah Waterland * for this file and therefore domerg() 635*5c51f124SMoriah Waterland * considers these files to be different even 636*5c51f124SMoriah Waterland * though they are the same. 637*5c51f124SMoriah Waterland */ 638*5c51f124SMoriah Waterland n = 0; 639*5c51f124SMoriah Waterland if (is_fs_writeable(ept->path, 640*5c51f124SMoriah Waterland &(ext->fsys_value))) 641*5c51f124SMoriah Waterland n = cppath(MODE_SET|DIR_DISPLAY, srcp, 642*5c51f124SMoriah Waterland dstp, ept->ainfo.mode); 643*5c51f124SMoriah Waterland 644*5c51f124SMoriah Waterland if (n != 0) { 645*5c51f124SMoriah Waterland warnflag++; 646*5c51f124SMoriah Waterland } else if (!finalck(ept, 1, 1, B_FALSE)) { 647*5c51f124SMoriah Waterland /* 648*5c51f124SMoriah Waterland * everything checks here 649*5c51f124SMoriah Waterland */ 650*5c51f124SMoriah Waterland mstat->attrchg = 0; 651*5c51f124SMoriah Waterland mstat->contchg = 0; 652*5c51f124SMoriah Waterland } 653*5c51f124SMoriah Waterland } 654*5c51f124SMoriah Waterland 655*5c51f124SMoriah Waterland /* NOTE: a package object was updated */ 656*5c51f124SMoriah Waterland 657*5c51f124SMoriah Waterland if (updated == (char *)NULL) { 658*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_UPDATED, dstp); 659*5c51f124SMoriah Waterland updated = dstp; 660*5c51f124SMoriah Waterland } 661*5c51f124SMoriah Waterland } 662*5c51f124SMoriah Waterland 663*5c51f124SMoriah Waterland /* 664*5c51f124SMoriah Waterland * We have now completed processing of all pathnames 665*5c51f124SMoriah Waterland * associated with this volume and class. 666*5c51f124SMoriah Waterland */ 667*5c51f124SMoriah Waterland if (cl_iscript(classidx)) { 668*5c51f124SMoriah Waterland /* 669*5c51f124SMoriah Waterland * Execute appropriate class action script 670*5c51f124SMoriah Waterland * with list of source/destination pathnames 671*5c51f124SMoriah Waterland * as the input to the script. 672*5c51f124SMoriah Waterland */ 673*5c51f124SMoriah Waterland 674*5c51f124SMoriah Waterland if (chdir(pkgbin)) { 675*5c51f124SMoriah Waterland progerr(ERR_CHGDIR, pkgbin); 676*5c51f124SMoriah Waterland quit(99); 677*5c51f124SMoriah Waterland } 678*5c51f124SMoriah Waterland 679*5c51f124SMoriah Waterland if (listfp) { 680*5c51f124SMoriah Waterland (void) fclose(listfp); 681*5c51f124SMoriah Waterland } 682*5c51f124SMoriah Waterland 683*5c51f124SMoriah Waterland /* 684*5c51f124SMoriah Waterland * if the object associated with the class action script 685*5c51f124SMoriah Waterland * is in an area inherited from the global zone, then 686*5c51f124SMoriah Waterland * there is no need to run the class action script - 687*5c51f124SMoriah Waterland * assume that anything the script would do has already 688*5c51f124SMoriah Waterland * been done in the area shared from the global zone. 689*5c51f124SMoriah Waterland */ 690*5c51f124SMoriah Waterland 691*5c51f124SMoriah Waterland /* nothing updated, nothing skipped */ 692*5c51f124SMoriah Waterland 693*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_CAS_INFO, is_partial_inst(), 694*5c51f124SMoriah Waterland updated ? updated : "", 695*5c51f124SMoriah Waterland skipped ? skipped : "", 696*5c51f124SMoriah Waterland anyPathLocal ? anyPathLocal : ""); 697*5c51f124SMoriah Waterland 698*5c51f124SMoriah Waterland if ((is_partial_inst() != 0) && 699*5c51f124SMoriah Waterland (updated == (char *)NULL) && 700*5c51f124SMoriah Waterland (anyPathLocal == (char *)NULL)) { 701*5c51f124SMoriah Waterland 702*5c51f124SMoriah Waterland /* 703*5c51f124SMoriah Waterland * installing in non-global zone, and no object 704*5c51f124SMoriah Waterland * has been updated (installed/verified in non- 705*5c51f124SMoriah Waterland * inherited area), and no path delivered by the 706*5c51f124SMoriah Waterland * package is in an area not inherited from the 707*5c51f124SMoriah Waterland * global zone (all paths delivered are in 708*5c51f124SMoriah Waterland * areas inherited from the global zone): do not 709*5c51f124SMoriah Waterland * run the class action script because the only 710*5c51f124SMoriah Waterland * affected areas are inherited (read only). 711*5c51f124SMoriah Waterland */ 712*5c51f124SMoriah Waterland 713*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_NOT_RUNNING_CAS, 714*5c51f124SMoriah Waterland a_zoneName ? a_zoneName : "?", 715*5c51f124SMoriah Waterland eocflag ? "ENDOFCLASS" : 716*5c51f124SMoriah Waterland cl_iscript(classidx), 717*5c51f124SMoriah Waterland cl_nam(classidx), 718*5c51f124SMoriah Waterland cl_iscript(classidx)); 719*5c51f124SMoriah Waterland 720*5c51f124SMoriah Waterland if ((r_skipped != (char **)NULL) && 721*5c51f124SMoriah Waterland (*r_skipped == (char *)NULL) && 722*5c51f124SMoriah Waterland (skipped == (char *)NULL)) { 723*5c51f124SMoriah Waterland skipped = "postinstall"; 724*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 725*5c51f124SMoriah Waterland skipped); 726*5c51f124SMoriah Waterland } 727*5c51f124SMoriah Waterland } else { 728*5c51f124SMoriah Waterland /* run the class action script */ 729*5c51f124SMoriah Waterland 730*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_RUNNING_CAS, 731*5c51f124SMoriah Waterland a_zoneName ? a_zoneName : "?", 732*5c51f124SMoriah Waterland eocflag ? "ENDOFCLASS" : 733*5c51f124SMoriah Waterland cl_iscript(classidx), 734*5c51f124SMoriah Waterland cl_nam(classidx), 735*5c51f124SMoriah Waterland cl_iscript(classidx)); 736*5c51f124SMoriah Waterland 737*5c51f124SMoriah Waterland /* Use ULIMIT if supplied. */ 738*5c51f124SMoriah Waterland set_ulimit(cl_iscript(classidx), ERR_CASFAIL); 739*5c51f124SMoriah Waterland 740*5c51f124SMoriah Waterland if (eocflag) { 741*5c51f124SMoriah Waterland /* 742*5c51f124SMoriah Waterland * end of class detected. 743*5c51f124SMoriah Waterland * Since there are no more volumes which 744*5c51f124SMoriah Waterland * contain pathnames associated with 745*5c51f124SMoriah Waterland * this class, execute class action 746*5c51f124SMoriah Waterland * script with the ENDOFCLASS argument; 747*5c51f124SMoriah Waterland * we do this even if none of the path 748*5c51f124SMoriah Waterland * names associated with this class and 749*5c51f124SMoriah Waterland * volume needed installation to 750*5c51f124SMoriah Waterland * guarantee the class action script is 751*5c51f124SMoriah Waterland * executed at least once during package 752*5c51f124SMoriah Waterland * installation. 753*5c51f124SMoriah Waterland */ 754*5c51f124SMoriah Waterland if (pkgverbose) { 755*5c51f124SMoriah Waterland n = pkgexecl((listfp ? 756*5c51f124SMoriah Waterland listfile : CAS_STDIN), 757*5c51f124SMoriah Waterland CAS_STDOUT, 758*5c51f124SMoriah Waterland CAS_USER, CAS_GRP, 759*5c51f124SMoriah Waterland SHELL, "-x", 760*5c51f124SMoriah Waterland cl_iscript(classidx), 761*5c51f124SMoriah Waterland "ENDOFCLASS", NULL); 762*5c51f124SMoriah Waterland } else { 763*5c51f124SMoriah Waterland n = pkgexecl( 764*5c51f124SMoriah Waterland (listfp ? 765*5c51f124SMoriah Waterland listfile : CAS_STDIN), 766*5c51f124SMoriah Waterland CAS_STDOUT, CAS_USER, 767*5c51f124SMoriah Waterland CAS_GRP, SHELL, 768*5c51f124SMoriah Waterland cl_iscript(classidx), 769*5c51f124SMoriah Waterland "ENDOFCLASS", NULL); 770*5c51f124SMoriah Waterland } 771*5c51f124SMoriah Waterland ckreturn(n, ERR_CASFAIL); 772*5c51f124SMoriah Waterland } else if (count) { 773*5c51f124SMoriah Waterland /* execute class action script */ 774*5c51f124SMoriah Waterland if (pkgverbose) { 775*5c51f124SMoriah Waterland n = pkgexecl(listfile, 776*5c51f124SMoriah Waterland CAS_STDOUT, CAS_USER, 777*5c51f124SMoriah Waterland CAS_GRP, SHELL, "-x", 778*5c51f124SMoriah Waterland cl_iscript(classidx), 779*5c51f124SMoriah Waterland NULL); 780*5c51f124SMoriah Waterland } else { 781*5c51f124SMoriah Waterland n = pkgexecl(listfile, 782*5c51f124SMoriah Waterland CAS_STDOUT, CAS_USER, 783*5c51f124SMoriah Waterland CAS_GRP, SHELL, 784*5c51f124SMoriah Waterland cl_iscript(classidx), 785*5c51f124SMoriah Waterland NULL); 786*5c51f124SMoriah Waterland } 787*5c51f124SMoriah Waterland ckreturn(n, ERR_CASFAIL); 788*5c51f124SMoriah Waterland } 789*5c51f124SMoriah Waterland 790*5c51f124SMoriah Waterland /* 791*5c51f124SMoriah Waterland * Ensure the mod times on disk match those 792*5c51f124SMoriah Waterland * in the pkgmap. In this case, call cverify 793*5c51f124SMoriah Waterland * with checksumming disabled, since the only 794*5c51f124SMoriah Waterland * action that needs to be done is to verify 795*5c51f124SMoriah Waterland * that the attributes are correct. 796*5c51f124SMoriah Waterland */ 797*5c51f124SMoriah Waterland 798*5c51f124SMoriah Waterland if ((rfp = regfiles_head) != NULL) { 799*5c51f124SMoriah Waterland while (rfp != NULL) { 800*5c51f124SMoriah Waterland ept = &(extlist[rfp->val]->cf_ent); 801*5c51f124SMoriah Waterland cverify(1, &ept->ftype, ept->path, 802*5c51f124SMoriah Waterland &ept->cinfo, 0); 803*5c51f124SMoriah Waterland rfp = rfp->next; 804*5c51f124SMoriah Waterland } 805*5c51f124SMoriah Waterland regfiles_free(); 806*5c51f124SMoriah Waterland } 807*5c51f124SMoriah Waterland 808*5c51f124SMoriah Waterland clr_ulimit(); 809*5c51f124SMoriah Waterland 810*5c51f124SMoriah Waterland if ((r_updated != (char **)NULL) && 811*5c51f124SMoriah Waterland (*r_updated == (char *)NULL) && 812*5c51f124SMoriah Waterland (updated == (char *)NULL)) { 813*5c51f124SMoriah Waterland updated = "postinstall"; 814*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_UPDATED, 815*5c51f124SMoriah Waterland updated); 816*5c51f124SMoriah Waterland } 817*5c51f124SMoriah Waterland } 818*5c51f124SMoriah Waterland if (listfile) { 819*5c51f124SMoriah Waterland (void) remove(listfile); 820*5c51f124SMoriah Waterland } 821*5c51f124SMoriah Waterland } 822*5c51f124SMoriah Waterland 823*5c51f124SMoriah Waterland if (eocflag && (!is_partial_inst() || (is_partial_inst() && 824*5c51f124SMoriah Waterland strcmp(cl_nam(classidx), "none") != 0))) { 825*5c51f124SMoriah Waterland if (cl_dvfy(classidx) == QKVERIFY && !repl_permitted) { 826*5c51f124SMoriah Waterland /* 827*5c51f124SMoriah Waterland * The quick verify just fixes everything. 828*5c51f124SMoriah Waterland * If it returns 0, all is well. If it 829*5c51f124SMoriah Waterland * returns 1, then the class installation 830*5c51f124SMoriah Waterland * was incomplete and we retry on the 831*5c51f124SMoriah Waterland * stuff that failed in the conventional 832*5c51f124SMoriah Waterland * way (without a CAS). this is primarily 833*5c51f124SMoriah Waterland * to accomodate old archives such as are 834*5c51f124SMoriah Waterland * found in pre-2.5 WOS; but, it is also 835*5c51f124SMoriah Waterland * used when a critical dynamic library 836*5c51f124SMoriah Waterland * is not archived with its class. 837*5c51f124SMoriah Waterland */ 838*5c51f124SMoriah Waterland if (!fix_attributes(extlist, classidx)) { 839*5c51f124SMoriah Waterland /* 840*5c51f124SMoriah Waterland * Reset the CAS pointer. If the 841*5c51f124SMoriah Waterland * function returns 0 then there 842*5c51f124SMoriah Waterland * was no script there in the first 843*5c51f124SMoriah Waterland * place and we'll just have to 844*5c51f124SMoriah Waterland * call this a miss. 845*5c51f124SMoriah Waterland */ 846*5c51f124SMoriah Waterland if (cl_deliscript(classidx)) 847*5c51f124SMoriah Waterland /* 848*5c51f124SMoriah Waterland * Decrement classidx for 849*5c51f124SMoriah Waterland * next pass. 850*5c51f124SMoriah Waterland */ 851*5c51f124SMoriah Waterland classidx--; 852*5c51f124SMoriah Waterland } 853*5c51f124SMoriah Waterland } else { 854*5c51f124SMoriah Waterland /* 855*5c51f124SMoriah Waterland * Finalize merge. This checks to make sure 856*5c51f124SMoriah Waterland * file attributes are correct and any links 857*5c51f124SMoriah Waterland * specified are created. 858*5c51f124SMoriah Waterland */ 859*5c51f124SMoriah Waterland (void) endofclass(extlist, classidx, 860*5c51f124SMoriah Waterland (cl_iscript(classidx) ? 0 : 1), 861*5c51f124SMoriah Waterland a_cfVfp, a_cfTmpVfp); 862*5c51f124SMoriah Waterland } 863*5c51f124SMoriah Waterland } 864*5c51f124SMoriah Waterland } 865*5c51f124SMoriah Waterland } 866*5c51f124SMoriah Waterland 867*5c51f124SMoriah Waterland /* 868*5c51f124SMoriah Waterland * Instead of creating links back to the GZ files the logic is 869*5c51f124SMoriah Waterland * to let zdo recreate the files from the GZ then invoke pkgadd to 870*5c51f124SMoriah Waterland * install the editable files and skip over any 'f'type files. 871*5c51f124SMoriah Waterland * The commented out block is to create the links which should be 872*5c51f124SMoriah Waterland * removed once the current code is tested to be correct. 873*5c51f124SMoriah Waterland */ 874*5c51f124SMoriah Waterland 875*5c51f124SMoriah Waterland /* 876*5c51f124SMoriah Waterland * Go through extlist creating links for 'f'type files 877*5c51f124SMoriah Waterland * if we're in a global zone. Note that this code lies 878*5c51f124SMoriah Waterland * here instead of in the main loop to support CAF packages. 879*5c51f124SMoriah Waterland * In a CAF package the files are installed by the i.none script 880*5c51f124SMoriah Waterland * and don't exist until all files are done being processed, thus 881*5c51f124SMoriah Waterland * the additional loop through extlist. 882*5c51f124SMoriah Waterland */ 883*5c51f124SMoriah Waterland 884*5c51f124SMoriah Waterland /* 885*5c51f124SMoriah Waterland * output appropriate completion message 886*5c51f124SMoriah Waterland */ 887*5c51f124SMoriah Waterland 888*5c51f124SMoriah Waterland if (is_depend_pkginfo_DB() == B_TRUE) { 889*5c51f124SMoriah Waterland /* updating database only (hollow package) */ 890*5c51f124SMoriah Waterland if (a_zoneName == (char *)NULL) { 891*5c51f124SMoriah Waterland echo(MSG_DBUPD_N_N, part, nparts); 892*5c51f124SMoriah Waterland } else { 893*5c51f124SMoriah Waterland echo(MSG_DBUPD_N_N_LZ, part, nparts, a_zoneName); 894*5c51f124SMoriah Waterland } 895*5c51f124SMoriah Waterland } else if (tcount == 0) { 896*5c51f124SMoriah Waterland /* updating package (non-hollow package) */ 897*5c51f124SMoriah Waterland if (a_zoneName == (char *)NULL) { 898*5c51f124SMoriah Waterland echo(MSG_INST_N_N, part, nparts); 899*5c51f124SMoriah Waterland } else { 900*5c51f124SMoriah Waterland echo(MSG_INST_N_N_LZ, part, nparts, a_zoneName); 901*5c51f124SMoriah Waterland } 902*5c51f124SMoriah Waterland } 903*5c51f124SMoriah Waterland 904*5c51f124SMoriah Waterland /* 905*5c51f124SMoriah Waterland * if any package objects were updated (not inherited from the 906*5c51f124SMoriah Waterland * global zone or otherwise already in existence), set the updated 907*5c51f124SMoriah Waterland * flag as appropriate 908*5c51f124SMoriah Waterland */ 909*5c51f124SMoriah Waterland 910*5c51f124SMoriah Waterland if (updated != (char *)NULL) { 911*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_UPDATED, updated); 912*5c51f124SMoriah Waterland if (r_updated != (char **)NULL) { 913*5c51f124SMoriah Waterland *r_updated = updated; 914*5c51f124SMoriah Waterland } 915*5c51f124SMoriah Waterland } 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland /* 918*5c51f124SMoriah Waterland * if any package objects were skipped (verified inherited from the 919*5c51f124SMoriah Waterland * global zone), set the skipped flag as appropriate 920*5c51f124SMoriah Waterland */ 921*5c51f124SMoriah Waterland 922*5c51f124SMoriah Waterland if (skipped != (char *)NULL) { 923*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_SKIPPED, skipped); 924*5c51f124SMoriah Waterland if (r_skipped != (char **)NULL) { 925*5c51f124SMoriah Waterland *r_skipped = skipped; 926*5c51f124SMoriah Waterland } 927*5c51f124SMoriah Waterland } 928*5c51f124SMoriah Waterland } 929*5c51f124SMoriah Waterland 930*5c51f124SMoriah Waterland /* 931*5c51f124SMoriah Waterland * Name: domerg 932*5c51f124SMoriah Waterland * Description: For the specified class, review each entry and return the array 933*5c51f124SMoriah Waterland * index number of the next regular file to process. Hard links are 934*5c51f124SMoriah Waterland * skipped (they are created in endofclass() and directories, 935*5c51f124SMoriah Waterland * symlinks, pipes and devices are created here, as well as any 936*5c51f124SMoriah Waterland * file that already exists and has the correct attributes. 937*5c51f124SMoriah Waterland * Arguments: struct cfextra **extlist - [RO, *RW] 938*5c51f124SMoriah Waterland * - Pointer to list of cfextra structures representing 939*5c51f124SMoriah Waterland * the pkgmap of the package to be installed 940*5c51f124SMoriah Waterland * int part - [RO, *RO] 941*5c51f124SMoriah Waterland * - the part of the package currently being processed; 942*5c51f124SMoriah Waterland * packages begin with part "1" and proceed for the 943*5c51f124SMoriah Waterland * number (nparts) that comprise the package (volume). 944*5c51f124SMoriah Waterland * int nparts - [RO, *RO] 945*5c51f124SMoriah Waterland * - the number of parts the package is divided into 946*5c51f124SMoriah Waterland * int myclass - [RO, *RO] 947*5c51f124SMoriah Waterland * - index into class array of the current class 948*5c51f124SMoriah Waterland * char **srcp - [RW, *RW] 949*5c51f124SMoriah Waterland * - pointer to pointer to string representing the source 950*5c51f124SMoriah Waterland * path for the next package to process - if this 951*5c51f124SMoriah Waterland * function returns != DMRG_DONE then this pointer is 952*5c51f124SMoriah Waterland * set to a pointer to a string representing the source 953*5c51f124SMoriah Waterland * path for the next object from the package to process 954*5c51f124SMoriah Waterland * char **dstp - [RW, *RW] 955*5c51f124SMoriah Waterland * - pointer to pointer to string representing the target 956*5c51f124SMoriah Waterland * path for the next package to process - if this 957*5c51f124SMoriah Waterland * function returns != DMRG_DONE then this pointer is 958*5c51f124SMoriah Waterland * set to a pointer to a string representing the target 959*5c51f124SMoriah Waterland * path for the next object from the package to process 960*5c51f124SMoriah Waterland * char **r_updated - [RO, *RW] 961*5c51f124SMoriah Waterland * - pointer to pointer to string - set if the last path 962*5c51f124SMoriah Waterland * returned exists or does not need updating and the 963*5c51f124SMoriah Waterland * object is NOT located in an area inherited from the 964*5c51f124SMoriah Waterland * global zone. This is used to determine if the last 965*5c51f124SMoriah Waterland * path object returned DOES exist in an area that is 966*5c51f124SMoriah Waterland * inherited from the global zone. If no paths are 967*5c51f124SMoriah Waterland * inherited from the global zone, this is always set 968*5c51f124SMoriah Waterland * when a path to be installed exists and has the 969*5c51f124SMoriah Waterland * correct contents. 970*5c51f124SMoriah Waterland * char **r_skipped - [RO, *RW] 971*5c51f124SMoriah Waterland * - pointer to pointer to string - set if the last path 972*5c51f124SMoriah Waterland * returned exists or does not need updating and the 973*5c51f124SMoriah Waterland * object IS located in an area inherited from the 974*5c51f124SMoriah Waterland * global zone. This is used to determine if the last 975*5c51f124SMoriah Waterland * path object returned does NOT exist in an area that 976*5c51f124SMoriah Waterland * is inherited from the global zone. If no paths are 977*5c51f124SMoriah Waterland * inherited from the global zone, this is never set. 978*5c51f124SMoriah Waterland * char **r_anyPathLocal - [RO, *RW] 979*5c51f124SMoriah Waterland * - pointer to pointer to string - set if any object 980*5c51f124SMoriah Waterland * belonging to the package is NOT located in an area 981*5c51f124SMoriah Waterland * inherited from the global zone. This is used to 982*5c51f124SMoriah Waterland * determine if the package references ANY objects that 983*5c51f124SMoriah Waterland * are NOT located in an area inherited from the global 984*5c51f124SMoriah Waterland * zone - regardless of whether or not they need to be 985*5c51f124SMoriah Waterland * updated (installed/copied). If no paths are inherited 986*5c51f124SMoriah Waterland * from the global zone, this is always set when a path 987*5c51f124SMoriah Waterland * to be installed already exists and has the correct 988*5c51f124SMoriah Waterland * contents. 989*5c51f124SMoriah Waterland * Returns: int 990*5c51f124SMoriah Waterland * != DMRG_DONE - index into extlist of the next path to 991*5c51f124SMoriah Waterland * be processed - that needs to be installed/copied 992*5c51f124SMoriah Waterland * == DMRG_DONE - all entries processed 993*5c51f124SMoriah Waterland */ 994*5c51f124SMoriah Waterland 995*5c51f124SMoriah Waterland static int 996*5c51f124SMoriah Waterland domerg(struct cfextra **extlist, int part, int nparts, 997*5c51f124SMoriah Waterland int myclass, char **srcp, char **dstp, 998*5c51f124SMoriah Waterland char **r_updated, char **r_skipped, 999*5c51f124SMoriah Waterland char **r_anyPathLocal) 1000*5c51f124SMoriah Waterland { 1001*5c51f124SMoriah Waterland boolean_t stateFlag = B_FALSE; 1002*5c51f124SMoriah Waterland int i; 1003*5c51f124SMoriah Waterland int msg_ugid; 1004*5c51f124SMoriah Waterland static int maxvol = 0; 1005*5c51f124SMoriah Waterland static int svindx = 0; 1006*5c51f124SMoriah Waterland static int svpart = 0; 1007*5c51f124SMoriah Waterland struct cfent *ept = (struct cfent *)NULL; 1008*5c51f124SMoriah Waterland struct mergstat *mstat = (struct mergstat *)NULL; 1009*5c51f124SMoriah Waterland 1010*5c51f124SMoriah Waterland /* reset returned path pointers */ 1011*5c51f124SMoriah Waterland 1012*5c51f124SMoriah Waterland *dstp = (char *)NULL; 1013*5c51f124SMoriah Waterland *srcp = (char *)NULL; 1014*5c51f124SMoriah Waterland 1015*5c51f124SMoriah Waterland /* set to start or continue based on which part being processed */ 1016*5c51f124SMoriah Waterland 1017*5c51f124SMoriah Waterland if (part != 0) { 1018*5c51f124SMoriah Waterland maxvol = 0; 1019*5c51f124SMoriah Waterland svindx = 0; 1020*5c51f124SMoriah Waterland svpart = part; 1021*5c51f124SMoriah Waterland } else { 1022*5c51f124SMoriah Waterland i = svindx; 1023*5c51f124SMoriah Waterland part = svpart; 1024*5c51f124SMoriah Waterland } 1025*5c51f124SMoriah Waterland 1026*5c51f124SMoriah Waterland /* 1027*5c51f124SMoriah Waterland * This goes through the pkgmap entries one by one testing them 1028*5c51f124SMoriah Waterland * for inclusion in the package database as well as for validity 1029*5c51f124SMoriah Waterland * against existing files. 1030*5c51f124SMoriah Waterland */ 1031*5c51f124SMoriah Waterland for (i = svindx; extlist[i]; i++) { 1032*5c51f124SMoriah Waterland ept = &(extlist[i]->cf_ent); 1033*5c51f124SMoriah Waterland mstat = &(extlist[i]->mstat); 1034*5c51f124SMoriah Waterland 1035*5c51f124SMoriah Waterland /* 1036*5c51f124SMoriah Waterland * as paths are processed, if the "anyPathLocal" flag has not 1037*5c51f124SMoriah Waterland * been set, if the object is not of type 'i' (package script), 1038*5c51f124SMoriah Waterland * check to see if the object is in an area inherited from the 1039*5c51f124SMoriah Waterland * global zone - if not, set "anyPathLocal" to the path found, 1040*5c51f124SMoriah Waterland * indicating that at least one path is in an area that is not 1041*5c51f124SMoriah Waterland * inherited from the global zone. 1042*5c51f124SMoriah Waterland */ 1043*5c51f124SMoriah Waterland 1044*5c51f124SMoriah Waterland if ((r_anyPathLocal != (char **)NULL) && 1045*5c51f124SMoriah Waterland (*r_anyPathLocal == (char *)NULL) && 1046*5c51f124SMoriah Waterland (ept->ftype != 'i') && 1047*5c51f124SMoriah Waterland (z_path_is_inherited(ept->path, ept->ftype, 1048*5c51f124SMoriah Waterland get_inst_root()) == B_FALSE)) { 1049*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_LOCAL, ept->path); 1050*5c51f124SMoriah Waterland *r_anyPathLocal = ept->path; 1051*5c51f124SMoriah Waterland } 1052*5c51f124SMoriah Waterland 1053*5c51f124SMoriah Waterland /* if this isn't the class of current interest, skip it */ 1054*5c51f124SMoriah Waterland 1055*5c51f124SMoriah Waterland if (myclass != ept->pkg_class_idx) { 1056*5c51f124SMoriah Waterland continue; 1057*5c51f124SMoriah Waterland } 1058*5c51f124SMoriah Waterland 1059*5c51f124SMoriah Waterland /* if the class is invalid, announce it & exit */ 1060*5c51f124SMoriah Waterland if (ept->pkg_class_idx == -1) { 1061*5c51f124SMoriah Waterland progerr(ERR_CLIDX, ept->pkg_class_idx, 1062*5c51f124SMoriah Waterland (ept->path && *ept->path) ? ept->path : "unknown"); 1063*5c51f124SMoriah Waterland logerr(gettext("pathname=%s\n"), 1064*5c51f124SMoriah Waterland (ept->path && *ept->path) ? ept->path : "unknown"); 1065*5c51f124SMoriah Waterland logerr(gettext("class=<%s>\n"), 1066*5c51f124SMoriah Waterland (ept->pkg_class && *ept->pkg_class) ? 1067*5c51f124SMoriah Waterland ept->pkg_class : "Unknown"); 1068*5c51f124SMoriah Waterland logerr(gettext("CLASSES=<%s>\n"), 1069*5c51f124SMoriah Waterland getenv("CLASSES") ? getenv("CLASSES") : "Not Set"); 1070*5c51f124SMoriah Waterland quit(99); 1071*5c51f124SMoriah Waterland } 1072*5c51f124SMoriah Waterland 1073*5c51f124SMoriah Waterland /* 1074*5c51f124SMoriah Waterland * Next check to see if we are going to try to delete a 1075*5c51f124SMoriah Waterland * populated directory in some distressing way. 1076*5c51f124SMoriah Waterland */ 1077*5c51f124SMoriah Waterland if (mstat->dir2nondir) 1078*5c51f124SMoriah Waterland if (dir_is_populated(ept->path)) { 1079*5c51f124SMoriah Waterland logerr(WRN_INSTVOL_NOTDIR, ept->path); 1080*5c51f124SMoriah Waterland warnflag++; 1081*5c51f124SMoriah Waterland mstat->denied = 1; /* install denied! */ 1082*5c51f124SMoriah Waterland continue; 1083*5c51f124SMoriah Waterland } else { /* Replace is OK. */ 1084*5c51f124SMoriah Waterland /* 1085*5c51f124SMoriah Waterland * Remove this directory, so it won't 1086*5c51f124SMoriah Waterland * interfere with creation of the new object. 1087*5c51f124SMoriah Waterland */ 1088*5c51f124SMoriah Waterland if (rmdir(ept->path)) { 1089*5c51f124SMoriah Waterland /* 1090*5c51f124SMoriah Waterland * If it didn't work, there's nothing 1091*5c51f124SMoriah Waterland * we can do. To continue would 1092*5c51f124SMoriah Waterland * likely corrupt the filesystem 1093*5c51f124SMoriah Waterland * which is unacceptable. 1094*5c51f124SMoriah Waterland */ 1095*5c51f124SMoriah Waterland progerr(ERR_RMDIR, ept->path); 1096*5c51f124SMoriah Waterland quit(99); 1097*5c51f124SMoriah Waterland } 1098*5c51f124SMoriah Waterland 1099*5c51f124SMoriah Waterland repl_permitted = 1; /* flag it */ 1100*5c51f124SMoriah Waterland } 1101*5c51f124SMoriah Waterland 1102*5c51f124SMoriah Waterland /* adjust the max volume number appropriately */ 1103*5c51f124SMoriah Waterland 1104*5c51f124SMoriah Waterland if (ept->volno > maxvol) { 1105*5c51f124SMoriah Waterland maxvol = ept->volno; 1106*5c51f124SMoriah Waterland } 1107*5c51f124SMoriah Waterland 1108*5c51f124SMoriah Waterland /* if this part goes into another volume, skip it */ 1109*5c51f124SMoriah Waterland 1110*5c51f124SMoriah Waterland if (part != ept->volno) { 1111*5c51f124SMoriah Waterland continue; 1112*5c51f124SMoriah Waterland } 1113*5c51f124SMoriah Waterland 1114*5c51f124SMoriah Waterland /* 1115*5c51f124SMoriah Waterland * If it's a conflicting file and it's not supposed to be 1116*5c51f124SMoriah Waterland * installed, note it and skip. 1117*5c51f124SMoriah Waterland */ 1118*5c51f124SMoriah Waterland if (nocnflct && mstat->shared && ept->ftype != 'e') { 1119*5c51f124SMoriah Waterland if (mstat->contchg || mstat->attrchg) { 1120*5c51f124SMoriah Waterland echo(MSG_SHIGN, ept->path); 1121*5c51f124SMoriah Waterland } 1122*5c51f124SMoriah Waterland continue; 1123*5c51f124SMoriah Waterland } 1124*5c51f124SMoriah Waterland 1125*5c51f124SMoriah Waterland /* 1126*5c51f124SMoriah Waterland * If we want to set uid or gid but user says no, note it. 1127*5c51f124SMoriah Waterland * Remember that the actual mode bits in the structure have 1128*5c51f124SMoriah Waterland * already been adjusted and the mstat flag is telling us 1129*5c51f124SMoriah Waterland * about the original mode. 1130*5c51f124SMoriah Waterland */ 1131*5c51f124SMoriah Waterland if (nosetuid && (mstat->setuid || mstat->setgid)) { 1132*5c51f124SMoriah Waterland msg_ugid = 1; /* don't repeat attribute message. */ 1133*5c51f124SMoriah Waterland if (is_fs_writeable(ept->path, 1134*5c51f124SMoriah Waterland &(extlist[i]->fsys_value))) { 1135*5c51f124SMoriah Waterland if (!(mstat->contchg) && mstat->attrchg) { 1136*5c51f124SMoriah Waterland echo(MSG_UGMOD, ept->path); 1137*5c51f124SMoriah Waterland } else { 1138*5c51f124SMoriah Waterland echo(MSG_UGID, ept->path); 1139*5c51f124SMoriah Waterland } 1140*5c51f124SMoriah Waterland } 1141*5c51f124SMoriah Waterland } else { 1142*5c51f124SMoriah Waterland msg_ugid = 0; 1143*5c51f124SMoriah Waterland } 1144*5c51f124SMoriah Waterland 1145*5c51f124SMoriah Waterland switch (ept->ftype) { 1146*5c51f124SMoriah Waterland case 'l': /* hard link */ 1147*5c51f124SMoriah Waterland /* links treated as object "update/skip" */ 1148*5c51f124SMoriah Waterland stateFlag = B_TRUE; 1149*5c51f124SMoriah Waterland continue; /* defer to final proc */ 1150*5c51f124SMoriah Waterland 1151*5c51f124SMoriah Waterland case 's': /* for symlink, verify without fix first */ 1152*5c51f124SMoriah Waterland /* links treated as object "update/skip" */ 1153*5c51f124SMoriah Waterland stateFlag = B_TRUE; 1154*5c51f124SMoriah Waterland 1155*5c51f124SMoriah Waterland /* Do this only for default verify */ 1156*5c51f124SMoriah Waterland if (cl_dvfy(myclass) == DEFAULT) { 1157*5c51f124SMoriah Waterland if (averify(0, &ept->ftype, 1158*5c51f124SMoriah Waterland ept->path, &ept->ainfo)) 1159*5c51f124SMoriah Waterland echo(MSG_SLINK, ept->path); 1160*5c51f124SMoriah Waterland } 1161*5c51f124SMoriah Waterland 1162*5c51f124SMoriah Waterland /*FALLTHRU*/ 1163*5c51f124SMoriah Waterland 1164*5c51f124SMoriah Waterland case 'd': /* directory */ 1165*5c51f124SMoriah Waterland case 'x': /* exclusive directory */ 1166*5c51f124SMoriah Waterland case 'c': /* character special device */ 1167*5c51f124SMoriah Waterland case 'b': /* block special device */ 1168*5c51f124SMoriah Waterland case 'p': /* named pipe */ 1169*5c51f124SMoriah Waterland /* these NOT treated as object "update/skip" */ 1170*5c51f124SMoriah Waterland stateFlag = B_FALSE; 1171*5c51f124SMoriah Waterland 1172*5c51f124SMoriah Waterland /* 1173*5c51f124SMoriah Waterland * If we can't get to it for legitimate reasons, 1174*5c51f124SMoriah Waterland * don't try to verify it. 1175*5c51f124SMoriah Waterland */ 1176*5c51f124SMoriah Waterland if ((z_path_is_inherited(ept->path, ept->ftype, 1177*5c51f124SMoriah Waterland get_inst_root())) || 1178*5c51f124SMoriah Waterland is_remote_fs(ept->path, 1179*5c51f124SMoriah Waterland &(extlist[i]->fsys_value)) && 1180*5c51f124SMoriah Waterland !is_fs_writeable(ept->path, 1181*5c51f124SMoriah Waterland &(extlist[i]->fsys_value))) { 1182*5c51f124SMoriah Waterland mstat->attrchg = 0; 1183*5c51f124SMoriah Waterland mstat->contchg = 0; 1184*5c51f124SMoriah Waterland break; 1185*5c51f124SMoriah Waterland } 1186*5c51f124SMoriah Waterland 1187*5c51f124SMoriah Waterland if (averify(1, &ept->ftype, ept->path, 1188*5c51f124SMoriah Waterland &ept->ainfo) == 0) { 1189*5c51f124SMoriah Waterland mstat->contchg = mstat->attrchg = 0; 1190*5c51f124SMoriah Waterland } else { 1191*5c51f124SMoriah Waterland progerr(ERR_CREATE_PKGOBJ, ept->path); 1192*5c51f124SMoriah Waterland logerr(getErrbufAddr()); 1193*5c51f124SMoriah Waterland warnflag++; 1194*5c51f124SMoriah Waterland } 1195*5c51f124SMoriah Waterland 1196*5c51f124SMoriah Waterland break; 1197*5c51f124SMoriah Waterland 1198*5c51f124SMoriah Waterland case 'i': /* information file */ 1199*5c51f124SMoriah Waterland /* not treated as object "update/skip" */ 1200*5c51f124SMoriah Waterland stateFlag = B_FALSE; 1201*5c51f124SMoriah Waterland break; 1202*5c51f124SMoriah Waterland 1203*5c51f124SMoriah Waterland default: 1204*5c51f124SMoriah Waterland /* all files treated as object "update/skip" */ 1205*5c51f124SMoriah Waterland stateFlag = B_TRUE; 1206*5c51f124SMoriah Waterland break; 1207*5c51f124SMoriah Waterland } 1208*5c51f124SMoriah Waterland 1209*5c51f124SMoriah Waterland /* 1210*5c51f124SMoriah Waterland * Both contchg and shared flags have to be taken into 1211*5c51f124SMoriah Waterland * account. contchg is set if the file is already present 1212*5c51f124SMoriah Waterland * in the package database, if it does not exist or if it 1213*5c51f124SMoriah Waterland * exists and is modified. 1214*5c51f124SMoriah Waterland * The shared flag is set when 'e' or 'v' file is not 1215*5c51f124SMoriah Waterland * present in the package database, exists and is not 1216*5c51f124SMoriah Waterland * modified. It also has to be checked here. 1217*5c51f124SMoriah Waterland * Shared flag is also set when file is present in package 1218*5c51f124SMoriah Waterland * database and owned by more than one package, but for 1219*5c51f124SMoriah Waterland * this case contchg has already been set. 1220*5c51f124SMoriah Waterland */ 1221*5c51f124SMoriah Waterland if (mstat->contchg || (mstat->shared && 1222*5c51f124SMoriah Waterland ((ept->ftype == 'e') || (ept->ftype == 'v')))) { 1223*5c51f124SMoriah Waterland *dstp = ept->path; 1224*5c51f124SMoriah Waterland if ((ept->ftype == 'f') || (ept->ftype == 'e') || 1225*5c51f124SMoriah Waterland (ept->ftype == 'v')) { 1226*5c51f124SMoriah Waterland *srcp = ept->ainfo.local; 1227*5c51f124SMoriah Waterland if (is_partial_inst() != 0) { 1228*5c51f124SMoriah Waterland if (*srcp[0] == '~') { 1229*5c51f124SMoriah Waterland /* translate source pathname */ 1230*5c51f124SMoriah Waterland *srcp = srcpath(instdir, 1231*5c51f124SMoriah Waterland extlist[i]->map_path, 1232*5c51f124SMoriah Waterland part, nparts); 1233*5c51f124SMoriah Waterland } else { 1234*5c51f124SMoriah Waterland *srcp = extlist[i]->map_path; 1235*5c51f124SMoriah Waterland } 1236*5c51f124SMoriah Waterland } else { 1237*5c51f124SMoriah Waterland if (*srcp[0] == '~') { 1238*5c51f124SMoriah Waterland /* translate source pathname */ 1239*5c51f124SMoriah Waterland *srcp = srcpath(instdir, 1240*5c51f124SMoriah Waterland &(ept->ainfo.local[1]), 1241*5c51f124SMoriah Waterland part, nparts); 1242*5c51f124SMoriah Waterland } 1243*5c51f124SMoriah Waterland } 1244*5c51f124SMoriah Waterland 1245*5c51f124SMoriah Waterland echoDebug(DBG_DOMERG_NO_SUCH_FILE, 1246*5c51f124SMoriah Waterland ept->ftype, cl_nam(ept->pkg_class_idx), 1247*5c51f124SMoriah Waterland ept->path); 1248*5c51f124SMoriah Waterland } else { 1249*5c51f124SMoriah Waterland /* 1250*5c51f124SMoriah Waterland * At this point, we're returning a non-file 1251*5c51f124SMoriah Waterland * that couldn't be created in the standard 1252*5c51f124SMoriah Waterland * way. If it refers to a filesystem that is 1253*5c51f124SMoriah Waterland * not writeable by us, don't waste the 1254*5c51f124SMoriah Waterland * calling process's time. 1255*5c51f124SMoriah Waterland */ 1256*5c51f124SMoriah Waterland if (!is_fs_writeable(ept->path, 1257*5c51f124SMoriah Waterland &(extlist[i]->fsys_value))) { 1258*5c51f124SMoriah Waterland echoDebug(DBG_DOMERG_NOT_WRITABLE, 1259*5c51f124SMoriah Waterland ept->ftype, 1260*5c51f124SMoriah Waterland cl_nam(ept->pkg_class_idx), 1261*5c51f124SMoriah Waterland ept->path); 1262*5c51f124SMoriah Waterland continue; 1263*5c51f124SMoriah Waterland } 1264*5c51f124SMoriah Waterland 1265*5c51f124SMoriah Waterland *srcp = NULL; 1266*5c51f124SMoriah Waterland echoDebug(DBG_DOMERG_NOT_THERE, 1267*5c51f124SMoriah Waterland ept->ftype, cl_nam(ept->pkg_class_idx), 1268*5c51f124SMoriah Waterland ept->path); 1269*5c51f124SMoriah Waterland } 1270*5c51f124SMoriah Waterland 1271*5c51f124SMoriah Waterland svindx = i+1; 1272*5c51f124SMoriah Waterland backup(*dstp, 1); 1273*5c51f124SMoriah Waterland return (i); 1274*5c51f124SMoriah Waterland } 1275*5c51f124SMoriah Waterland 1276*5c51f124SMoriah Waterland if (mstat->attrchg) { 1277*5c51f124SMoriah Waterland backup(ept->path, 0); 1278*5c51f124SMoriah Waterland if (!msg_ugid) 1279*5c51f124SMoriah Waterland echo(MSG_ATTRIB, ept->path); 1280*5c51f124SMoriah Waterland 1281*5c51f124SMoriah Waterland /* fix the attributes now for robustness sake */ 1282*5c51f124SMoriah Waterland if (averify(1, &ept->ftype, 1283*5c51f124SMoriah Waterland ept->path, 1284*5c51f124SMoriah Waterland &ept->ainfo) == 0) { 1285*5c51f124SMoriah Waterland mstat->attrchg = 0; 1286*5c51f124SMoriah Waterland } 1287*5c51f124SMoriah Waterland } 1288*5c51f124SMoriah Waterland 1289*5c51f124SMoriah Waterland /* 1290*5c51f124SMoriah Waterland * package object exists, or does not need updating: if the path 1291*5c51f124SMoriah Waterland * is in an area inherited from the global zone, then treat 1292*5c51f124SMoriah Waterland * the object as if it were "skipped" - if the path is not in an 1293*5c51f124SMoriah Waterland * area inherited from the global zone, then treat the object as 1294*5c51f124SMoriah Waterland * if it were "updated" 1295*5c51f124SMoriah Waterland */ 1296*5c51f124SMoriah Waterland 1297*5c51f124SMoriah Waterland /* LINTED warning: statement has no consequent: if */ 1298*5c51f124SMoriah Waterland if ((stateFlag == B_FALSE) || (ept == (struct cfent *)NULL)) { 1299*5c51f124SMoriah Waterland /* 1300*5c51f124SMoriah Waterland * the object in question is a directory or special 1301*5c51f124SMoriah Waterland * file - the fact that this type of object already 1302*5c51f124SMoriah Waterland * exists or does not need updating must not trigger 1303*5c51f124SMoriah Waterland * the object updated/object skipped indication - 1304*5c51f124SMoriah Waterland * that would cause class action scripts to be run 1305*5c51f124SMoriah Waterland * when installing a new non-global zone - that action 1306*5c51f124SMoriah Waterland * must only be done when a file object that is in 1307*5c51f124SMoriah Waterland * an area inherited from the global zone is present. 1308*5c51f124SMoriah Waterland */ 1309*5c51f124SMoriah Waterland } else if (z_path_is_inherited(ept->path, ept->ftype, 1310*5c51f124SMoriah Waterland get_inst_root()) == B_TRUE) { 1311*5c51f124SMoriah Waterland if (r_skipped != (char **)NULL) { 1312*5c51f124SMoriah Waterland if (*r_skipped == (char *)NULL) { 1313*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 1314*5c51f124SMoriah Waterland ept->path); 1315*5c51f124SMoriah Waterland *r_skipped = ept->path; 1316*5c51f124SMoriah Waterland } 1317*5c51f124SMoriah Waterland } 1318*5c51f124SMoriah Waterland } else { 1319*5c51f124SMoriah Waterland if (r_updated != (char **)NULL) { 1320*5c51f124SMoriah Waterland if (*r_updated == (char *)NULL) { 1321*5c51f124SMoriah Waterland echoDebug(DBG_INSTVOL_OBJ_UPDATED, 1322*5c51f124SMoriah Waterland ept->path); 1323*5c51f124SMoriah Waterland } 1324*5c51f124SMoriah Waterland *r_updated = ept->path; 1325*5c51f124SMoriah Waterland } 1326*5c51f124SMoriah Waterland } 1327*5c51f124SMoriah Waterland } 1328*5c51f124SMoriah Waterland 1329*5c51f124SMoriah Waterland if (maxvol == part) { 1330*5c51f124SMoriah Waterland eocflag++; /* endofclass */ 1331*5c51f124SMoriah Waterland } 1332*5c51f124SMoriah Waterland 1333*5c51f124SMoriah Waterland return (DMRG_DONE); /* no remaining entries on this volume */ 1334*5c51f124SMoriah Waterland } 1335*5c51f124SMoriah Waterland 1336*5c51f124SMoriah Waterland /* 1337*5c51f124SMoriah Waterland * Determine if the provided directory is populated. Return 0 if so and 1 if 1338*5c51f124SMoriah Waterland * not. This also returns 0 if the dirpath is not a directory or if it does 1339*5c51f124SMoriah Waterland * not exist. 1340*5c51f124SMoriah Waterland */ 1341*5c51f124SMoriah Waterland static int 1342*5c51f124SMoriah Waterland dir_is_populated(char *dirpath) { 1343*5c51f124SMoriah Waterland DIR *dirfp; 1344*5c51f124SMoriah Waterland struct dirent *drp; 1345*5c51f124SMoriah Waterland int retcode = 0; 1346*5c51f124SMoriah Waterland 1347*5c51f124SMoriah Waterland if ((dirfp = opendir(dirpath)) != NULL) { 1348*5c51f124SMoriah Waterland while ((drp = readdir(dirfp)) != NULL) { 1349*5c51f124SMoriah Waterland if (strcmp(drp->d_name, ".") == 0) { 1350*5c51f124SMoriah Waterland continue; 1351*5c51f124SMoriah Waterland } 1352*5c51f124SMoriah Waterland if (strcmp(drp->d_name, "..") == 0) { 1353*5c51f124SMoriah Waterland continue; 1354*5c51f124SMoriah Waterland } 1355*5c51f124SMoriah Waterland /* 1356*5c51f124SMoriah Waterland * If we get here, there's a real file in the 1357*5c51f124SMoriah Waterland * directory 1358*5c51f124SMoriah Waterland */ 1359*5c51f124SMoriah Waterland retcode = 1; 1360*5c51f124SMoriah Waterland break; 1361*5c51f124SMoriah Waterland } 1362*5c51f124SMoriah Waterland (void) closedir(dirfp); 1363*5c51f124SMoriah Waterland } 1364*5c51f124SMoriah Waterland 1365*5c51f124SMoriah Waterland return (retcode); 1366*5c51f124SMoriah Waterland } 1367*5c51f124SMoriah Waterland 1368*5c51f124SMoriah Waterland /* 1369*5c51f124SMoriah Waterland * This is the function that cleans up the installation of this class. 1370*5c51f124SMoriah Waterland * This is where hard links get put in since the stuff they're linking 1371*5c51f124SMoriah Waterland * probably exists by now. 1372*5c51f124SMoriah Waterland */ 1373*5c51f124SMoriah Waterland static void 1374*5c51f124SMoriah Waterland endofclass(struct cfextra **extlist, int myclass, int ckflag, 1375*5c51f124SMoriah Waterland VFP_T **a_cfVfp, VFP_T **a_cfTmpVfp) 1376*5c51f124SMoriah Waterland { 1377*5c51f124SMoriah Waterland char *temppath; 1378*5c51f124SMoriah Waterland char *pspool_loc; 1379*5c51f124SMoriah Waterland char *relocpath = (char *)NULL; 1380*5c51f124SMoriah Waterland char scrpt_dst[PATH_MAX]; 1381*5c51f124SMoriah Waterland int flag; 1382*5c51f124SMoriah Waterland int idx; 1383*5c51f124SMoriah Waterland int n; 1384*5c51f124SMoriah Waterland struct cfent *ept; /* entry from the internal list */ 1385*5c51f124SMoriah Waterland struct cfextra entry; /* entry from the package database */ 1386*5c51f124SMoriah Waterland struct mergstat *mstat; /* merge status */ 1387*5c51f124SMoriah Waterland struct pinfo *pinfo; 1388*5c51f124SMoriah Waterland 1389*5c51f124SMoriah Waterland /* open the package database (contents) file */ 1390*5c51f124SMoriah Waterland 1391*5c51f124SMoriah Waterland if (!ocfile(a_cfVfp, a_cfTmpVfp, pkgmap_blks)) { 1392*5c51f124SMoriah Waterland quit(99); 1393*5c51f124SMoriah Waterland } 1394*5c51f124SMoriah Waterland 1395*5c51f124SMoriah Waterland echo(MSG_VERIFYING_CLASS, cl_nam(myclass)); 1396*5c51f124SMoriah Waterland 1397*5c51f124SMoriah Waterland for (idx = 0; /* void */; idx++) { 1398*5c51f124SMoriah Waterland /* find next package object in this class */ 1399*5c51f124SMoriah Waterland while (extlist[idx]) { 1400*5c51f124SMoriah Waterland if ((extlist[idx]->cf_ent.ftype != 'i') && 1401*5c51f124SMoriah Waterland extlist[idx]->cf_ent.pkg_class_idx == myclass) { 1402*5c51f124SMoriah Waterland break; 1403*5c51f124SMoriah Waterland } 1404*5c51f124SMoriah Waterland idx++; 1405*5c51f124SMoriah Waterland } 1406*5c51f124SMoriah Waterland 1407*5c51f124SMoriah Waterland if (extlist[idx] == NULL) { 1408*5c51f124SMoriah Waterland /* finish copying contents file and exit loop */ 1409*5c51f124SMoriah Waterland (void) srchcfile(&(entry.cf_ent), NULL, 1410*5c51f124SMoriah Waterland *a_cfVfp, *a_cfTmpVfp); 1411*5c51f124SMoriah Waterland break; 1412*5c51f124SMoriah Waterland } 1413*5c51f124SMoriah Waterland 1414*5c51f124SMoriah Waterland ept = &(extlist[idx]->cf_ent); 1415*5c51f124SMoriah Waterland mstat = &(extlist[idx]->mstat); 1416*5c51f124SMoriah Waterland 1417*5c51f124SMoriah Waterland temppath = 1418*5c51f124SMoriah Waterland extlist[idx] ? extlist[idx]->client_path : 1419*5c51f124SMoriah Waterland NULL; 1420*5c51f124SMoriah Waterland 1421*5c51f124SMoriah Waterland /* 1422*5c51f124SMoriah Waterland * At this point the only difference between the entry 1423*5c51f124SMoriah Waterland * in the contents file and the entry in extlist[] is 1424*5c51f124SMoriah Waterland * that the status indicator contains CONFIRM_CONT. 1425*5c51f124SMoriah Waterland * So for the new DB we use this knowledge and just 1426*5c51f124SMoriah Waterland * verify everything in accordance with extlist without 1427*5c51f124SMoriah Waterland * trying to retrieve the entry from the DB. 1428*5c51f124SMoriah Waterland */ 1429*5c51f124SMoriah Waterland 1430*5c51f124SMoriah Waterland n = srchcfile(&(entry.cf_ent), 1431*5c51f124SMoriah Waterland (ept ? temppath : NULL), *a_cfVfp, *a_cfTmpVfp); 1432*5c51f124SMoriah Waterland 1433*5c51f124SMoriah Waterland if (n == 0) { 1434*5c51f124SMoriah Waterland break; 1435*5c51f124SMoriah Waterland } else if (n < 0) { 1436*5c51f124SMoriah Waterland char *errstr = getErrstr(); 1437*5c51f124SMoriah Waterland progerr(ERR_CFBAD); 1438*5c51f124SMoriah Waterland logerr(gettext("pathname=%s\n"), 1439*5c51f124SMoriah Waterland entry.cf_ent.path && *entry.cf_ent.path ? 1440*5c51f124SMoriah Waterland entry.cf_ent.path : "Unknown"); 1441*5c51f124SMoriah Waterland logerr(gettext("problem=%s\n"), 1442*5c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 1443*5c51f124SMoriah Waterland quit(99); 1444*5c51f124SMoriah Waterland } else if (n != 1) { 1445*5c51f124SMoriah Waterland /* 1446*5c51f124SMoriah Waterland * Check if path should be in the package 1447*5c51f124SMoriah Waterland * database. 1448*5c51f124SMoriah Waterland */ 1449*5c51f124SMoriah Waterland if ((mstat->shared && nocnflct)) { 1450*5c51f124SMoriah Waterland continue; 1451*5c51f124SMoriah Waterland } 1452*5c51f124SMoriah Waterland progerr(ERR_CFMISSING, ept->path); 1453*5c51f124SMoriah Waterland quit(99); 1454*5c51f124SMoriah Waterland } 1455*5c51f124SMoriah Waterland 1456*5c51f124SMoriah Waterland /* 1457*5c51f124SMoriah Waterland * If merge was not appropriate for this object, now is the 1458*5c51f124SMoriah Waterland * time to choose one or the other. 1459*5c51f124SMoriah Waterland */ 1460*5c51f124SMoriah Waterland if (mstat->denied) { 1461*5c51f124SMoriah Waterland /* 1462*5c51f124SMoriah Waterland * If installation was denied AFTER the package 1463*5c51f124SMoriah Waterland * database was updated, skip this. We've already 1464*5c51f124SMoriah Waterland * announced the discrepancy and the verifications 1465*5c51f124SMoriah Waterland * that follow will make faulty decisions based on 1466*5c51f124SMoriah Waterland * the ftype, which may not be correct. 1467*5c51f124SMoriah Waterland */ 1468*5c51f124SMoriah Waterland progerr(ERR_COULD_NOT_INSTALL, ept->path); 1469*5c51f124SMoriah Waterland warnflag++; 1470*5c51f124SMoriah Waterland } else { 1471*5c51f124SMoriah Waterland if (mstat->replace) 1472*5c51f124SMoriah Waterland /* 1473*5c51f124SMoriah Waterland * This replaces the old entry with the new 1474*5c51f124SMoriah Waterland * one. This should never happen in the new 1475*5c51f124SMoriah Waterland * DB since the entries are already identical. 1476*5c51f124SMoriah Waterland */ 1477*5c51f124SMoriah Waterland repl_cfent(ept, &(entry.cf_ent)); 1478*5c51f124SMoriah Waterland 1479*5c51f124SMoriah Waterland /* 1480*5c51f124SMoriah Waterland * Validate this entry and change the status flag in 1481*5c51f124SMoriah Waterland * the package database. 1482*5c51f124SMoriah Waterland */ 1483*5c51f124SMoriah Waterland if (ept->ftype == RM_RDY) { 1484*5c51f124SMoriah Waterland (void) eptstat(&(entry.cf_ent), pkginst, 1485*5c51f124SMoriah Waterland STAT_NEXT); 1486*5c51f124SMoriah Waterland } else { 1487*5c51f124SMoriah Waterland /* check the hard link now. */ 1488*5c51f124SMoriah Waterland if (ept->ftype == 'l') { 1489*5c51f124SMoriah Waterland if (averify(0, &ept->ftype, 1490*5c51f124SMoriah Waterland ept->path, &ept->ainfo)) { 1491*5c51f124SMoriah Waterland echo(MSG_HRDLINK, 1492*5c51f124SMoriah Waterland ept->path); 1493*5c51f124SMoriah Waterland mstat->attrchg++; 1494*5c51f124SMoriah Waterland } 1495*5c51f124SMoriah Waterland } 1496*5c51f124SMoriah Waterland 1497*5c51f124SMoriah Waterland /* 1498*5c51f124SMoriah Waterland * Don't install or verify objects for 1499*5c51f124SMoriah Waterland * remote, read-only filesystems. We need 1500*5c51f124SMoriah Waterland * only flag them as shared from some server. 1501*5c51f124SMoriah Waterland * Otherwise, ok to do final check. 1502*5c51f124SMoriah Waterland */ 1503*5c51f124SMoriah Waterland if (is_remote_fs(ept->path, 1504*5c51f124SMoriah Waterland &(extlist[idx]->fsys_value)) && 1505*5c51f124SMoriah Waterland !is_fs_writeable(ept->path, 1506*5c51f124SMoriah Waterland &(extlist[idx]->fsys_value))) { 1507*5c51f124SMoriah Waterland flag = -1; 1508*5c51f124SMoriah Waterland } else { 1509*5c51f124SMoriah Waterland boolean_t inheritedFlag; 1510*5c51f124SMoriah Waterland inheritedFlag = 1511*5c51f124SMoriah Waterland z_path_is_inherited(ept->path, 1512*5c51f124SMoriah Waterland ept->ftype, get_inst_root()); 1513*5c51f124SMoriah Waterland flag = finalck(ept, mstat->attrchg, 1514*5c51f124SMoriah Waterland (ckflag ? mstat->contchg : 1515*5c51f124SMoriah Waterland (-1)), inheritedFlag); 1516*5c51f124SMoriah Waterland } 1517*5c51f124SMoriah Waterland 1518*5c51f124SMoriah Waterland pinfo = entry.cf_ent.pinfo; 1519*5c51f124SMoriah Waterland 1520*5c51f124SMoriah Waterland /* Find this package in the list. */ 1521*5c51f124SMoriah Waterland while (pinfo) { 1522*5c51f124SMoriah Waterland if (strcmp(pkginst, pinfo->pkg) == 0) { 1523*5c51f124SMoriah Waterland break; 1524*5c51f124SMoriah Waterland } 1525*5c51f124SMoriah Waterland pinfo = pinfo->next; 1526*5c51f124SMoriah Waterland } 1527*5c51f124SMoriah Waterland 1528*5c51f124SMoriah Waterland /* 1529*5c51f124SMoriah Waterland * If this package owns this file, then store 1530*5c51f124SMoriah Waterland * it in the database with the appropriate 1531*5c51f124SMoriah Waterland * status. Need to check pinfo in case it 1532*5c51f124SMoriah Waterland * points to NULL which could happen if 1533*5c51f124SMoriah Waterland * pinfo->next = NULL above. 1534*5c51f124SMoriah Waterland */ 1535*5c51f124SMoriah Waterland if (pinfo) { 1536*5c51f124SMoriah Waterland if (flag < 0 || is_served(ept->path, 1537*5c51f124SMoriah Waterland &(extlist[idx]->fsys_value))) { 1538*5c51f124SMoriah Waterland /* 1539*5c51f124SMoriah Waterland * This is provided to 1540*5c51f124SMoriah Waterland * clients by a server. 1541*5c51f124SMoriah Waterland */ 1542*5c51f124SMoriah Waterland pinfo->status = SERVED_FILE; 1543*5c51f124SMoriah Waterland } else { 1544*5c51f124SMoriah Waterland /* 1545*5c51f124SMoriah Waterland * It's either there or it's 1546*5c51f124SMoriah Waterland * not. 1547*5c51f124SMoriah Waterland */ 1548*5c51f124SMoriah Waterland pinfo->status = (flag ? 1549*5c51f124SMoriah Waterland NOT_FND : ENTRY_OK); 1550*5c51f124SMoriah Waterland } 1551*5c51f124SMoriah Waterland } 1552*5c51f124SMoriah Waterland } 1553*5c51f124SMoriah Waterland } 1554*5c51f124SMoriah Waterland 1555*5c51f124SMoriah Waterland /* 1556*5c51f124SMoriah Waterland * If not installing from a partially spooled package, the 1557*5c51f124SMoriah Waterland * "save/pspool" area, and the file contents can be 1558*5c51f124SMoriah Waterland * changed (type is 'e' or 'v'), and the class IS "none": 1559*5c51f124SMoriah Waterland * copy the installed volatile file into the appropriate 1560*5c51f124SMoriah Waterland * location in the packages destination "save/pspool" area. 1561*5c51f124SMoriah Waterland */ 1562*5c51f124SMoriah Waterland 1563*5c51f124SMoriah Waterland if ((!is_partial_inst()) && 1564*5c51f124SMoriah Waterland ((ept->ftype == 'e') || (ept->ftype == 'v')) && 1565*5c51f124SMoriah Waterland (strcmp(ept->pkg_class, "none") == 0)) { 1566*5c51f124SMoriah Waterland 1567*5c51f124SMoriah Waterland if (absolutepath(extlist[idx]->map_path) == B_TRUE && 1568*5c51f124SMoriah Waterland parametricpath(extlist[idx]->cf_ent.ainfo.local, 1569*5c51f124SMoriah Waterland &relocpath) == B_FALSE) { 1570*5c51f124SMoriah Waterland pspool_loc = ROOT; 1571*5c51f124SMoriah Waterland } else { 1572*5c51f124SMoriah Waterland pspool_loc = RELOC; 1573*5c51f124SMoriah Waterland } 1574*5c51f124SMoriah Waterland 1575*5c51f124SMoriah Waterland n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 1576*5c51f124SMoriah Waterland saveSpoolInstallDir, pspool_loc, 1577*5c51f124SMoriah Waterland relocpath ? relocpath : extlist[idx]->map_path); 1578*5c51f124SMoriah Waterland 1579*5c51f124SMoriah Waterland if (n >= PATH_MAX) { 1580*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, 1581*5c51f124SMoriah Waterland saveSpoolInstallDir, 1582*5c51f124SMoriah Waterland extlist[idx]->map_path); 1583*5c51f124SMoriah Waterland quit(99); 1584*5c51f124SMoriah Waterland } 1585*5c51f124SMoriah Waterland 1586*5c51f124SMoriah Waterland /* copy, preserve source file mode */ 1587*5c51f124SMoriah Waterland 1588*5c51f124SMoriah Waterland if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) { 1589*5c51f124SMoriah Waterland warnflag++; 1590*5c51f124SMoriah Waterland } 1591*5c51f124SMoriah Waterland } 1592*5c51f124SMoriah Waterland 1593*5c51f124SMoriah Waterland /* 1594*5c51f124SMoriah Waterland * Now insert this potentially changed package database 1595*5c51f124SMoriah Waterland * entry. 1596*5c51f124SMoriah Waterland */ 1597*5c51f124SMoriah Waterland if (entry.cf_ent.npkgs) { 1598*5c51f124SMoriah Waterland if (putcvfpfile(&(entry.cf_ent), *a_cfTmpVfp)) { 1599*5c51f124SMoriah Waterland quit(99); 1600*5c51f124SMoriah Waterland } 1601*5c51f124SMoriah Waterland } 1602*5c51f124SMoriah Waterland } 1603*5c51f124SMoriah Waterland 1604*5c51f124SMoriah Waterland n = swapcfile(a_cfVfp, a_cfTmpVfp, pkginst, dbchg); 1605*5c51f124SMoriah Waterland if (n == RESULT_WRN) { 1606*5c51f124SMoriah Waterland warnflag++; 1607*5c51f124SMoriah Waterland } else if (n == RESULT_ERR) { 1608*5c51f124SMoriah Waterland quit(99); 1609*5c51f124SMoriah Waterland } 1610*5c51f124SMoriah Waterland } 1611*5c51f124SMoriah Waterland 1612*5c51f124SMoriah Waterland /* 1613*5c51f124SMoriah Waterland * This function goes through and fixes all the attributes. This is called 1614*5c51f124SMoriah Waterland * out by using DST_QKVERIFY=this_class in the pkginfo file. The primary 1615*5c51f124SMoriah Waterland * use for this is to fix up files installed by a class action script 1616*5c51f124SMoriah Waterland * which is time-critical and reliable enough to assume likely success. 1617*5c51f124SMoriah Waterland * The first such format was for WOS compressed-cpio'd file sets. 1618*5c51f124SMoriah Waterland * The second format is the Class Archive Format. 1619*5c51f124SMoriah Waterland */ 1620*5c51f124SMoriah Waterland static int 1621*5c51f124SMoriah Waterland fix_attributes(struct cfextra **extlist, int idx) 1622*5c51f124SMoriah Waterland { 1623*5c51f124SMoriah Waterland struct cfextra *ext; 1624*5c51f124SMoriah Waterland int i, retval = 1; 1625*5c51f124SMoriah Waterland int nc = cl_getn(); 1626*5c51f124SMoriah Waterland int n; 1627*5c51f124SMoriah Waterland struct cfent *ept; 1628*5c51f124SMoriah Waterland struct mergstat *mstat; 1629*5c51f124SMoriah Waterland char scrpt_dst[PATH_MAX]; 1630*5c51f124SMoriah Waterland char *pspool_loc; 1631*5c51f124SMoriah Waterland char *relocpath = (char *)NULL; 1632*5c51f124SMoriah Waterland 1633*5c51f124SMoriah Waterland for (i = 0; extlist[i]; i++) { 1634*5c51f124SMoriah Waterland ext = extlist[i]; 1635*5c51f124SMoriah Waterland ept = &(extlist[i]->cf_ent); 1636*5c51f124SMoriah Waterland mstat = &(extlist[i]->mstat); 1637*5c51f124SMoriah Waterland 1638*5c51f124SMoriah Waterland /* 1639*5c51f124SMoriah Waterland * We don't care about 'i'nfo files because, they 1640*5c51f124SMoriah Waterland * aren't laid down, 'e'ditable files can change 1641*5c51f124SMoriah Waterland * anyway, so who cares and 's'ymlinks were already 1642*5c51f124SMoriah Waterland * fixed in domerg(); however, certain old WOS 1643*5c51f124SMoriah Waterland * package symlinks depend on a bug in the old 1644*5c51f124SMoriah Waterland * pkgadd which has recently been expunged. For 1645*5c51f124SMoriah Waterland * those packages in 2.2, we repeat the verification 1646*5c51f124SMoriah Waterland * of symlinks. 1647*5c51f124SMoriah Waterland * 1648*5c51f124SMoriah Waterland * By 2.6 or so, ftype == 's' should be added to this. 1649*5c51f124SMoriah Waterland */ 1650*5c51f124SMoriah Waterland if (ept->ftype == 'i' || ept->ftype == 'e' || 1651*5c51f124SMoriah Waterland (mstat->shared && nocnflct)) 1652*5c51f124SMoriah Waterland continue; 1653*5c51f124SMoriah Waterland 1654*5c51f124SMoriah Waterland if (mstat->denied) { 1655*5c51f124SMoriah Waterland progerr(ERR_COULD_NOT_INSTALL, ept->path); 1656*5c51f124SMoriah Waterland warnflag++; 1657*5c51f124SMoriah Waterland continue; 1658*5c51f124SMoriah Waterland } 1659*5c51f124SMoriah Waterland 1660*5c51f124SMoriah Waterland if (ept->pkg_class_idx < 0 || ept->pkg_class_idx > nc) { 1661*5c51f124SMoriah Waterland progerr(ERR_CLIDX, ept->pkg_class_idx, 1662*5c51f124SMoriah Waterland (ept->path && *ept->path) ? ept->path : "unknown"); 1663*5c51f124SMoriah Waterland continue; 1664*5c51f124SMoriah Waterland } 1665*5c51f124SMoriah Waterland 1666*5c51f124SMoriah Waterland /* If this is the right class, do the fast verify. */ 1667*5c51f124SMoriah Waterland if (ept->pkg_class_idx == idx) { 1668*5c51f124SMoriah Waterland if (fverify(1, &ept->ftype, ept->path, 1669*5c51f124SMoriah Waterland &ept->ainfo, &ept->cinfo) == 0) { 1670*5c51f124SMoriah Waterland mstat->attrchg = 0; 1671*5c51f124SMoriah Waterland mstat->contchg = 0; 1672*5c51f124SMoriah Waterland } else /* We'll try full verify later */ 1673*5c51f124SMoriah Waterland retval = 0; 1674*5c51f124SMoriah Waterland } 1675*5c51f124SMoriah Waterland /* 1676*5c51f124SMoriah Waterland * Need to copy the installed volitale file back to the 1677*5c51f124SMoriah Waterland * partial spooled area if we are installing to a local zone 1678*5c51f124SMoriah Waterland * or similar installation method. 1679*5c51f124SMoriah Waterland */ 1680*5c51f124SMoriah Waterland 1681*5c51f124SMoriah Waterland if ((!is_partial_inst()) && 1682*5c51f124SMoriah Waterland ((ept->ftype == 'e') || (ept->ftype == 'v')) && 1683*5c51f124SMoriah Waterland (strcmp(ept->pkg_class, "none") == 0)) { 1684*5c51f124SMoriah Waterland 1685*5c51f124SMoriah Waterland if (absolutepath(ext->map_path) == B_TRUE && 1686*5c51f124SMoriah Waterland parametricpath(ext->cf_ent.ainfo.local, 1687*5c51f124SMoriah Waterland &relocpath) == B_FALSE) { 1688*5c51f124SMoriah Waterland pspool_loc = ROOT; 1689*5c51f124SMoriah Waterland } else { 1690*5c51f124SMoriah Waterland pspool_loc = RELOC; 1691*5c51f124SMoriah Waterland } 1692*5c51f124SMoriah Waterland 1693*5c51f124SMoriah Waterland n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 1694*5c51f124SMoriah Waterland saveSpoolInstallDir, pspool_loc, 1695*5c51f124SMoriah Waterland relocpath ? relocpath : ext->map_path); 1696*5c51f124SMoriah Waterland 1697*5c51f124SMoriah Waterland if (n >= PATH_MAX) { 1698*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, 1699*5c51f124SMoriah Waterland saveSpoolInstallDir, 1700*5c51f124SMoriah Waterland ext->map_path); 1701*5c51f124SMoriah Waterland quit(99); 1702*5c51f124SMoriah Waterland } 1703*5c51f124SMoriah Waterland 1704*5c51f124SMoriah Waterland /* copy, preserve source file mode */ 1705*5c51f124SMoriah Waterland 1706*5c51f124SMoriah Waterland if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) { 1707*5c51f124SMoriah Waterland warnflag++; 1708*5c51f124SMoriah Waterland } 1709*5c51f124SMoriah Waterland } 1710*5c51f124SMoriah Waterland } 1711*5c51f124SMoriah Waterland 1712*5c51f124SMoriah Waterland return (retval); 1713*5c51f124SMoriah Waterland } 1714*5c51f124SMoriah Waterland 1715*5c51f124SMoriah Waterland /* 1716*5c51f124SMoriah Waterland * Check to see if first charcter in path is a '/'. 1717*5c51f124SMoriah Waterland * 1718*5c51f124SMoriah Waterland * Return: 1719*5c51f124SMoriah Waterland * B_TRUE - if path is prepended with '/' 1720*5c51f124SMoriah Waterland * B_FALSE - if not 1721*5c51f124SMoriah Waterland */ 1722*5c51f124SMoriah Waterland static boolean_t 1723*5c51f124SMoriah Waterland absolutepath(char *path) 1724*5c51f124SMoriah Waterland { 1725*5c51f124SMoriah Waterland assert(path != NULL); 1726*5c51f124SMoriah Waterland assert(path[0] != '\0'); 1727*5c51f124SMoriah Waterland 1728*5c51f124SMoriah Waterland return (path[0] == '/' ? B_TRUE : B_FALSE); 1729*5c51f124SMoriah Waterland } 1730*5c51f124SMoriah Waterland 1731*5c51f124SMoriah Waterland /* 1732*5c51f124SMoriah Waterland * Check to see if path contains a '$' which makes it 1733*5c51f124SMoriah Waterland * a parametric path and therefore relocatable. 1734*5c51f124SMoriah Waterland * 1735*5c51f124SMoriah Waterland * Parameters: 1736*5c51f124SMoriah Waterland * path - The path to determine if it is absolute 1737*5c51f124SMoriah Waterland * relocpath - The value of the unconditioned path 1738*5c51f124SMoriah Waterland * i.e. $OPTDIR/usr/ls 1739*5c51f124SMoriah Waterland * Return: 1740*5c51f124SMoriah Waterland * B_TRUE - if path is a parametric path 1741*5c51f124SMoriah Waterland * B_FALSE - if not 1742*5c51f124SMoriah Waterland */ 1743*5c51f124SMoriah Waterland static boolean_t 1744*5c51f124SMoriah Waterland parametricpath(char *path, char **relocpath) 1745*5c51f124SMoriah Waterland { 1746*5c51f124SMoriah Waterland assert(path != NULL); 1747*5c51f124SMoriah Waterland assert(path[0] != '\0'); 1748*5c51f124SMoriah Waterland 1749*5c51f124SMoriah Waterland /* 1750*5c51f124SMoriah Waterland * If this is a valid parametric path then a '$' MUST occur at the 1751*5c51f124SMoriah Waterland * first or second character. 1752*5c51f124SMoriah Waterland */ 1753*5c51f124SMoriah Waterland 1754*5c51f124SMoriah Waterland if (path[0] == '$' || path[1] == '$') { 1755*5c51f124SMoriah Waterland /* 1756*5c51f124SMoriah Waterland * If a parametric path exists then when copying the 1757*5c51f124SMoriah Waterland * path to the pspool directoy from the installing 1758*5c51f124SMoriah Waterland * pkgs reloc directory we want to use the uncononditional 1759*5c51f124SMoriah Waterland * varaiable path. 1760*5c51f124SMoriah Waterland */ 1761*5c51f124SMoriah Waterland *relocpath = (path + 1); 1762*5c51f124SMoriah Waterland return (B_TRUE); 1763*5c51f124SMoriah Waterland } 1764*5c51f124SMoriah Waterland return (B_FALSE); 1765*5c51f124SMoriah Waterland } 1766*5c51f124SMoriah Waterland 1767*5c51f124SMoriah Waterland void 1768*5c51f124SMoriah Waterland regfiles_free() 1769*5c51f124SMoriah Waterland { 1770*5c51f124SMoriah Waterland if (regfiles_head != NULL) { 1771*5c51f124SMoriah Waterland struct reg_files *rfp = regfiles_head->next; 1772*5c51f124SMoriah Waterland 1773*5c51f124SMoriah Waterland while (rfp != NULL) { 1774*5c51f124SMoriah Waterland free(regfiles_head); 1775*5c51f124SMoriah Waterland regfiles_head = rfp; 1776*5c51f124SMoriah Waterland rfp = regfiles_head->next; 1777*5c51f124SMoriah Waterland } 1778*5c51f124SMoriah Waterland free(regfiles_head); 1779*5c51f124SMoriah Waterland regfiles_head = NULL; 1780*5c51f124SMoriah Waterland } 1781*5c51f124SMoriah Waterland } 1782