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