19781SMoriah.Waterland@Sun.COM /* 29781SMoriah.Waterland@Sun.COM * CDDL HEADER START 39781SMoriah.Waterland@Sun.COM * 49781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 59781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 69781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 79781SMoriah.Waterland@Sun.COM * 89781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 109781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 119781SMoriah.Waterland@Sun.COM * and limitations under the License. 129781SMoriah.Waterland@Sun.COM * 139781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 149781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 169781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 179781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 189781SMoriah.Waterland@Sun.COM * 199781SMoriah.Waterland@Sun.COM * CDDL HEADER END 209781SMoriah.Waterland@Sun.COM */ 219781SMoriah.Waterland@Sun.COM 229781SMoriah.Waterland@Sun.COM /* 239781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 249781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 259781SMoriah.Waterland@Sun.COM */ 269781SMoriah.Waterland@Sun.COM 279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 299781SMoriah.Waterland@Sun.COM 309781SMoriah.Waterland@Sun.COM 319781SMoriah.Waterland@Sun.COM #include <stdio.h> 329781SMoriah.Waterland@Sun.COM #include <string.h> 339781SMoriah.Waterland@Sun.COM #include <locale.h> 349781SMoriah.Waterland@Sun.COM #include <libintl.h> 359781SMoriah.Waterland@Sun.COM #include <dirent.h> 369781SMoriah.Waterland@Sun.COM #include <pkgstrct.h> 379781SMoriah.Waterland@Sun.COM #include <pkgdev.h> 389781SMoriah.Waterland@Sun.COM #include <pkglocs.h> 399781SMoriah.Waterland@Sun.COM #include <archives.h> 409781SMoriah.Waterland@Sun.COM #include <errno.h> 419781SMoriah.Waterland@Sun.COM #include <fcntl.h> 429781SMoriah.Waterland@Sun.COM #include <sys/stat.h> 439781SMoriah.Waterland@Sun.COM #include <sys/param.h> 449781SMoriah.Waterland@Sun.COM #include <stdlib.h> 459781SMoriah.Waterland@Sun.COM #include <unistd.h> 469781SMoriah.Waterland@Sun.COM #include <assert.h> 479781SMoriah.Waterland@Sun.COM #include <wait.h> 489781SMoriah.Waterland@Sun.COM 499781SMoriah.Waterland@Sun.COM /* 509781SMoriah.Waterland@Sun.COM * libinstzones includes 519781SMoriah.Waterland@Sun.COM */ 529781SMoriah.Waterland@Sun.COM 539781SMoriah.Waterland@Sun.COM #include <instzones_api.h> 549781SMoriah.Waterland@Sun.COM 559781SMoriah.Waterland@Sun.COM /* 569781SMoriah.Waterland@Sun.COM * consolidation pkg command library includes 579781SMoriah.Waterland@Sun.COM */ 589781SMoriah.Waterland@Sun.COM 599781SMoriah.Waterland@Sun.COM #include <pkglib.h> 609781SMoriah.Waterland@Sun.COM #include <pkgweb.h> 619781SMoriah.Waterland@Sun.COM 629781SMoriah.Waterland@Sun.COM /* 639781SMoriah.Waterland@Sun.COM * local pkg command library includes 649781SMoriah.Waterland@Sun.COM */ 659781SMoriah.Waterland@Sun.COM 669781SMoriah.Waterland@Sun.COM #include <install.h> 679781SMoriah.Waterland@Sun.COM #include <libinst.h> 689781SMoriah.Waterland@Sun.COM #include <libadm.h> 699781SMoriah.Waterland@Sun.COM #include <dryrun.h> 709781SMoriah.Waterland@Sun.COM #include <messages.h> 719781SMoriah.Waterland@Sun.COM 729781SMoriah.Waterland@Sun.COM /* 739781SMoriah.Waterland@Sun.COM * pkginstall local includes 749781SMoriah.Waterland@Sun.COM */ 759781SMoriah.Waterland@Sun.COM 769781SMoriah.Waterland@Sun.COM #include "pkginstall.h" 779781SMoriah.Waterland@Sun.COM 789781SMoriah.Waterland@Sun.COM extern int pkgverbose; 799781SMoriah.Waterland@Sun.COM extern fsblkcnt_t pkgmap_blks; /* main.c */ 809781SMoriah.Waterland@Sun.COM 819781SMoriah.Waterland@Sun.COM extern struct pkgdev pkgdev; 829781SMoriah.Waterland@Sun.COM 839781SMoriah.Waterland@Sun.COM extern char tmpdir[]; 849781SMoriah.Waterland@Sun.COM extern char pkgbin[]; 859781SMoriah.Waterland@Sun.COM extern char instdir[]; 869781SMoriah.Waterland@Sun.COM extern char saveSpoolInstallDir[]; 879781SMoriah.Waterland@Sun.COM extern char *pkginst; 889781SMoriah.Waterland@Sun.COM 899781SMoriah.Waterland@Sun.COM extern int dbchg; 909781SMoriah.Waterland@Sun.COM extern int nosetuid; 919781SMoriah.Waterland@Sun.COM extern int nocnflct; 929781SMoriah.Waterland@Sun.COM extern int warnflag; 939781SMoriah.Waterland@Sun.COM 949781SMoriah.Waterland@Sun.COM #define DMRG_DONE -1 959781SMoriah.Waterland@Sun.COM 969781SMoriah.Waterland@Sun.COM #define ck_efile(s, p) \ 979781SMoriah.Waterland@Sun.COM ((p->cinfo.modtime >= 0) && \ 989781SMoriah.Waterland@Sun.COM p->ainfo.local && \ 999781SMoriah.Waterland@Sun.COM cverify(0, &p->ftype, s, &p->cinfo, 1)) 1009781SMoriah.Waterland@Sun.COM 1019781SMoriah.Waterland@Sun.COM static int eocflag; 1029781SMoriah.Waterland@Sun.COM 1039781SMoriah.Waterland@Sun.COM /* 1049781SMoriah.Waterland@Sun.COM * The variable below indicates that fix_attributes() will be inadequate 1059781SMoriah.Waterland@Sun.COM * because a replacement was permitted. 1069781SMoriah.Waterland@Sun.COM */ 1079781SMoriah.Waterland@Sun.COM static int repl_permitted = 0; 1089781SMoriah.Waterland@Sun.COM 1099781SMoriah.Waterland@Sun.COM static int domerg(struct cfextra **extlist, int part, int nparts, 1109781SMoriah.Waterland@Sun.COM int myclass, char **srcp, char **dstp, 1119781SMoriah.Waterland@Sun.COM char **r_updated, char **r_skipped, 1129781SMoriah.Waterland@Sun.COM char **r_anyPathLocal); 1139781SMoriah.Waterland@Sun.COM static void endofclass(struct cfextra **extlist, int myclass, 114*9869SCasper.Dik@Sun.COM int ckflag, PKGserver server, VFP_T **a_cfTmpVfp); 1159781SMoriah.Waterland@Sun.COM static int fix_attributes(struct cfextra **, int); 1169781SMoriah.Waterland@Sun.COM static int dir_is_populated(char *dirpath); 1179781SMoriah.Waterland@Sun.COM static boolean_t absolutepath(char *path); 1189781SMoriah.Waterland@Sun.COM static boolean_t parametricpath(char *path, char **relocpath); 1199781SMoriah.Waterland@Sun.COM 1209781SMoriah.Waterland@Sun.COM /* Used to keep track of the entries in extlist that are regular files. */ 1219781SMoriah.Waterland@Sun.COM struct reg_files { 1229781SMoriah.Waterland@Sun.COM struct reg_files *next; 1239781SMoriah.Waterland@Sun.COM int val; 1249781SMoriah.Waterland@Sun.COM }; 1259781SMoriah.Waterland@Sun.COM static struct reg_files *regfiles_head = NULL; 1269781SMoriah.Waterland@Sun.COM 1279781SMoriah.Waterland@Sun.COM /* 1289781SMoriah.Waterland@Sun.COM * This is the function that actually installs one volume (usually that's 1299781SMoriah.Waterland@Sun.COM * all there is). Upon entry, the extlist is entirely correct: 1309781SMoriah.Waterland@Sun.COM * 1319781SMoriah.Waterland@Sun.COM * 1. It contains only those files which are to be installed 1329781SMoriah.Waterland@Sun.COM * from all volumes. 1339781SMoriah.Waterland@Sun.COM * 2. The mode bits in the ainfo structure for each file are set 1349781SMoriah.Waterland@Sun.COM * correctly in accordance with administrative defaults. 1359781SMoriah.Waterland@Sun.COM * 3. mstat.setuid/setgid reflect what the status *was* before 1369781SMoriah.Waterland@Sun.COM * pkgdbmerg() processed compliance. 1379781SMoriah.Waterland@Sun.COM */ 1389781SMoriah.Waterland@Sun.COM void 1399781SMoriah.Waterland@Sun.COM instvol(struct cfextra **extlist, char *srcinst, int part, 140*9869SCasper.Dik@Sun.COM int nparts, PKGserver pkgserver, VFP_T **a_cfTmpVfp, 1419781SMoriah.Waterland@Sun.COM char **r_updated, char **r_skipped, 1429781SMoriah.Waterland@Sun.COM char *a_zoneName) 1439781SMoriah.Waterland@Sun.COM { 1449781SMoriah.Waterland@Sun.COM FILE *listfp; 1459781SMoriah.Waterland@Sun.COM char *updated = (char *)NULL; 1469781SMoriah.Waterland@Sun.COM char *skipped = (char *)NULL; 1479781SMoriah.Waterland@Sun.COM char *anyPathLocal = (char *)NULL; 1489781SMoriah.Waterland@Sun.COM char *relocpath = (char *)NULL; 1499781SMoriah.Waterland@Sun.COM char *dstp; 1509781SMoriah.Waterland@Sun.COM char *listfile; 1519781SMoriah.Waterland@Sun.COM char *srcp; 1529781SMoriah.Waterland@Sun.COM char *pspool_loc; 1539781SMoriah.Waterland@Sun.COM char scrpt_dst[PATH_MAX]; 1549781SMoriah.Waterland@Sun.COM int count; 1559781SMoriah.Waterland@Sun.COM int entryidx; /* array of current package objects */ 1569781SMoriah.Waterland@Sun.COM int n; 1579781SMoriah.Waterland@Sun.COM int nc = 0; 1589781SMoriah.Waterland@Sun.COM int pass; /* pass count through the for loop. */ 1599781SMoriah.Waterland@Sun.COM int tcount; 1609781SMoriah.Waterland@Sun.COM struct cfent *ept; 1619781SMoriah.Waterland@Sun.COM struct cfextra *ext; 1629781SMoriah.Waterland@Sun.COM struct mergstat *mstat; 1639781SMoriah.Waterland@Sun.COM struct reg_files *rfp = NULL; 1649781SMoriah.Waterland@Sun.COM 1659781SMoriah.Waterland@Sun.COM /* 1669781SMoriah.Waterland@Sun.COM * r_updated and r_skipped are optional parameters that can be passed in 1679781SMoriah.Waterland@Sun.COM * by the caller if the caller wants to know if any objects are either 1689781SMoriah.Waterland@Sun.COM * updated or skipped. Do not initialize either r_updated or r_skipped; 1699781SMoriah.Waterland@Sun.COM * the call to instvol could be cumulative and any previous update or 1709781SMoriah.Waterland@Sun.COM * skipped indication must not be disturbed - these flags are only set, 1719781SMoriah.Waterland@Sun.COM * they must never be reset. These flags are "char *" pointers so that 1729781SMoriah.Waterland@Sun.COM * the object that was skipped or updated can be displayed in debugging 1739781SMoriah.Waterland@Sun.COM * output. 1749781SMoriah.Waterland@Sun.COM */ 1759781SMoriah.Waterland@Sun.COM 1769781SMoriah.Waterland@Sun.COM if (part == 1) { 1779781SMoriah.Waterland@Sun.COM pkgvolume(&pkgdev, srcinst, part, nparts); 1789781SMoriah.Waterland@Sun.COM } 1799781SMoriah.Waterland@Sun.COM 1809781SMoriah.Waterland@Sun.COM tcount = 0; 1819781SMoriah.Waterland@Sun.COM nc = cl_getn(); 1829781SMoriah.Waterland@Sun.COM 1839781SMoriah.Waterland@Sun.COM /* 1849781SMoriah.Waterland@Sun.COM * For each class in this volume, install those files. 1859781SMoriah.Waterland@Sun.COM * 1869781SMoriah.Waterland@Sun.COM * NOTE : This loop index may be decremented by code below forcing a 1879781SMoriah.Waterland@Sun.COM * second trip through for the same class. This happens only when a 1889781SMoriah.Waterland@Sun.COM * class is split between an archive and the tree. Examples would be 1899781SMoriah.Waterland@Sun.COM * old WOS packages and the occasional class containing dynamic 1909781SMoriah.Waterland@Sun.COM * libraries which require special treatment. 1919781SMoriah.Waterland@Sun.COM */ 1929781SMoriah.Waterland@Sun.COM 1939781SMoriah.Waterland@Sun.COM if (is_depend_pkginfo_DB() == B_FALSE) { 1949781SMoriah.Waterland@Sun.COM int classidx; /* the current class */ 1959781SMoriah.Waterland@Sun.COM 1969781SMoriah.Waterland@Sun.COM for (classidx = 0; classidx < nc; classidx++) { 1979781SMoriah.Waterland@Sun.COM int pass_relative = 0; 1989781SMoriah.Waterland@Sun.COM int rel_init = 0; 1999781SMoriah.Waterland@Sun.COM 2009781SMoriah.Waterland@Sun.COM eocflag = count = pass = 0; 2019781SMoriah.Waterland@Sun.COM listfp = (FILE *)0; 2029781SMoriah.Waterland@Sun.COM listfile = NULL; 2039781SMoriah.Waterland@Sun.COM 2049781SMoriah.Waterland@Sun.COM /* Now what do we pass to the class action script */ 2059781SMoriah.Waterland@Sun.COM 2069781SMoriah.Waterland@Sun.COM if (cl_pthrel(classidx) == REL_2_CAS) { 2079781SMoriah.Waterland@Sun.COM pass_relative = 1; 2089781SMoriah.Waterland@Sun.COM } 2099781SMoriah.Waterland@Sun.COM 2109781SMoriah.Waterland@Sun.COM for (;;) { 2119781SMoriah.Waterland@Sun.COM if (!tcount++) { 2129781SMoriah.Waterland@Sun.COM /* first file to install */ 2139781SMoriah.Waterland@Sun.COM if (a_zoneName == (char *)NULL) { 2149781SMoriah.Waterland@Sun.COM echo(MSG_INS_N_N, part, nparts); 2159781SMoriah.Waterland@Sun.COM } else { 2169781SMoriah.Waterland@Sun.COM echo(MSG_INS_N_N_LZ, part, nparts, 2179781SMoriah.Waterland@Sun.COM a_zoneName); 2189781SMoriah.Waterland@Sun.COM } 2199781SMoriah.Waterland@Sun.COM } 2209781SMoriah.Waterland@Sun.COM 2219781SMoriah.Waterland@Sun.COM /* 2229781SMoriah.Waterland@Sun.COM * If there's an install class action script and no 2239781SMoriah.Waterland@Sun.COM * list file has been created yet, create that file 2249781SMoriah.Waterland@Sun.COM * and provide the pointer in listfp. 2259781SMoriah.Waterland@Sun.COM */ 2269781SMoriah.Waterland@Sun.COM if (cl_iscript(classidx) && !listfp) { 2279781SMoriah.Waterland@Sun.COM /* create list file */ 2289781SMoriah.Waterland@Sun.COM putparam("TMPDIR", tmpdir); 2299781SMoriah.Waterland@Sun.COM listfile = tempnam(tmpdir, "list"); 2309781SMoriah.Waterland@Sun.COM if ((listfp = fopen(listfile, "w")) == NULL) { 2319781SMoriah.Waterland@Sun.COM progerr(ERR_WTMPFILE, listfile); 2329781SMoriah.Waterland@Sun.COM quit(99); 2339781SMoriah.Waterland@Sun.COM } 2349781SMoriah.Waterland@Sun.COM } 2359781SMoriah.Waterland@Sun.COM 2369781SMoriah.Waterland@Sun.COM /* 2379781SMoriah.Waterland@Sun.COM * The following function goes through the package 2389781SMoriah.Waterland@Sun.COM * object list returning the array index of the next 2399781SMoriah.Waterland@Sun.COM * regular file. If it encounters a directory, 2409781SMoriah.Waterland@Sun.COM * symlink, named pipe or device, it just creates it. 2419781SMoriah.Waterland@Sun.COM */ 2429781SMoriah.Waterland@Sun.COM 2439781SMoriah.Waterland@Sun.COM entryidx = domerg(extlist, (pass++ ? 0 : part), nparts, 2449781SMoriah.Waterland@Sun.COM classidx, &srcp, &dstp, &updated, &skipped, 2459781SMoriah.Waterland@Sun.COM &anyPathLocal); 2469781SMoriah.Waterland@Sun.COM 2479781SMoriah.Waterland@Sun.COM /* Evaluate the return code */ 2489781SMoriah.Waterland@Sun.COM if (entryidx == DMRG_DONE) { 2499781SMoriah.Waterland@Sun.COM /* 2509781SMoriah.Waterland@Sun.COM * Set ept to the first entry in extlist 2519781SMoriah.Waterland@Sun.COM * which is guaranteed to exist so 2529781SMoriah.Waterland@Sun.COM * later checks against ept->ftype are 2539781SMoriah.Waterland@Sun.COM * not compared to NULL. 2549781SMoriah.Waterland@Sun.COM */ 2559781SMoriah.Waterland@Sun.COM ext = extlist[0]; 2569781SMoriah.Waterland@Sun.COM ept = &(ext->cf_ent); 2579781SMoriah.Waterland@Sun.COM break; /* no more entries to process */ 2589781SMoriah.Waterland@Sun.COM } 2599781SMoriah.Waterland@Sun.COM 2609781SMoriah.Waterland@Sun.COM ext = extlist[entryidx]; 2619781SMoriah.Waterland@Sun.COM ept = &(ext->cf_ent); 2629781SMoriah.Waterland@Sun.COM mstat = &(ext->mstat); 2639781SMoriah.Waterland@Sun.COM 2649781SMoriah.Waterland@Sun.COM /* 2659781SMoriah.Waterland@Sun.COM * If not installing from a partially spooled package 2669781SMoriah.Waterland@Sun.COM * (the "save/pspool" area), and the file contents can 2679781SMoriah.Waterland@Sun.COM * be changed (type is 'e' or 'v'), and the class is not 2689781SMoriah.Waterland@Sun.COM * "none": copy the file from the package (in pristine 2699781SMoriah.Waterland@Sun.COM * state with no actions performed) into the appropriate 2709781SMoriah.Waterland@Sun.COM * location in the packages destination "save/pspool" 2719781SMoriah.Waterland@Sun.COM * area. 2729781SMoriah.Waterland@Sun.COM */ 2739781SMoriah.Waterland@Sun.COM 2749781SMoriah.Waterland@Sun.COM if ((!is_partial_inst()) && 2759781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || (ept->ftype == 'v')) && 2769781SMoriah.Waterland@Sun.COM (strcmp(ept->pkg_class, "none") != 0)) { 2779781SMoriah.Waterland@Sun.COM 2789781SMoriah.Waterland@Sun.COM if (absolutepath(ext->map_path) == B_TRUE && 2799781SMoriah.Waterland@Sun.COM parametricpath(ext->cf_ent.ainfo.local, 2809781SMoriah.Waterland@Sun.COM &relocpath) == B_FALSE) { 2819781SMoriah.Waterland@Sun.COM pspool_loc = ROOT; 2829781SMoriah.Waterland@Sun.COM } else { 2839781SMoriah.Waterland@Sun.COM pspool_loc = RELOC; 2849781SMoriah.Waterland@Sun.COM } 2859781SMoriah.Waterland@Sun.COM 2869781SMoriah.Waterland@Sun.COM n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 2879781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, pspool_loc, 2889781SMoriah.Waterland@Sun.COM relocpath ? relocpath : ext->map_path); 2899781SMoriah.Waterland@Sun.COM 2909781SMoriah.Waterland@Sun.COM if (n >= PATH_MAX) { 2919781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 2929781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 2939781SMoriah.Waterland@Sun.COM ext->map_path); 2949781SMoriah.Waterland@Sun.COM quit(99); 2959781SMoriah.Waterland@Sun.COM } 2969781SMoriah.Waterland@Sun.COM 2979781SMoriah.Waterland@Sun.COM /* copy, preserve source file mode */ 2989781SMoriah.Waterland@Sun.COM 2999781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) { 3009781SMoriah.Waterland@Sun.COM warnflag++; 3019781SMoriah.Waterland@Sun.COM } 3029781SMoriah.Waterland@Sun.COM } 3039781SMoriah.Waterland@Sun.COM 3049781SMoriah.Waterland@Sun.COM /* 3059781SMoriah.Waterland@Sun.COM * If this isn't writeable anyway, it's not going 3069781SMoriah.Waterland@Sun.COM * into the list file. Only count it if it's going 3079781SMoriah.Waterland@Sun.COM * into the list file. 3089781SMoriah.Waterland@Sun.COM */ 3099781SMoriah.Waterland@Sun.COM if (is_fs_writeable(ext->cf_ent.path, 3109781SMoriah.Waterland@Sun.COM &(ext->fsys_value))) 3119781SMoriah.Waterland@Sun.COM count++; 3129781SMoriah.Waterland@Sun.COM 3139781SMoriah.Waterland@Sun.COM pkgvolume(&pkgdev, srcinst, part, nparts); 3149781SMoriah.Waterland@Sun.COM 3159781SMoriah.Waterland@Sun.COM /* 3169781SMoriah.Waterland@Sun.COM * If source verification is OK for this class, make 3179781SMoriah.Waterland@Sun.COM * sure the source we're passing to the class action 3189781SMoriah.Waterland@Sun.COM * script is useable. 3199781SMoriah.Waterland@Sun.COM */ 3209781SMoriah.Waterland@Sun.COM if (cl_svfy(classidx) != NOVERIFY) { 3219781SMoriah.Waterland@Sun.COM if (cl_iscript(classidx) || 3229781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || 3239781SMoriah.Waterland@Sun.COM (ept->ftype == 'n'))) { 3249781SMoriah.Waterland@Sun.COM if (ck_efile(srcp, ept)) { 3259781SMoriah.Waterland@Sun.COM progerr(ERR_CORRUPT, 3269781SMoriah.Waterland@Sun.COM srcp); 3279781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr()); 3289781SMoriah.Waterland@Sun.COM warnflag++; 3299781SMoriah.Waterland@Sun.COM continue; 3309781SMoriah.Waterland@Sun.COM } 3319781SMoriah.Waterland@Sun.COM } 3329781SMoriah.Waterland@Sun.COM } 3339781SMoriah.Waterland@Sun.COM 3349781SMoriah.Waterland@Sun.COM /* 3359781SMoriah.Waterland@Sun.COM * If there's a class action script for this class, 3369781SMoriah.Waterland@Sun.COM * just collect names in a temporary file 3379781SMoriah.Waterland@Sun.COM * that will be used as the stdin when the 3389781SMoriah.Waterland@Sun.COM * class action script is invoked. 3399781SMoriah.Waterland@Sun.COM */ 3409781SMoriah.Waterland@Sun.COM 3419781SMoriah.Waterland@Sun.COM if ((cl_iscript(classidx)) && 3429781SMoriah.Waterland@Sun.COM ((is_fs_writeable(ept->path, 3439781SMoriah.Waterland@Sun.COM &(ext->fsys_value))))) { 3449781SMoriah.Waterland@Sun.COM if (pass_relative) { 3459781SMoriah.Waterland@Sun.COM if (!rel_init) { 3469781SMoriah.Waterland@Sun.COM (void) fputs(instdir, listfp); 3479781SMoriah.Waterland@Sun.COM (void) putc('\n', listfp); 3489781SMoriah.Waterland@Sun.COM rel_init++; 3499781SMoriah.Waterland@Sun.COM } 3509781SMoriah.Waterland@Sun.COM (void) fputs(ext->map_path, listfp); 3519781SMoriah.Waterland@Sun.COM (void) putc('\n', listfp); 3529781SMoriah.Waterland@Sun.COM } else { 3539781SMoriah.Waterland@Sun.COM (void) fputs(srcp ? 3549781SMoriah.Waterland@Sun.COM srcp : "/dev/null", listfp); 3559781SMoriah.Waterland@Sun.COM (void) putc(' ', listfp); 3569781SMoriah.Waterland@Sun.COM (void) fputs(dstp, listfp); 3579781SMoriah.Waterland@Sun.COM (void) putc('\n', listfp); 3589781SMoriah.Waterland@Sun.COM } 3599781SMoriah.Waterland@Sun.COM /* 3609781SMoriah.Waterland@Sun.COM * Note which entries in extlist are regular 3619781SMoriah.Waterland@Sun.COM * files to be installed via the class action 3629781SMoriah.Waterland@Sun.COM * script. 3639781SMoriah.Waterland@Sun.COM */ 3649781SMoriah.Waterland@Sun.COM if (regfiles_head == NULL) { 3659781SMoriah.Waterland@Sun.COM assert(rfp == NULL); 3669781SMoriah.Waterland@Sun.COM regfiles_head = 3679781SMoriah.Waterland@Sun.COM malloc(sizeof (struct reg_files)); 3689781SMoriah.Waterland@Sun.COM if (regfiles_head == NULL) { 3699781SMoriah.Waterland@Sun.COM progerr(ERR_MEMORY, errno); 3709781SMoriah.Waterland@Sun.COM quit(99); 3719781SMoriah.Waterland@Sun.COM } 3729781SMoriah.Waterland@Sun.COM regfiles_head->next = NULL; 3739781SMoriah.Waterland@Sun.COM regfiles_head->val = entryidx; 3749781SMoriah.Waterland@Sun.COM rfp = regfiles_head; 3759781SMoriah.Waterland@Sun.COM } else { 3769781SMoriah.Waterland@Sun.COM assert(rfp != NULL); 3779781SMoriah.Waterland@Sun.COM rfp->next = 3789781SMoriah.Waterland@Sun.COM malloc(sizeof (struct reg_files)); 3799781SMoriah.Waterland@Sun.COM if (rfp->next == NULL) { 3809781SMoriah.Waterland@Sun.COM progerr(ERR_MEMORY, errno); 3819781SMoriah.Waterland@Sun.COM quit(99); 3829781SMoriah.Waterland@Sun.COM } 3839781SMoriah.Waterland@Sun.COM rfp = rfp->next; 3849781SMoriah.Waterland@Sun.COM rfp->next = NULL; 3859781SMoriah.Waterland@Sun.COM rfp->val = entryidx; 3869781SMoriah.Waterland@Sun.COM } 3879781SMoriah.Waterland@Sun.COM 3889781SMoriah.Waterland@Sun.COM /* 3899781SMoriah.Waterland@Sun.COM * A warning message about unwritable targets 3909781SMoriah.Waterland@Sun.COM * in a class may be appropriate here. 3919781SMoriah.Waterland@Sun.COM */ 3929781SMoriah.Waterland@Sun.COM continue; 3939781SMoriah.Waterland@Sun.COM } 3949781SMoriah.Waterland@Sun.COM 3959781SMoriah.Waterland@Sun.COM /* 3969781SMoriah.Waterland@Sun.COM * If not installing from a partially spooled package 3979781SMoriah.Waterland@Sun.COM * (the "save/pspool" area), and the file contents can 3989781SMoriah.Waterland@Sun.COM * be changed (type is 'e' or 'v') and the class 3999781SMoriah.Waterland@Sun.COM * identifier is not "none": copy the file from the 4009781SMoriah.Waterland@Sun.COM * package (in pristine state with no actions performed) 4019781SMoriah.Waterland@Sun.COM * into the appropriate location in the packages 4029781SMoriah.Waterland@Sun.COM * destination "save/pspool" area. 4039781SMoriah.Waterland@Sun.COM */ 4049781SMoriah.Waterland@Sun.COM 4059781SMoriah.Waterland@Sun.COM if ((!is_partial_inst()) && 4069781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || (ept->ftype == 'v') && 4079781SMoriah.Waterland@Sun.COM (strcmp(ept->pkg_class, "none") != 0))) { 4089781SMoriah.Waterland@Sun.COM 4099781SMoriah.Waterland@Sun.COM if (absolutepath(ext->map_path) == B_TRUE && 4109781SMoriah.Waterland@Sun.COM parametricpath(ext->cf_ent.ainfo.local, 4119781SMoriah.Waterland@Sun.COM &relocpath) == B_FALSE) { 4129781SMoriah.Waterland@Sun.COM pspool_loc = ROOT; 4139781SMoriah.Waterland@Sun.COM } else { 4149781SMoriah.Waterland@Sun.COM pspool_loc = RELOC; 4159781SMoriah.Waterland@Sun.COM } 4169781SMoriah.Waterland@Sun.COM 4179781SMoriah.Waterland@Sun.COM n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 4189781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, pspool_loc, 4199781SMoriah.Waterland@Sun.COM relocpath ? relocpath : ext->map_path); 4209781SMoriah.Waterland@Sun.COM 4219781SMoriah.Waterland@Sun.COM if (n >= PATH_MAX) { 4229781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 4239781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 4249781SMoriah.Waterland@Sun.COM ext->map_path); 4259781SMoriah.Waterland@Sun.COM quit(99); 4269781SMoriah.Waterland@Sun.COM } 4279781SMoriah.Waterland@Sun.COM 4289781SMoriah.Waterland@Sun.COM /* copy, preserve source file mode */ 4299781SMoriah.Waterland@Sun.COM 4309781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) { 4319781SMoriah.Waterland@Sun.COM warnflag++; 4329781SMoriah.Waterland@Sun.COM } 4339781SMoriah.Waterland@Sun.COM } 4349781SMoriah.Waterland@Sun.COM 4359781SMoriah.Waterland@Sun.COM /* 4369781SMoriah.Waterland@Sun.COM * There are several tests here to determine 4379781SMoriah.Waterland@Sun.COM * how we're going to deal with objects 4389781SMoriah.Waterland@Sun.COM * intended for remote read-only filesystems. 4399781SMoriah.Waterland@Sun.COM * We don't use is_served() because this may be 4409781SMoriah.Waterland@Sun.COM * a server. We're actually interested in if 4419781SMoriah.Waterland@Sun.COM * it's *really* remote and *really* not 4429781SMoriah.Waterland@Sun.COM * writeable. 4439781SMoriah.Waterland@Sun.COM */ 4449781SMoriah.Waterland@Sun.COM 4459781SMoriah.Waterland@Sun.COM n = is_remote_fs(ept->path, &(ext->fsys_value)); 4469781SMoriah.Waterland@Sun.COM if ((n != 0) && 4479781SMoriah.Waterland@Sun.COM !is_fs_writeable(ept->path, 4489781SMoriah.Waterland@Sun.COM &(ext->fsys_value))) { 4499781SMoriah.Waterland@Sun.COM 4509781SMoriah.Waterland@Sun.COM /* 4519781SMoriah.Waterland@Sun.COM * Don't change the file, we can't write 4529781SMoriah.Waterland@Sun.COM * to it anyway. 4539781SMoriah.Waterland@Sun.COM */ 4549781SMoriah.Waterland@Sun.COM 4559781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 4569781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 4579781SMoriah.Waterland@Sun.COM 4589781SMoriah.Waterland@Sun.COM /* 4599781SMoriah.Waterland@Sun.COM * If it's currently mounted, we can 4609781SMoriah.Waterland@Sun.COM * at least test it for existence. 4619781SMoriah.Waterland@Sun.COM */ 4629781SMoriah.Waterland@Sun.COM 4639781SMoriah.Waterland@Sun.COM if (is_mounted(ept->path, &(ext->fsys_value))) { 4649781SMoriah.Waterland@Sun.COM if (!isfile(NULL, dstp)) { 4659781SMoriah.Waterland@Sun.COM echo(MSG_IS_PRESENT, dstp); 4669781SMoriah.Waterland@Sun.COM } else { 4679781SMoriah.Waterland@Sun.COM echo(WRN_INSTVOL_NONE, dstp); 4689781SMoriah.Waterland@Sun.COM } 4699781SMoriah.Waterland@Sun.COM } else { 4709781SMoriah.Waterland@Sun.COM char *server_host; 4719781SMoriah.Waterland@Sun.COM 4729781SMoriah.Waterland@Sun.COM server_host = get_server_host( 4739781SMoriah.Waterland@Sun.COM ext->fsys_value); 4749781SMoriah.Waterland@Sun.COM 4759781SMoriah.Waterland@Sun.COM /* If not, we're just stuck. */ 4769781SMoriah.Waterland@Sun.COM echo(WRN_INSTVOL_NOVERIFY, 4779781SMoriah.Waterland@Sun.COM dstp, server_host); 4789781SMoriah.Waterland@Sun.COM } 4799781SMoriah.Waterland@Sun.COM 4809781SMoriah.Waterland@Sun.COM continue; 4819781SMoriah.Waterland@Sun.COM } 4829781SMoriah.Waterland@Sun.COM 4839781SMoriah.Waterland@Sun.COM /* echo output destination name */ 4849781SMoriah.Waterland@Sun.COM 4859781SMoriah.Waterland@Sun.COM echo("%s", dstp); 4869781SMoriah.Waterland@Sun.COM 4879781SMoriah.Waterland@Sun.COM /* 4889781SMoriah.Waterland@Sun.COM * if no source then no need to copy/verify 4899781SMoriah.Waterland@Sun.COM */ 4909781SMoriah.Waterland@Sun.COM 4919781SMoriah.Waterland@Sun.COM if (srcp == (char *)NULL) { 4929781SMoriah.Waterland@Sun.COM continue; 4939781SMoriah.Waterland@Sun.COM } 4949781SMoriah.Waterland@Sun.COM 4959781SMoriah.Waterland@Sun.COM /* 4969781SMoriah.Waterland@Sun.COM * If doing a partial installation (creating a 4979781SMoriah.Waterland@Sun.COM * non-global zone), extra steps need to be taken: 4989781SMoriah.Waterland@Sun.COM * 4999781SMoriah.Waterland@Sun.COM * 1) if the file is not type 'e' and not type 'v' and 5009781SMoriah.Waterland@Sun.COM * the class is "none": then the file must already 5019781SMoriah.Waterland@Sun.COM * exist (as a result of the initial non-global zone 5029781SMoriah.Waterland@Sun.COM * installation which caused all non-e/v files to be 5039781SMoriah.Waterland@Sun.COM * copied from the global zone to the non-global 5049781SMoriah.Waterland@Sun.COM * zone). If this is the case, verify that the file 5059781SMoriah.Waterland@Sun.COM * exists and has the correct attributes. 5069781SMoriah.Waterland@Sun.COM * 5079781SMoriah.Waterland@Sun.COM * 2) if the file is not type 'e' and not type 'v' 5089781SMoriah.Waterland@Sun.COM * and the class is NOT "none", *OR* if the file is 5099781SMoriah.Waterland@Sun.COM * type 'e' or type 'v': then check to see if the 5109781SMoriah.Waterland@Sun.COM * file is located in an area inherited from the 5119781SMoriah.Waterland@Sun.COM * global zone. If so, then there is no ability to 5129781SMoriah.Waterland@Sun.COM * change the file since inherited file systems are 5139781SMoriah.Waterland@Sun.COM * "read only" - just verify that the file exists and 5149781SMoriah.Waterland@Sun.COM * verify attributes only if not 'e' or 'v'. 5159781SMoriah.Waterland@Sun.COM */ 5169781SMoriah.Waterland@Sun.COM 5179781SMoriah.Waterland@Sun.COM if (is_partial_inst() != 0) { 5189781SMoriah.Waterland@Sun.COM 5199781SMoriah.Waterland@Sun.COM /* 5209781SMoriah.Waterland@Sun.COM * determine if the destination package is in an 5219781SMoriah.Waterland@Sun.COM * area inherited from the global zone 5229781SMoriah.Waterland@Sun.COM */ 5239781SMoriah.Waterland@Sun.COM 5249781SMoriah.Waterland@Sun.COM n = pkgMatchInherited(srcp, dstp, 5259781SMoriah.Waterland@Sun.COM get_inst_root(), ept->ainfo.mode, 5269781SMoriah.Waterland@Sun.COM ept->cinfo.modtime, ept->ftype, 5279781SMoriah.Waterland@Sun.COM ept->cinfo.cksum); 5289781SMoriah.Waterland@Sun.COM 5299781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_PARTIAL_INST, 5309781SMoriah.Waterland@Sun.COM srcp ? srcp : "", dstp ? dstp: "", 5319781SMoriah.Waterland@Sun.COM ((get_inst_root()) && 5329781SMoriah.Waterland@Sun.COM (strcmp(get_inst_root(), "/") != 0)) ? 5339781SMoriah.Waterland@Sun.COM get_inst_root() : "", 5349781SMoriah.Waterland@Sun.COM ept->ainfo.mode, ept->cinfo.modtime, 5359781SMoriah.Waterland@Sun.COM ept->ftype, ept->cinfo.cksum, n); 5369781SMoriah.Waterland@Sun.COM 5379781SMoriah.Waterland@Sun.COM /* 5389781SMoriah.Waterland@Sun.COM * if not type 'e|v' and class 'none', then the 5399781SMoriah.Waterland@Sun.COM * file must already exist. 5409781SMoriah.Waterland@Sun.COM */ 5419781SMoriah.Waterland@Sun.COM 5429781SMoriah.Waterland@Sun.COM if ((ept->ftype != 'e') && 5439781SMoriah.Waterland@Sun.COM (ept->ftype != 'v') && 5449781SMoriah.Waterland@Sun.COM (strcmp(cl_nam(ept->pkg_class_idx), 5459781SMoriah.Waterland@Sun.COM "none") == 0)) { 5469781SMoriah.Waterland@Sun.COM 5479781SMoriah.Waterland@Sun.COM /* 5489781SMoriah.Waterland@Sun.COM * if the file is in a space inherited 5499781SMoriah.Waterland@Sun.COM * from the global zone, and if the 5509781SMoriah.Waterland@Sun.COM * contents or attributes are incorrect, 5519781SMoriah.Waterland@Sun.COM * then generate a warning that the 5529781SMoriah.Waterland@Sun.COM * global zone file contents and/or file 5539781SMoriah.Waterland@Sun.COM * attributes have been modified and 5549781SMoriah.Waterland@Sun.COM * that the modifications are extended 5559781SMoriah.Waterland@Sun.COM * to the non-global zone (inherited 5569781SMoriah.Waterland@Sun.COM * from the global zone). 5579781SMoriah.Waterland@Sun.COM */ 5589781SMoriah.Waterland@Sun.COM 5599781SMoriah.Waterland@Sun.COM if (n == 0) { 5609781SMoriah.Waterland@Sun.COM /* is file changed? */ 5619781SMoriah.Waterland@Sun.COM n = finalck(ept, 1, 1, B_TRUE); 5629781SMoriah.Waterland@Sun.COM 5639781SMoriah.Waterland@Sun.COM /* no - ok - continue */ 5649781SMoriah.Waterland@Sun.COM if (n == 0) { 5659781SMoriah.Waterland@Sun.COM continue; 5669781SMoriah.Waterland@Sun.COM } 5679781SMoriah.Waterland@Sun.COM 5689781SMoriah.Waterland@Sun.COM /* output warning message */ 5699781SMoriah.Waterland@Sun.COM logerr(NOTE_INSTVOL_FINALCKFAIL, 5709781SMoriah.Waterland@Sun.COM pkginst, ext->map_path, 5719781SMoriah.Waterland@Sun.COM a_zoneName, ept->path); 5729781SMoriah.Waterland@Sun.COM continue; 5739781SMoriah.Waterland@Sun.COM } else if (!finalck(ept, 1, 1, 5749781SMoriah.Waterland@Sun.COM B_FALSE)) { 5759781SMoriah.Waterland@Sun.COM /* 5769781SMoriah.Waterland@Sun.COM * non-e/v file of class "none" 5779781SMoriah.Waterland@Sun.COM * not inherited from the global 5789781SMoriah.Waterland@Sun.COM * zone: verify file already 5799781SMoriah.Waterland@Sun.COM * exists:everything checks here 5809781SMoriah.Waterland@Sun.COM */ 5819781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 5829781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 5839781SMoriah.Waterland@Sun.COM } 5849781SMoriah.Waterland@Sun.COM continue; 5859781SMoriah.Waterland@Sun.COM } 5869781SMoriah.Waterland@Sun.COM 5879781SMoriah.Waterland@Sun.COM /* 5889781SMoriah.Waterland@Sun.COM * non-e/v file with class action script, or 5899781SMoriah.Waterland@Sun.COM * e/v file: if the file is in an area inherited 5909781SMoriah.Waterland@Sun.COM * from the global zone, then no need (or the 5919781SMoriah.Waterland@Sun.COM * ability) to update just accept the file as is 5929781SMoriah.Waterland@Sun.COM */ 5939781SMoriah.Waterland@Sun.COM 5949781SMoriah.Waterland@Sun.COM if (n == B_TRUE) { 5959781SMoriah.Waterland@Sun.COM /* 5969781SMoriah.Waterland@Sun.COM * the object is in an area inherited 5979781SMoriah.Waterland@Sun.COM * from the global zone and the objects 5989781SMoriah.Waterland@Sun.COM * attributes are verified 5999781SMoriah.Waterland@Sun.COM */ 6009781SMoriah.Waterland@Sun.COM 6019781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 6029781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 6039781SMoriah.Waterland@Sun.COM 6049781SMoriah.Waterland@Sun.COM /* NOTE: package object skipped */ 6059781SMoriah.Waterland@Sun.COM 6069781SMoriah.Waterland@Sun.COM if (skipped == (char *)NULL) { 6079781SMoriah.Waterland@Sun.COM skipped = dstp; 6089781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 6099781SMoriah.Waterland@Sun.COM skipped); 6109781SMoriah.Waterland@Sun.COM } 6119781SMoriah.Waterland@Sun.COM continue; 6129781SMoriah.Waterland@Sun.COM } 6139781SMoriah.Waterland@Sun.COM } 6149781SMoriah.Waterland@Sun.COM 6159781SMoriah.Waterland@Sun.COM /* 6169781SMoriah.Waterland@Sun.COM * Copy from source media to target path and fix file 6179781SMoriah.Waterland@Sun.COM * mode and permission now in case installation halted. 6189781SMoriah.Waterland@Sun.COM */ 6199781SMoriah.Waterland@Sun.COM 6209781SMoriah.Waterland@Sun.COM if (z_path_is_inherited(dstp, ept->ftype, 6219781SMoriah.Waterland@Sun.COM get_inst_root()) == B_FALSE) { 6229781SMoriah.Waterland@Sun.COM 6239781SMoriah.Waterland@Sun.COM /* 6249781SMoriah.Waterland@Sun.COM * If the filesystem is read-only don't attempt 6259781SMoriah.Waterland@Sun.COM * to copy a file. Just check that the content 6269781SMoriah.Waterland@Sun.COM * and attributes of the file are correct. 6279781SMoriah.Waterland@Sun.COM * 6289781SMoriah.Waterland@Sun.COM * Normally this doesn't happen, because files, 6299781SMoriah.Waterland@Sun.COM * which don't change, are not returned by 6309781SMoriah.Waterland@Sun.COM * domerg(). However when installing a patch in 6319781SMoriah.Waterland@Sun.COM * a sparse zone, which was already installed 6329781SMoriah.Waterland@Sun.COM * in global zone with -G option, NGZ's 6339781SMoriah.Waterland@Sun.COM * contents db still contains the old record 6349781SMoriah.Waterland@Sun.COM * for this file and therefore domerg() 6359781SMoriah.Waterland@Sun.COM * considers these files to be different even 6369781SMoriah.Waterland@Sun.COM * though they are the same. 6379781SMoriah.Waterland@Sun.COM */ 6389781SMoriah.Waterland@Sun.COM n = 0; 6399781SMoriah.Waterland@Sun.COM if (is_fs_writeable(ept->path, 6409781SMoriah.Waterland@Sun.COM &(ext->fsys_value))) 6419781SMoriah.Waterland@Sun.COM n = cppath(MODE_SET|DIR_DISPLAY, srcp, 6429781SMoriah.Waterland@Sun.COM dstp, ept->ainfo.mode); 6439781SMoriah.Waterland@Sun.COM 6449781SMoriah.Waterland@Sun.COM if (n != 0) { 6459781SMoriah.Waterland@Sun.COM warnflag++; 6469781SMoriah.Waterland@Sun.COM } else if (!finalck(ept, 1, 1, B_FALSE)) { 6479781SMoriah.Waterland@Sun.COM /* 6489781SMoriah.Waterland@Sun.COM * everything checks here 6499781SMoriah.Waterland@Sun.COM */ 6509781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 6519781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 6529781SMoriah.Waterland@Sun.COM } 6539781SMoriah.Waterland@Sun.COM } 6549781SMoriah.Waterland@Sun.COM 6559781SMoriah.Waterland@Sun.COM /* NOTE: a package object was updated */ 6569781SMoriah.Waterland@Sun.COM 6579781SMoriah.Waterland@Sun.COM if (updated == (char *)NULL) { 6589781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_UPDATED, dstp); 6599781SMoriah.Waterland@Sun.COM updated = dstp; 6609781SMoriah.Waterland@Sun.COM } 6619781SMoriah.Waterland@Sun.COM } 6629781SMoriah.Waterland@Sun.COM 6639781SMoriah.Waterland@Sun.COM /* 6649781SMoriah.Waterland@Sun.COM * We have now completed processing of all pathnames 6659781SMoriah.Waterland@Sun.COM * associated with this volume and class. 6669781SMoriah.Waterland@Sun.COM */ 6679781SMoriah.Waterland@Sun.COM if (cl_iscript(classidx)) { 6689781SMoriah.Waterland@Sun.COM /* 6699781SMoriah.Waterland@Sun.COM * Execute appropriate class action script 6709781SMoriah.Waterland@Sun.COM * with list of source/destination pathnames 6719781SMoriah.Waterland@Sun.COM * as the input to the script. 6729781SMoriah.Waterland@Sun.COM */ 6739781SMoriah.Waterland@Sun.COM 6749781SMoriah.Waterland@Sun.COM if (chdir(pkgbin)) { 6759781SMoriah.Waterland@Sun.COM progerr(ERR_CHGDIR, pkgbin); 6769781SMoriah.Waterland@Sun.COM quit(99); 6779781SMoriah.Waterland@Sun.COM } 6789781SMoriah.Waterland@Sun.COM 6799781SMoriah.Waterland@Sun.COM if (listfp) { 6809781SMoriah.Waterland@Sun.COM (void) fclose(listfp); 6819781SMoriah.Waterland@Sun.COM } 6829781SMoriah.Waterland@Sun.COM 6839781SMoriah.Waterland@Sun.COM /* 6849781SMoriah.Waterland@Sun.COM * if the object associated with the class action script 6859781SMoriah.Waterland@Sun.COM * is in an area inherited from the global zone, then 6869781SMoriah.Waterland@Sun.COM * there is no need to run the class action script - 6879781SMoriah.Waterland@Sun.COM * assume that anything the script would do has already 6889781SMoriah.Waterland@Sun.COM * been done in the area shared from the global zone. 6899781SMoriah.Waterland@Sun.COM */ 6909781SMoriah.Waterland@Sun.COM 6919781SMoriah.Waterland@Sun.COM /* nothing updated, nothing skipped */ 6929781SMoriah.Waterland@Sun.COM 6939781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_CAS_INFO, is_partial_inst(), 6949781SMoriah.Waterland@Sun.COM updated ? updated : "", 6959781SMoriah.Waterland@Sun.COM skipped ? skipped : "", 6969781SMoriah.Waterland@Sun.COM anyPathLocal ? anyPathLocal : ""); 6979781SMoriah.Waterland@Sun.COM 6989781SMoriah.Waterland@Sun.COM if ((is_partial_inst() != 0) && 6999781SMoriah.Waterland@Sun.COM (updated == (char *)NULL) && 7009781SMoriah.Waterland@Sun.COM (anyPathLocal == (char *)NULL)) { 7019781SMoriah.Waterland@Sun.COM 7029781SMoriah.Waterland@Sun.COM /* 7039781SMoriah.Waterland@Sun.COM * installing in non-global zone, and no object 7049781SMoriah.Waterland@Sun.COM * has been updated (installed/verified in non- 7059781SMoriah.Waterland@Sun.COM * inherited area), and no path delivered by the 7069781SMoriah.Waterland@Sun.COM * package is in an area not inherited from the 7079781SMoriah.Waterland@Sun.COM * global zone (all paths delivered are in 7089781SMoriah.Waterland@Sun.COM * areas inherited from the global zone): do not 7099781SMoriah.Waterland@Sun.COM * run the class action script because the only 7109781SMoriah.Waterland@Sun.COM * affected areas are inherited (read only). 7119781SMoriah.Waterland@Sun.COM */ 7129781SMoriah.Waterland@Sun.COM 7139781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_NOT_RUNNING_CAS, 7149781SMoriah.Waterland@Sun.COM a_zoneName ? a_zoneName : "?", 7159781SMoriah.Waterland@Sun.COM eocflag ? "ENDOFCLASS" : 7169781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7179781SMoriah.Waterland@Sun.COM cl_nam(classidx), 7189781SMoriah.Waterland@Sun.COM cl_iscript(classidx)); 7199781SMoriah.Waterland@Sun.COM 7209781SMoriah.Waterland@Sun.COM if ((r_skipped != (char **)NULL) && 7219781SMoriah.Waterland@Sun.COM (*r_skipped == (char *)NULL) && 7229781SMoriah.Waterland@Sun.COM (skipped == (char *)NULL)) { 7239781SMoriah.Waterland@Sun.COM skipped = "postinstall"; 7249781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 7259781SMoriah.Waterland@Sun.COM skipped); 7269781SMoriah.Waterland@Sun.COM } 7279781SMoriah.Waterland@Sun.COM } else { 7289781SMoriah.Waterland@Sun.COM /* run the class action script */ 7299781SMoriah.Waterland@Sun.COM 7309781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_RUNNING_CAS, 7319781SMoriah.Waterland@Sun.COM a_zoneName ? a_zoneName : "?", 7329781SMoriah.Waterland@Sun.COM eocflag ? "ENDOFCLASS" : 7339781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7349781SMoriah.Waterland@Sun.COM cl_nam(classidx), 7359781SMoriah.Waterland@Sun.COM cl_iscript(classidx)); 7369781SMoriah.Waterland@Sun.COM 7379781SMoriah.Waterland@Sun.COM /* Use ULIMIT if supplied. */ 7389781SMoriah.Waterland@Sun.COM set_ulimit(cl_iscript(classidx), ERR_CASFAIL); 7399781SMoriah.Waterland@Sun.COM 7409781SMoriah.Waterland@Sun.COM if (eocflag) { 7419781SMoriah.Waterland@Sun.COM /* 7429781SMoriah.Waterland@Sun.COM * end of class detected. 7439781SMoriah.Waterland@Sun.COM * Since there are no more volumes which 7449781SMoriah.Waterland@Sun.COM * contain pathnames associated with 7459781SMoriah.Waterland@Sun.COM * this class, execute class action 7469781SMoriah.Waterland@Sun.COM * script with the ENDOFCLASS argument; 7479781SMoriah.Waterland@Sun.COM * we do this even if none of the path 7489781SMoriah.Waterland@Sun.COM * names associated with this class and 7499781SMoriah.Waterland@Sun.COM * volume needed installation to 7509781SMoriah.Waterland@Sun.COM * guarantee the class action script is 7519781SMoriah.Waterland@Sun.COM * executed at least once during package 7529781SMoriah.Waterland@Sun.COM * installation. 7539781SMoriah.Waterland@Sun.COM */ 7549781SMoriah.Waterland@Sun.COM if (pkgverbose) { 7559781SMoriah.Waterland@Sun.COM n = pkgexecl((listfp ? 7569781SMoriah.Waterland@Sun.COM listfile : CAS_STDIN), 7579781SMoriah.Waterland@Sun.COM CAS_STDOUT, 7589781SMoriah.Waterland@Sun.COM CAS_USER, CAS_GRP, 7599781SMoriah.Waterland@Sun.COM SHELL, "-x", 7609781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7619781SMoriah.Waterland@Sun.COM "ENDOFCLASS", NULL); 7629781SMoriah.Waterland@Sun.COM } else { 7639781SMoriah.Waterland@Sun.COM n = pkgexecl( 7649781SMoriah.Waterland@Sun.COM (listfp ? 7659781SMoriah.Waterland@Sun.COM listfile : CAS_STDIN), 7669781SMoriah.Waterland@Sun.COM CAS_STDOUT, CAS_USER, 7679781SMoriah.Waterland@Sun.COM CAS_GRP, SHELL, 7689781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7699781SMoriah.Waterland@Sun.COM "ENDOFCLASS", NULL); 7709781SMoriah.Waterland@Sun.COM } 7719781SMoriah.Waterland@Sun.COM ckreturn(n, ERR_CASFAIL); 7729781SMoriah.Waterland@Sun.COM } else if (count) { 7739781SMoriah.Waterland@Sun.COM /* execute class action script */ 7749781SMoriah.Waterland@Sun.COM if (pkgverbose) { 7759781SMoriah.Waterland@Sun.COM n = pkgexecl(listfile, 7769781SMoriah.Waterland@Sun.COM CAS_STDOUT, CAS_USER, 7779781SMoriah.Waterland@Sun.COM CAS_GRP, SHELL, "-x", 7789781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7799781SMoriah.Waterland@Sun.COM NULL); 7809781SMoriah.Waterland@Sun.COM } else { 7819781SMoriah.Waterland@Sun.COM n = pkgexecl(listfile, 7829781SMoriah.Waterland@Sun.COM CAS_STDOUT, CAS_USER, 7839781SMoriah.Waterland@Sun.COM CAS_GRP, SHELL, 7849781SMoriah.Waterland@Sun.COM cl_iscript(classidx), 7859781SMoriah.Waterland@Sun.COM NULL); 7869781SMoriah.Waterland@Sun.COM } 7879781SMoriah.Waterland@Sun.COM ckreturn(n, ERR_CASFAIL); 7889781SMoriah.Waterland@Sun.COM } 7899781SMoriah.Waterland@Sun.COM 7909781SMoriah.Waterland@Sun.COM /* 7919781SMoriah.Waterland@Sun.COM * Ensure the mod times on disk match those 7929781SMoriah.Waterland@Sun.COM * in the pkgmap. In this case, call cverify 7939781SMoriah.Waterland@Sun.COM * with checksumming disabled, since the only 7949781SMoriah.Waterland@Sun.COM * action that needs to be done is to verify 7959781SMoriah.Waterland@Sun.COM * that the attributes are correct. 7969781SMoriah.Waterland@Sun.COM */ 7979781SMoriah.Waterland@Sun.COM 7989781SMoriah.Waterland@Sun.COM if ((rfp = regfiles_head) != NULL) { 7999781SMoriah.Waterland@Sun.COM while (rfp != NULL) { 8009781SMoriah.Waterland@Sun.COM ept = &(extlist[rfp->val]->cf_ent); 8019781SMoriah.Waterland@Sun.COM cverify(1, &ept->ftype, ept->path, 8029781SMoriah.Waterland@Sun.COM &ept->cinfo, 0); 8039781SMoriah.Waterland@Sun.COM rfp = rfp->next; 8049781SMoriah.Waterland@Sun.COM } 8059781SMoriah.Waterland@Sun.COM regfiles_free(); 8069781SMoriah.Waterland@Sun.COM } 8079781SMoriah.Waterland@Sun.COM 8089781SMoriah.Waterland@Sun.COM clr_ulimit(); 8099781SMoriah.Waterland@Sun.COM 8109781SMoriah.Waterland@Sun.COM if ((r_updated != (char **)NULL) && 8119781SMoriah.Waterland@Sun.COM (*r_updated == (char *)NULL) && 8129781SMoriah.Waterland@Sun.COM (updated == (char *)NULL)) { 8139781SMoriah.Waterland@Sun.COM updated = "postinstall"; 8149781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_UPDATED, 8159781SMoriah.Waterland@Sun.COM updated); 8169781SMoriah.Waterland@Sun.COM } 8179781SMoriah.Waterland@Sun.COM } 8189781SMoriah.Waterland@Sun.COM if (listfile) { 8199781SMoriah.Waterland@Sun.COM (void) remove(listfile); 8209781SMoriah.Waterland@Sun.COM } 8219781SMoriah.Waterland@Sun.COM } 8229781SMoriah.Waterland@Sun.COM 8239781SMoriah.Waterland@Sun.COM if (eocflag && (!is_partial_inst() || (is_partial_inst() && 8249781SMoriah.Waterland@Sun.COM strcmp(cl_nam(classidx), "none") != 0))) { 8259781SMoriah.Waterland@Sun.COM if (cl_dvfy(classidx) == QKVERIFY && !repl_permitted) { 8269781SMoriah.Waterland@Sun.COM /* 8279781SMoriah.Waterland@Sun.COM * The quick verify just fixes everything. 8289781SMoriah.Waterland@Sun.COM * If it returns 0, all is well. If it 8299781SMoriah.Waterland@Sun.COM * returns 1, then the class installation 8309781SMoriah.Waterland@Sun.COM * was incomplete and we retry on the 8319781SMoriah.Waterland@Sun.COM * stuff that failed in the conventional 8329781SMoriah.Waterland@Sun.COM * way (without a CAS). this is primarily 8339781SMoriah.Waterland@Sun.COM * to accomodate old archives such as are 8349781SMoriah.Waterland@Sun.COM * found in pre-2.5 WOS; but, it is also 8359781SMoriah.Waterland@Sun.COM * used when a critical dynamic library 8369781SMoriah.Waterland@Sun.COM * is not archived with its class. 8379781SMoriah.Waterland@Sun.COM */ 8389781SMoriah.Waterland@Sun.COM if (!fix_attributes(extlist, classidx)) { 8399781SMoriah.Waterland@Sun.COM /* 8409781SMoriah.Waterland@Sun.COM * Reset the CAS pointer. If the 8419781SMoriah.Waterland@Sun.COM * function returns 0 then there 8429781SMoriah.Waterland@Sun.COM * was no script there in the first 8439781SMoriah.Waterland@Sun.COM * place and we'll just have to 8449781SMoriah.Waterland@Sun.COM * call this a miss. 8459781SMoriah.Waterland@Sun.COM */ 8469781SMoriah.Waterland@Sun.COM if (cl_deliscript(classidx)) 8479781SMoriah.Waterland@Sun.COM /* 8489781SMoriah.Waterland@Sun.COM * Decrement classidx for 8499781SMoriah.Waterland@Sun.COM * next pass. 8509781SMoriah.Waterland@Sun.COM */ 8519781SMoriah.Waterland@Sun.COM classidx--; 8529781SMoriah.Waterland@Sun.COM } 8539781SMoriah.Waterland@Sun.COM } else { 8549781SMoriah.Waterland@Sun.COM /* 8559781SMoriah.Waterland@Sun.COM * Finalize merge. This checks to make sure 8569781SMoriah.Waterland@Sun.COM * file attributes are correct and any links 8579781SMoriah.Waterland@Sun.COM * specified are created. 8589781SMoriah.Waterland@Sun.COM */ 8599781SMoriah.Waterland@Sun.COM (void) endofclass(extlist, classidx, 8609781SMoriah.Waterland@Sun.COM (cl_iscript(classidx) ? 0 : 1), 861*9869SCasper.Dik@Sun.COM pkgserver, a_cfTmpVfp); 8629781SMoriah.Waterland@Sun.COM } 8639781SMoriah.Waterland@Sun.COM } 8649781SMoriah.Waterland@Sun.COM } 8659781SMoriah.Waterland@Sun.COM } 8669781SMoriah.Waterland@Sun.COM 8679781SMoriah.Waterland@Sun.COM /* 8689781SMoriah.Waterland@Sun.COM * Instead of creating links back to the GZ files the logic is 8699781SMoriah.Waterland@Sun.COM * to let zdo recreate the files from the GZ then invoke pkgadd to 8709781SMoriah.Waterland@Sun.COM * install the editable files and skip over any 'f'type files. 8719781SMoriah.Waterland@Sun.COM * The commented out block is to create the links which should be 8729781SMoriah.Waterland@Sun.COM * removed once the current code is tested to be correct. 8739781SMoriah.Waterland@Sun.COM */ 8749781SMoriah.Waterland@Sun.COM 8759781SMoriah.Waterland@Sun.COM /* 8769781SMoriah.Waterland@Sun.COM * Go through extlist creating links for 'f'type files 8779781SMoriah.Waterland@Sun.COM * if we're in a global zone. Note that this code lies 8789781SMoriah.Waterland@Sun.COM * here instead of in the main loop to support CAF packages. 8799781SMoriah.Waterland@Sun.COM * In a CAF package the files are installed by the i.none script 8809781SMoriah.Waterland@Sun.COM * and don't exist until all files are done being processed, thus 8819781SMoriah.Waterland@Sun.COM * the additional loop through extlist. 8829781SMoriah.Waterland@Sun.COM */ 8839781SMoriah.Waterland@Sun.COM 8849781SMoriah.Waterland@Sun.COM /* 8859781SMoriah.Waterland@Sun.COM * output appropriate completion message 8869781SMoriah.Waterland@Sun.COM */ 8879781SMoriah.Waterland@Sun.COM 8889781SMoriah.Waterland@Sun.COM if (is_depend_pkginfo_DB() == B_TRUE) { 8899781SMoriah.Waterland@Sun.COM /* updating database only (hollow package) */ 8909781SMoriah.Waterland@Sun.COM if (a_zoneName == (char *)NULL) { 8919781SMoriah.Waterland@Sun.COM echo(MSG_DBUPD_N_N, part, nparts); 8929781SMoriah.Waterland@Sun.COM } else { 8939781SMoriah.Waterland@Sun.COM echo(MSG_DBUPD_N_N_LZ, part, nparts, a_zoneName); 8949781SMoriah.Waterland@Sun.COM } 8959781SMoriah.Waterland@Sun.COM } else if (tcount == 0) { 8969781SMoriah.Waterland@Sun.COM /* updating package (non-hollow package) */ 8979781SMoriah.Waterland@Sun.COM if (a_zoneName == (char *)NULL) { 8989781SMoriah.Waterland@Sun.COM echo(MSG_INST_N_N, part, nparts); 8999781SMoriah.Waterland@Sun.COM } else { 9009781SMoriah.Waterland@Sun.COM echo(MSG_INST_N_N_LZ, part, nparts, a_zoneName); 9019781SMoriah.Waterland@Sun.COM } 9029781SMoriah.Waterland@Sun.COM } 9039781SMoriah.Waterland@Sun.COM 9049781SMoriah.Waterland@Sun.COM /* 9059781SMoriah.Waterland@Sun.COM * if any package objects were updated (not inherited from the 9069781SMoriah.Waterland@Sun.COM * global zone or otherwise already in existence), set the updated 9079781SMoriah.Waterland@Sun.COM * flag as appropriate 9089781SMoriah.Waterland@Sun.COM */ 9099781SMoriah.Waterland@Sun.COM 9109781SMoriah.Waterland@Sun.COM if (updated != (char *)NULL) { 9119781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_UPDATED, updated); 9129781SMoriah.Waterland@Sun.COM if (r_updated != (char **)NULL) { 9139781SMoriah.Waterland@Sun.COM *r_updated = updated; 9149781SMoriah.Waterland@Sun.COM } 9159781SMoriah.Waterland@Sun.COM } 9169781SMoriah.Waterland@Sun.COM 9179781SMoriah.Waterland@Sun.COM /* 9189781SMoriah.Waterland@Sun.COM * if any package objects were skipped (verified inherited from the 9199781SMoriah.Waterland@Sun.COM * global zone), set the skipped flag as appropriate 9209781SMoriah.Waterland@Sun.COM */ 9219781SMoriah.Waterland@Sun.COM 9229781SMoriah.Waterland@Sun.COM if (skipped != (char *)NULL) { 9239781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_SKIPPED, skipped); 9249781SMoriah.Waterland@Sun.COM if (r_skipped != (char **)NULL) { 9259781SMoriah.Waterland@Sun.COM *r_skipped = skipped; 9269781SMoriah.Waterland@Sun.COM } 9279781SMoriah.Waterland@Sun.COM } 9289781SMoriah.Waterland@Sun.COM } 9299781SMoriah.Waterland@Sun.COM 9309781SMoriah.Waterland@Sun.COM /* 9319781SMoriah.Waterland@Sun.COM * Name: domerg 9329781SMoriah.Waterland@Sun.COM * Description: For the specified class, review each entry and return the array 9339781SMoriah.Waterland@Sun.COM * index number of the next regular file to process. Hard links are 9349781SMoriah.Waterland@Sun.COM * skipped (they are created in endofclass() and directories, 9359781SMoriah.Waterland@Sun.COM * symlinks, pipes and devices are created here, as well as any 9369781SMoriah.Waterland@Sun.COM * file that already exists and has the correct attributes. 9379781SMoriah.Waterland@Sun.COM * Arguments: struct cfextra **extlist - [RO, *RW] 9389781SMoriah.Waterland@Sun.COM * - Pointer to list of cfextra structures representing 9399781SMoriah.Waterland@Sun.COM * the pkgmap of the package to be installed 9409781SMoriah.Waterland@Sun.COM * int part - [RO, *RO] 9419781SMoriah.Waterland@Sun.COM * - the part of the package currently being processed; 9429781SMoriah.Waterland@Sun.COM * packages begin with part "1" and proceed for the 9439781SMoriah.Waterland@Sun.COM * number (nparts) that comprise the package (volume). 9449781SMoriah.Waterland@Sun.COM * int nparts - [RO, *RO] 9459781SMoriah.Waterland@Sun.COM * - the number of parts the package is divided into 9469781SMoriah.Waterland@Sun.COM * int myclass - [RO, *RO] 9479781SMoriah.Waterland@Sun.COM * - index into class array of the current class 9489781SMoriah.Waterland@Sun.COM * char **srcp - [RW, *RW] 9499781SMoriah.Waterland@Sun.COM * - pointer to pointer to string representing the source 9509781SMoriah.Waterland@Sun.COM * path for the next package to process - if this 9519781SMoriah.Waterland@Sun.COM * function returns != DMRG_DONE then this pointer is 9529781SMoriah.Waterland@Sun.COM * set to a pointer to a string representing the source 9539781SMoriah.Waterland@Sun.COM * path for the next object from the package to process 9549781SMoriah.Waterland@Sun.COM * char **dstp - [RW, *RW] 9559781SMoriah.Waterland@Sun.COM * - pointer to pointer to string representing the target 9569781SMoriah.Waterland@Sun.COM * path for the next package to process - if this 9579781SMoriah.Waterland@Sun.COM * function returns != DMRG_DONE then this pointer is 9589781SMoriah.Waterland@Sun.COM * set to a pointer to a string representing the target 9599781SMoriah.Waterland@Sun.COM * path for the next object from the package to process 9609781SMoriah.Waterland@Sun.COM * char **r_updated - [RO, *RW] 9619781SMoriah.Waterland@Sun.COM * - pointer to pointer to string - set if the last path 9629781SMoriah.Waterland@Sun.COM * returned exists or does not need updating and the 9639781SMoriah.Waterland@Sun.COM * object is NOT located in an area inherited from the 9649781SMoriah.Waterland@Sun.COM * global zone. This is used to determine if the last 9659781SMoriah.Waterland@Sun.COM * path object returned DOES exist in an area that is 9669781SMoriah.Waterland@Sun.COM * inherited from the global zone. If no paths are 9679781SMoriah.Waterland@Sun.COM * inherited from the global zone, this is always set 9689781SMoriah.Waterland@Sun.COM * when a path to be installed exists and has the 9699781SMoriah.Waterland@Sun.COM * correct contents. 9709781SMoriah.Waterland@Sun.COM * char **r_skipped - [RO, *RW] 9719781SMoriah.Waterland@Sun.COM * - pointer to pointer to string - set if the last path 9729781SMoriah.Waterland@Sun.COM * returned exists or does not need updating and the 9739781SMoriah.Waterland@Sun.COM * object IS located in an area inherited from the 9749781SMoriah.Waterland@Sun.COM * global zone. This is used to determine if the last 9759781SMoriah.Waterland@Sun.COM * path object returned does NOT exist in an area that 9769781SMoriah.Waterland@Sun.COM * is inherited from the global zone. If no paths are 9779781SMoriah.Waterland@Sun.COM * inherited from the global zone, this is never set. 9789781SMoriah.Waterland@Sun.COM * char **r_anyPathLocal - [RO, *RW] 9799781SMoriah.Waterland@Sun.COM * - pointer to pointer to string - set if any object 9809781SMoriah.Waterland@Sun.COM * belonging to the package is NOT located in an area 9819781SMoriah.Waterland@Sun.COM * inherited from the global zone. This is used to 9829781SMoriah.Waterland@Sun.COM * determine if the package references ANY objects that 9839781SMoriah.Waterland@Sun.COM * are NOT located in an area inherited from the global 9849781SMoriah.Waterland@Sun.COM * zone - regardless of whether or not they need to be 9859781SMoriah.Waterland@Sun.COM * updated (installed/copied). If no paths are inherited 9869781SMoriah.Waterland@Sun.COM * from the global zone, this is always set when a path 9879781SMoriah.Waterland@Sun.COM * to be installed already exists and has the correct 9889781SMoriah.Waterland@Sun.COM * contents. 9899781SMoriah.Waterland@Sun.COM * Returns: int 9909781SMoriah.Waterland@Sun.COM * != DMRG_DONE - index into extlist of the next path to 9919781SMoriah.Waterland@Sun.COM * be processed - that needs to be installed/copied 9929781SMoriah.Waterland@Sun.COM * == DMRG_DONE - all entries processed 9939781SMoriah.Waterland@Sun.COM */ 9949781SMoriah.Waterland@Sun.COM 9959781SMoriah.Waterland@Sun.COM static int 9969781SMoriah.Waterland@Sun.COM domerg(struct cfextra **extlist, int part, int nparts, 9979781SMoriah.Waterland@Sun.COM int myclass, char **srcp, char **dstp, 9989781SMoriah.Waterland@Sun.COM char **r_updated, char **r_skipped, 9999781SMoriah.Waterland@Sun.COM char **r_anyPathLocal) 10009781SMoriah.Waterland@Sun.COM { 10019781SMoriah.Waterland@Sun.COM boolean_t stateFlag = B_FALSE; 10029781SMoriah.Waterland@Sun.COM int i; 10039781SMoriah.Waterland@Sun.COM int msg_ugid; 10049781SMoriah.Waterland@Sun.COM static int maxvol = 0; 10059781SMoriah.Waterland@Sun.COM static int svindx = 0; 10069781SMoriah.Waterland@Sun.COM static int svpart = 0; 10079781SMoriah.Waterland@Sun.COM struct cfent *ept = (struct cfent *)NULL; 10089781SMoriah.Waterland@Sun.COM struct mergstat *mstat = (struct mergstat *)NULL; 10099781SMoriah.Waterland@Sun.COM 10109781SMoriah.Waterland@Sun.COM /* reset returned path pointers */ 10119781SMoriah.Waterland@Sun.COM 10129781SMoriah.Waterland@Sun.COM *dstp = (char *)NULL; 10139781SMoriah.Waterland@Sun.COM *srcp = (char *)NULL; 10149781SMoriah.Waterland@Sun.COM 10159781SMoriah.Waterland@Sun.COM /* set to start or continue based on which part being processed */ 10169781SMoriah.Waterland@Sun.COM 10179781SMoriah.Waterland@Sun.COM if (part != 0) { 10189781SMoriah.Waterland@Sun.COM maxvol = 0; 10199781SMoriah.Waterland@Sun.COM svindx = 0; 10209781SMoriah.Waterland@Sun.COM svpart = part; 10219781SMoriah.Waterland@Sun.COM } else { 10229781SMoriah.Waterland@Sun.COM i = svindx; 10239781SMoriah.Waterland@Sun.COM part = svpart; 10249781SMoriah.Waterland@Sun.COM } 10259781SMoriah.Waterland@Sun.COM 10269781SMoriah.Waterland@Sun.COM /* 10279781SMoriah.Waterland@Sun.COM * This goes through the pkgmap entries one by one testing them 10289781SMoriah.Waterland@Sun.COM * for inclusion in the package database as well as for validity 10299781SMoriah.Waterland@Sun.COM * against existing files. 10309781SMoriah.Waterland@Sun.COM */ 10319781SMoriah.Waterland@Sun.COM for (i = svindx; extlist[i]; i++) { 10329781SMoriah.Waterland@Sun.COM ept = &(extlist[i]->cf_ent); 10339781SMoriah.Waterland@Sun.COM mstat = &(extlist[i]->mstat); 10349781SMoriah.Waterland@Sun.COM 10359781SMoriah.Waterland@Sun.COM /* 10369781SMoriah.Waterland@Sun.COM * as paths are processed, if the "anyPathLocal" flag has not 10379781SMoriah.Waterland@Sun.COM * been set, if the object is not of type 'i' (package script), 10389781SMoriah.Waterland@Sun.COM * check to see if the object is in an area inherited from the 10399781SMoriah.Waterland@Sun.COM * global zone - if not, set "anyPathLocal" to the path found, 10409781SMoriah.Waterland@Sun.COM * indicating that at least one path is in an area that is not 10419781SMoriah.Waterland@Sun.COM * inherited from the global zone. 10429781SMoriah.Waterland@Sun.COM */ 10439781SMoriah.Waterland@Sun.COM 10449781SMoriah.Waterland@Sun.COM if ((r_anyPathLocal != (char **)NULL) && 10459781SMoriah.Waterland@Sun.COM (*r_anyPathLocal == (char *)NULL) && 10469781SMoriah.Waterland@Sun.COM (ept->ftype != 'i') && 10479781SMoriah.Waterland@Sun.COM (z_path_is_inherited(ept->path, ept->ftype, 10489781SMoriah.Waterland@Sun.COM get_inst_root()) == B_FALSE)) { 10499781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_LOCAL, ept->path); 10509781SMoriah.Waterland@Sun.COM *r_anyPathLocal = ept->path; 10519781SMoriah.Waterland@Sun.COM } 10529781SMoriah.Waterland@Sun.COM 10539781SMoriah.Waterland@Sun.COM /* if this isn't the class of current interest, skip it */ 10549781SMoriah.Waterland@Sun.COM 10559781SMoriah.Waterland@Sun.COM if (myclass != ept->pkg_class_idx) { 10569781SMoriah.Waterland@Sun.COM continue; 10579781SMoriah.Waterland@Sun.COM } 10589781SMoriah.Waterland@Sun.COM 10599781SMoriah.Waterland@Sun.COM /* if the class is invalid, announce it & exit */ 10609781SMoriah.Waterland@Sun.COM if (ept->pkg_class_idx == -1) { 10619781SMoriah.Waterland@Sun.COM progerr(ERR_CLIDX, ept->pkg_class_idx, 10629781SMoriah.Waterland@Sun.COM (ept->path && *ept->path) ? ept->path : "unknown"); 1063*9869SCasper.Dik@Sun.COM logerr(gettext("pathname=%s"), 10649781SMoriah.Waterland@Sun.COM (ept->path && *ept->path) ? ept->path : "unknown"); 1065*9869SCasper.Dik@Sun.COM logerr(gettext("class=<%s>"), 10669781SMoriah.Waterland@Sun.COM (ept->pkg_class && *ept->pkg_class) ? 10679781SMoriah.Waterland@Sun.COM ept->pkg_class : "Unknown"); 1068*9869SCasper.Dik@Sun.COM logerr(gettext("CLASSES=<%s>"), 10699781SMoriah.Waterland@Sun.COM getenv("CLASSES") ? getenv("CLASSES") : "Not Set"); 10709781SMoriah.Waterland@Sun.COM quit(99); 10719781SMoriah.Waterland@Sun.COM } 10729781SMoriah.Waterland@Sun.COM 10739781SMoriah.Waterland@Sun.COM /* 10749781SMoriah.Waterland@Sun.COM * Next check to see if we are going to try to delete a 10759781SMoriah.Waterland@Sun.COM * populated directory in some distressing way. 10769781SMoriah.Waterland@Sun.COM */ 10779781SMoriah.Waterland@Sun.COM if (mstat->dir2nondir) 10789781SMoriah.Waterland@Sun.COM if (dir_is_populated(ept->path)) { 10799781SMoriah.Waterland@Sun.COM logerr(WRN_INSTVOL_NOTDIR, ept->path); 10809781SMoriah.Waterland@Sun.COM warnflag++; 10819781SMoriah.Waterland@Sun.COM mstat->denied = 1; /* install denied! */ 10829781SMoriah.Waterland@Sun.COM continue; 10839781SMoriah.Waterland@Sun.COM } else { /* Replace is OK. */ 10849781SMoriah.Waterland@Sun.COM /* 10859781SMoriah.Waterland@Sun.COM * Remove this directory, so it won't 10869781SMoriah.Waterland@Sun.COM * interfere with creation of the new object. 10879781SMoriah.Waterland@Sun.COM */ 10889781SMoriah.Waterland@Sun.COM if (rmdir(ept->path)) { 10899781SMoriah.Waterland@Sun.COM /* 10909781SMoriah.Waterland@Sun.COM * If it didn't work, there's nothing 10919781SMoriah.Waterland@Sun.COM * we can do. To continue would 10929781SMoriah.Waterland@Sun.COM * likely corrupt the filesystem 10939781SMoriah.Waterland@Sun.COM * which is unacceptable. 10949781SMoriah.Waterland@Sun.COM */ 10959781SMoriah.Waterland@Sun.COM progerr(ERR_RMDIR, ept->path); 10969781SMoriah.Waterland@Sun.COM quit(99); 10979781SMoriah.Waterland@Sun.COM } 10989781SMoriah.Waterland@Sun.COM 10999781SMoriah.Waterland@Sun.COM repl_permitted = 1; /* flag it */ 11009781SMoriah.Waterland@Sun.COM } 11019781SMoriah.Waterland@Sun.COM 11029781SMoriah.Waterland@Sun.COM /* adjust the max volume number appropriately */ 11039781SMoriah.Waterland@Sun.COM 11049781SMoriah.Waterland@Sun.COM if (ept->volno > maxvol) { 11059781SMoriah.Waterland@Sun.COM maxvol = ept->volno; 11069781SMoriah.Waterland@Sun.COM } 11079781SMoriah.Waterland@Sun.COM 11089781SMoriah.Waterland@Sun.COM /* if this part goes into another volume, skip it */ 11099781SMoriah.Waterland@Sun.COM 11109781SMoriah.Waterland@Sun.COM if (part != ept->volno) { 11119781SMoriah.Waterland@Sun.COM continue; 11129781SMoriah.Waterland@Sun.COM } 11139781SMoriah.Waterland@Sun.COM 11149781SMoriah.Waterland@Sun.COM /* 11159781SMoriah.Waterland@Sun.COM * If it's a conflicting file and it's not supposed to be 11169781SMoriah.Waterland@Sun.COM * installed, note it and skip. 11179781SMoriah.Waterland@Sun.COM */ 11189781SMoriah.Waterland@Sun.COM if (nocnflct && mstat->shared && ept->ftype != 'e') { 11199781SMoriah.Waterland@Sun.COM if (mstat->contchg || mstat->attrchg) { 11209781SMoriah.Waterland@Sun.COM echo(MSG_SHIGN, ept->path); 11219781SMoriah.Waterland@Sun.COM } 11229781SMoriah.Waterland@Sun.COM continue; 11239781SMoriah.Waterland@Sun.COM } 11249781SMoriah.Waterland@Sun.COM 11259781SMoriah.Waterland@Sun.COM /* 11269781SMoriah.Waterland@Sun.COM * If we want to set uid or gid but user says no, note it. 11279781SMoriah.Waterland@Sun.COM * Remember that the actual mode bits in the structure have 11289781SMoriah.Waterland@Sun.COM * already been adjusted and the mstat flag is telling us 11299781SMoriah.Waterland@Sun.COM * about the original mode. 11309781SMoriah.Waterland@Sun.COM */ 11319781SMoriah.Waterland@Sun.COM if (nosetuid && (mstat->setuid || mstat->setgid)) { 11329781SMoriah.Waterland@Sun.COM msg_ugid = 1; /* don't repeat attribute message. */ 11339781SMoriah.Waterland@Sun.COM if (is_fs_writeable(ept->path, 11349781SMoriah.Waterland@Sun.COM &(extlist[i]->fsys_value))) { 11359781SMoriah.Waterland@Sun.COM if (!(mstat->contchg) && mstat->attrchg) { 11369781SMoriah.Waterland@Sun.COM echo(MSG_UGMOD, ept->path); 11379781SMoriah.Waterland@Sun.COM } else { 11389781SMoriah.Waterland@Sun.COM echo(MSG_UGID, ept->path); 11399781SMoriah.Waterland@Sun.COM } 11409781SMoriah.Waterland@Sun.COM } 11419781SMoriah.Waterland@Sun.COM } else { 11429781SMoriah.Waterland@Sun.COM msg_ugid = 0; 11439781SMoriah.Waterland@Sun.COM } 11449781SMoriah.Waterland@Sun.COM 11459781SMoriah.Waterland@Sun.COM switch (ept->ftype) { 11469781SMoriah.Waterland@Sun.COM case 'l': /* hard link */ 11479781SMoriah.Waterland@Sun.COM /* links treated as object "update/skip" */ 11489781SMoriah.Waterland@Sun.COM stateFlag = B_TRUE; 11499781SMoriah.Waterland@Sun.COM continue; /* defer to final proc */ 11509781SMoriah.Waterland@Sun.COM 11519781SMoriah.Waterland@Sun.COM case 's': /* for symlink, verify without fix first */ 11529781SMoriah.Waterland@Sun.COM /* links treated as object "update/skip" */ 11539781SMoriah.Waterland@Sun.COM stateFlag = B_TRUE; 11549781SMoriah.Waterland@Sun.COM 11559781SMoriah.Waterland@Sun.COM /* Do this only for default verify */ 11569781SMoriah.Waterland@Sun.COM if (cl_dvfy(myclass) == DEFAULT) { 11579781SMoriah.Waterland@Sun.COM if (averify(0, &ept->ftype, 11589781SMoriah.Waterland@Sun.COM ept->path, &ept->ainfo)) 11599781SMoriah.Waterland@Sun.COM echo(MSG_SLINK, ept->path); 11609781SMoriah.Waterland@Sun.COM } 11619781SMoriah.Waterland@Sun.COM 11629781SMoriah.Waterland@Sun.COM /*FALLTHRU*/ 11639781SMoriah.Waterland@Sun.COM 11649781SMoriah.Waterland@Sun.COM case 'd': /* directory */ 11659781SMoriah.Waterland@Sun.COM case 'x': /* exclusive directory */ 11669781SMoriah.Waterland@Sun.COM case 'c': /* character special device */ 11679781SMoriah.Waterland@Sun.COM case 'b': /* block special device */ 11689781SMoriah.Waterland@Sun.COM case 'p': /* named pipe */ 11699781SMoriah.Waterland@Sun.COM /* these NOT treated as object "update/skip" */ 11709781SMoriah.Waterland@Sun.COM stateFlag = B_FALSE; 11719781SMoriah.Waterland@Sun.COM 11729781SMoriah.Waterland@Sun.COM /* 11739781SMoriah.Waterland@Sun.COM * If we can't get to it for legitimate reasons, 11749781SMoriah.Waterland@Sun.COM * don't try to verify it. 11759781SMoriah.Waterland@Sun.COM */ 11769781SMoriah.Waterland@Sun.COM if ((z_path_is_inherited(ept->path, ept->ftype, 11779781SMoriah.Waterland@Sun.COM get_inst_root())) || 11789781SMoriah.Waterland@Sun.COM is_remote_fs(ept->path, 11799781SMoriah.Waterland@Sun.COM &(extlist[i]->fsys_value)) && 11809781SMoriah.Waterland@Sun.COM !is_fs_writeable(ept->path, 11819781SMoriah.Waterland@Sun.COM &(extlist[i]->fsys_value))) { 11829781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 11839781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 11849781SMoriah.Waterland@Sun.COM break; 11859781SMoriah.Waterland@Sun.COM } 11869781SMoriah.Waterland@Sun.COM 11879781SMoriah.Waterland@Sun.COM if (averify(1, &ept->ftype, ept->path, 11889781SMoriah.Waterland@Sun.COM &ept->ainfo) == 0) { 11899781SMoriah.Waterland@Sun.COM mstat->contchg = mstat->attrchg = 0; 11909781SMoriah.Waterland@Sun.COM } else { 11919781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PKGOBJ, ept->path); 11929781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr()); 11939781SMoriah.Waterland@Sun.COM warnflag++; 11949781SMoriah.Waterland@Sun.COM } 11959781SMoriah.Waterland@Sun.COM 11969781SMoriah.Waterland@Sun.COM break; 11979781SMoriah.Waterland@Sun.COM 11989781SMoriah.Waterland@Sun.COM case 'i': /* information file */ 11999781SMoriah.Waterland@Sun.COM /* not treated as object "update/skip" */ 12009781SMoriah.Waterland@Sun.COM stateFlag = B_FALSE; 12019781SMoriah.Waterland@Sun.COM break; 12029781SMoriah.Waterland@Sun.COM 12039781SMoriah.Waterland@Sun.COM default: 12049781SMoriah.Waterland@Sun.COM /* all files treated as object "update/skip" */ 12059781SMoriah.Waterland@Sun.COM stateFlag = B_TRUE; 12069781SMoriah.Waterland@Sun.COM break; 12079781SMoriah.Waterland@Sun.COM } 12089781SMoriah.Waterland@Sun.COM 12099781SMoriah.Waterland@Sun.COM /* 12109781SMoriah.Waterland@Sun.COM * Both contchg and shared flags have to be taken into 12119781SMoriah.Waterland@Sun.COM * account. contchg is set if the file is already present 12129781SMoriah.Waterland@Sun.COM * in the package database, if it does not exist or if it 12139781SMoriah.Waterland@Sun.COM * exists and is modified. 12149781SMoriah.Waterland@Sun.COM * The shared flag is set when 'e' or 'v' file is not 12159781SMoriah.Waterland@Sun.COM * present in the package database, exists and is not 12169781SMoriah.Waterland@Sun.COM * modified. It also has to be checked here. 12179781SMoriah.Waterland@Sun.COM * Shared flag is also set when file is present in package 12189781SMoriah.Waterland@Sun.COM * database and owned by more than one package, but for 12199781SMoriah.Waterland@Sun.COM * this case contchg has already been set. 12209781SMoriah.Waterland@Sun.COM */ 12219781SMoriah.Waterland@Sun.COM if (mstat->contchg || (mstat->shared && 12229781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || (ept->ftype == 'v')))) { 12239781SMoriah.Waterland@Sun.COM *dstp = ept->path; 12249781SMoriah.Waterland@Sun.COM if ((ept->ftype == 'f') || (ept->ftype == 'e') || 12259781SMoriah.Waterland@Sun.COM (ept->ftype == 'v')) { 12269781SMoriah.Waterland@Sun.COM *srcp = ept->ainfo.local; 12279781SMoriah.Waterland@Sun.COM if (is_partial_inst() != 0) { 12289781SMoriah.Waterland@Sun.COM if (*srcp[0] == '~') { 12299781SMoriah.Waterland@Sun.COM /* translate source pathname */ 12309781SMoriah.Waterland@Sun.COM *srcp = srcpath(instdir, 12319781SMoriah.Waterland@Sun.COM extlist[i]->map_path, 12329781SMoriah.Waterland@Sun.COM part, nparts); 12339781SMoriah.Waterland@Sun.COM } else { 12349781SMoriah.Waterland@Sun.COM *srcp = extlist[i]->map_path; 12359781SMoriah.Waterland@Sun.COM } 12369781SMoriah.Waterland@Sun.COM } else { 12379781SMoriah.Waterland@Sun.COM if (*srcp[0] == '~') { 12389781SMoriah.Waterland@Sun.COM /* translate source pathname */ 12399781SMoriah.Waterland@Sun.COM *srcp = srcpath(instdir, 12409781SMoriah.Waterland@Sun.COM &(ept->ainfo.local[1]), 12419781SMoriah.Waterland@Sun.COM part, nparts); 12429781SMoriah.Waterland@Sun.COM } 12439781SMoriah.Waterland@Sun.COM } 12449781SMoriah.Waterland@Sun.COM 12459781SMoriah.Waterland@Sun.COM echoDebug(DBG_DOMERG_NO_SUCH_FILE, 12469781SMoriah.Waterland@Sun.COM ept->ftype, cl_nam(ept->pkg_class_idx), 12479781SMoriah.Waterland@Sun.COM ept->path); 12489781SMoriah.Waterland@Sun.COM } else { 12499781SMoriah.Waterland@Sun.COM /* 12509781SMoriah.Waterland@Sun.COM * At this point, we're returning a non-file 12519781SMoriah.Waterland@Sun.COM * that couldn't be created in the standard 12529781SMoriah.Waterland@Sun.COM * way. If it refers to a filesystem that is 12539781SMoriah.Waterland@Sun.COM * not writeable by us, don't waste the 12549781SMoriah.Waterland@Sun.COM * calling process's time. 12559781SMoriah.Waterland@Sun.COM */ 12569781SMoriah.Waterland@Sun.COM if (!is_fs_writeable(ept->path, 12579781SMoriah.Waterland@Sun.COM &(extlist[i]->fsys_value))) { 12589781SMoriah.Waterland@Sun.COM echoDebug(DBG_DOMERG_NOT_WRITABLE, 12599781SMoriah.Waterland@Sun.COM ept->ftype, 12609781SMoriah.Waterland@Sun.COM cl_nam(ept->pkg_class_idx), 12619781SMoriah.Waterland@Sun.COM ept->path); 12629781SMoriah.Waterland@Sun.COM continue; 12639781SMoriah.Waterland@Sun.COM } 12649781SMoriah.Waterland@Sun.COM 12659781SMoriah.Waterland@Sun.COM *srcp = NULL; 12669781SMoriah.Waterland@Sun.COM echoDebug(DBG_DOMERG_NOT_THERE, 12679781SMoriah.Waterland@Sun.COM ept->ftype, cl_nam(ept->pkg_class_idx), 12689781SMoriah.Waterland@Sun.COM ept->path); 12699781SMoriah.Waterland@Sun.COM } 12709781SMoriah.Waterland@Sun.COM 12719781SMoriah.Waterland@Sun.COM svindx = i+1; 12729781SMoriah.Waterland@Sun.COM backup(*dstp, 1); 12739781SMoriah.Waterland@Sun.COM return (i); 12749781SMoriah.Waterland@Sun.COM } 12759781SMoriah.Waterland@Sun.COM 12769781SMoriah.Waterland@Sun.COM if (mstat->attrchg) { 12779781SMoriah.Waterland@Sun.COM backup(ept->path, 0); 12789781SMoriah.Waterland@Sun.COM if (!msg_ugid) 12799781SMoriah.Waterland@Sun.COM echo(MSG_ATTRIB, ept->path); 12809781SMoriah.Waterland@Sun.COM 12819781SMoriah.Waterland@Sun.COM /* fix the attributes now for robustness sake */ 12829781SMoriah.Waterland@Sun.COM if (averify(1, &ept->ftype, 12839781SMoriah.Waterland@Sun.COM ept->path, 12849781SMoriah.Waterland@Sun.COM &ept->ainfo) == 0) { 12859781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 12869781SMoriah.Waterland@Sun.COM } 12879781SMoriah.Waterland@Sun.COM } 12889781SMoriah.Waterland@Sun.COM 12899781SMoriah.Waterland@Sun.COM /* 12909781SMoriah.Waterland@Sun.COM * package object exists, or does not need updating: if the path 12919781SMoriah.Waterland@Sun.COM * is in an area inherited from the global zone, then treat 12929781SMoriah.Waterland@Sun.COM * the object as if it were "skipped" - if the path is not in an 12939781SMoriah.Waterland@Sun.COM * area inherited from the global zone, then treat the object as 12949781SMoriah.Waterland@Sun.COM * if it were "updated" 12959781SMoriah.Waterland@Sun.COM */ 12969781SMoriah.Waterland@Sun.COM 12979781SMoriah.Waterland@Sun.COM /* LINTED warning: statement has no consequent: if */ 12989781SMoriah.Waterland@Sun.COM if ((stateFlag == B_FALSE) || (ept == (struct cfent *)NULL)) { 12999781SMoriah.Waterland@Sun.COM /* 13009781SMoriah.Waterland@Sun.COM * the object in question is a directory or special 13019781SMoriah.Waterland@Sun.COM * file - the fact that this type of object already 13029781SMoriah.Waterland@Sun.COM * exists or does not need updating must not trigger 13039781SMoriah.Waterland@Sun.COM * the object updated/object skipped indication - 13049781SMoriah.Waterland@Sun.COM * that would cause class action scripts to be run 13059781SMoriah.Waterland@Sun.COM * when installing a new non-global zone - that action 13069781SMoriah.Waterland@Sun.COM * must only be done when a file object that is in 13079781SMoriah.Waterland@Sun.COM * an area inherited from the global zone is present. 13089781SMoriah.Waterland@Sun.COM */ 13099781SMoriah.Waterland@Sun.COM } else if (z_path_is_inherited(ept->path, ept->ftype, 13109781SMoriah.Waterland@Sun.COM get_inst_root()) == B_TRUE) { 13119781SMoriah.Waterland@Sun.COM if (r_skipped != (char **)NULL) { 13129781SMoriah.Waterland@Sun.COM if (*r_skipped == (char *)NULL) { 13139781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_SKIPPED, 13149781SMoriah.Waterland@Sun.COM ept->path); 13159781SMoriah.Waterland@Sun.COM *r_skipped = ept->path; 13169781SMoriah.Waterland@Sun.COM } 13179781SMoriah.Waterland@Sun.COM } 13189781SMoriah.Waterland@Sun.COM } else { 13199781SMoriah.Waterland@Sun.COM if (r_updated != (char **)NULL) { 13209781SMoriah.Waterland@Sun.COM if (*r_updated == (char *)NULL) { 13219781SMoriah.Waterland@Sun.COM echoDebug(DBG_INSTVOL_OBJ_UPDATED, 13229781SMoriah.Waterland@Sun.COM ept->path); 13239781SMoriah.Waterland@Sun.COM } 13249781SMoriah.Waterland@Sun.COM *r_updated = ept->path; 13259781SMoriah.Waterland@Sun.COM } 13269781SMoriah.Waterland@Sun.COM } 13279781SMoriah.Waterland@Sun.COM } 13289781SMoriah.Waterland@Sun.COM 13299781SMoriah.Waterland@Sun.COM if (maxvol == part) { 13309781SMoriah.Waterland@Sun.COM eocflag++; /* endofclass */ 13319781SMoriah.Waterland@Sun.COM } 13329781SMoriah.Waterland@Sun.COM 13339781SMoriah.Waterland@Sun.COM return (DMRG_DONE); /* no remaining entries on this volume */ 13349781SMoriah.Waterland@Sun.COM } 13359781SMoriah.Waterland@Sun.COM 13369781SMoriah.Waterland@Sun.COM /* 13379781SMoriah.Waterland@Sun.COM * Determine if the provided directory is populated. Return 0 if so and 1 if 13389781SMoriah.Waterland@Sun.COM * not. This also returns 0 if the dirpath is not a directory or if it does 13399781SMoriah.Waterland@Sun.COM * not exist. 13409781SMoriah.Waterland@Sun.COM */ 13419781SMoriah.Waterland@Sun.COM static int 13429781SMoriah.Waterland@Sun.COM dir_is_populated(char *dirpath) { 13439781SMoriah.Waterland@Sun.COM DIR *dirfp; 13449781SMoriah.Waterland@Sun.COM struct dirent *drp; 13459781SMoriah.Waterland@Sun.COM int retcode = 0; 13469781SMoriah.Waterland@Sun.COM 13479781SMoriah.Waterland@Sun.COM if ((dirfp = opendir(dirpath)) != NULL) { 13489781SMoriah.Waterland@Sun.COM while ((drp = readdir(dirfp)) != NULL) { 13499781SMoriah.Waterland@Sun.COM if (strcmp(drp->d_name, ".") == 0) { 13509781SMoriah.Waterland@Sun.COM continue; 13519781SMoriah.Waterland@Sun.COM } 13529781SMoriah.Waterland@Sun.COM if (strcmp(drp->d_name, "..") == 0) { 13539781SMoriah.Waterland@Sun.COM continue; 13549781SMoriah.Waterland@Sun.COM } 13559781SMoriah.Waterland@Sun.COM /* 13569781SMoriah.Waterland@Sun.COM * If we get here, there's a real file in the 13579781SMoriah.Waterland@Sun.COM * directory 13589781SMoriah.Waterland@Sun.COM */ 13599781SMoriah.Waterland@Sun.COM retcode = 1; 13609781SMoriah.Waterland@Sun.COM break; 13619781SMoriah.Waterland@Sun.COM } 13629781SMoriah.Waterland@Sun.COM (void) closedir(dirfp); 13639781SMoriah.Waterland@Sun.COM } 13649781SMoriah.Waterland@Sun.COM 13659781SMoriah.Waterland@Sun.COM return (retcode); 13669781SMoriah.Waterland@Sun.COM } 13679781SMoriah.Waterland@Sun.COM 13689781SMoriah.Waterland@Sun.COM /* 13699781SMoriah.Waterland@Sun.COM * This is the function that cleans up the installation of this class. 13709781SMoriah.Waterland@Sun.COM * This is where hard links get put in since the stuff they're linking 13719781SMoriah.Waterland@Sun.COM * probably exists by now. 13729781SMoriah.Waterland@Sun.COM */ 13739781SMoriah.Waterland@Sun.COM static void 13749781SMoriah.Waterland@Sun.COM endofclass(struct cfextra **extlist, int myclass, int ckflag, 1375*9869SCasper.Dik@Sun.COM PKGserver pkgserver, VFP_T **a_cfTmpVfp) 13769781SMoriah.Waterland@Sun.COM { 13779781SMoriah.Waterland@Sun.COM char *temppath; 13789781SMoriah.Waterland@Sun.COM char *pspool_loc; 13799781SMoriah.Waterland@Sun.COM char *relocpath = (char *)NULL; 13809781SMoriah.Waterland@Sun.COM char scrpt_dst[PATH_MAX]; 13819781SMoriah.Waterland@Sun.COM int flag; 13829781SMoriah.Waterland@Sun.COM int idx; 13839781SMoriah.Waterland@Sun.COM int n; 13849781SMoriah.Waterland@Sun.COM struct cfent *ept; /* entry from the internal list */ 13859781SMoriah.Waterland@Sun.COM struct cfextra entry; /* entry from the package database */ 13869781SMoriah.Waterland@Sun.COM struct mergstat *mstat; /* merge status */ 13879781SMoriah.Waterland@Sun.COM struct pinfo *pinfo; 13889781SMoriah.Waterland@Sun.COM 13899781SMoriah.Waterland@Sun.COM /* open the package database (contents) file */ 13909781SMoriah.Waterland@Sun.COM 1391*9869SCasper.Dik@Sun.COM if (!ocfile(&pkgserver, a_cfTmpVfp, pkgmap_blks)) { 13929781SMoriah.Waterland@Sun.COM quit(99); 13939781SMoriah.Waterland@Sun.COM } 13949781SMoriah.Waterland@Sun.COM 13959781SMoriah.Waterland@Sun.COM echo(MSG_VERIFYING_CLASS, cl_nam(myclass)); 13969781SMoriah.Waterland@Sun.COM 13979781SMoriah.Waterland@Sun.COM for (idx = 0; /* void */; idx++) { 13989781SMoriah.Waterland@Sun.COM /* find next package object in this class */ 13999781SMoriah.Waterland@Sun.COM while (extlist[idx]) { 14009781SMoriah.Waterland@Sun.COM if ((extlist[idx]->cf_ent.ftype != 'i') && 14019781SMoriah.Waterland@Sun.COM extlist[idx]->cf_ent.pkg_class_idx == myclass) { 14029781SMoriah.Waterland@Sun.COM break; 14039781SMoriah.Waterland@Sun.COM } 14049781SMoriah.Waterland@Sun.COM idx++; 14059781SMoriah.Waterland@Sun.COM } 14069781SMoriah.Waterland@Sun.COM 1407*9869SCasper.Dik@Sun.COM if (extlist[idx] == NULL) 14089781SMoriah.Waterland@Sun.COM break; 1409*9869SCasper.Dik@Sun.COM 14109781SMoriah.Waterland@Sun.COM 14119781SMoriah.Waterland@Sun.COM ept = &(extlist[idx]->cf_ent); 14129781SMoriah.Waterland@Sun.COM mstat = &(extlist[idx]->mstat); 14139781SMoriah.Waterland@Sun.COM 1414*9869SCasper.Dik@Sun.COM temppath = extlist[idx]->client_path; 14159781SMoriah.Waterland@Sun.COM 14169781SMoriah.Waterland@Sun.COM /* 14179781SMoriah.Waterland@Sun.COM * At this point the only difference between the entry 14189781SMoriah.Waterland@Sun.COM * in the contents file and the entry in extlist[] is 14199781SMoriah.Waterland@Sun.COM * that the status indicator contains CONFIRM_CONT. 1420*9869SCasper.Dik@Sun.COM * This function should return one or something is wrong. 14219781SMoriah.Waterland@Sun.COM */ 14229781SMoriah.Waterland@Sun.COM 1423*9869SCasper.Dik@Sun.COM n = srchcfile(&(entry.cf_ent), temppath, pkgserver); 14249781SMoriah.Waterland@Sun.COM 1425*9869SCasper.Dik@Sun.COM if (n < 0) { 14269781SMoriah.Waterland@Sun.COM char *errstr = getErrstr(); 14279781SMoriah.Waterland@Sun.COM progerr(ERR_CFBAD); 1428*9869SCasper.Dik@Sun.COM logerr(gettext("pathname=%s"), 14299781SMoriah.Waterland@Sun.COM entry.cf_ent.path && *entry.cf_ent.path ? 14309781SMoriah.Waterland@Sun.COM entry.cf_ent.path : "Unknown"); 1431*9869SCasper.Dik@Sun.COM logerr(gettext("problem=%s"), 14329781SMoriah.Waterland@Sun.COM (errstr && *errstr) ? errstr : "Unknown"); 14339781SMoriah.Waterland@Sun.COM quit(99); 14349781SMoriah.Waterland@Sun.COM } else if (n != 1) { 14359781SMoriah.Waterland@Sun.COM /* 14369781SMoriah.Waterland@Sun.COM * Check if path should be in the package 14379781SMoriah.Waterland@Sun.COM * database. 14389781SMoriah.Waterland@Sun.COM */ 14399781SMoriah.Waterland@Sun.COM if ((mstat->shared && nocnflct)) { 14409781SMoriah.Waterland@Sun.COM continue; 14419781SMoriah.Waterland@Sun.COM } 14429781SMoriah.Waterland@Sun.COM progerr(ERR_CFMISSING, ept->path); 14439781SMoriah.Waterland@Sun.COM quit(99); 14449781SMoriah.Waterland@Sun.COM } 14459781SMoriah.Waterland@Sun.COM 14469781SMoriah.Waterland@Sun.COM /* 14479781SMoriah.Waterland@Sun.COM * If merge was not appropriate for this object, now is the 14489781SMoriah.Waterland@Sun.COM * time to choose one or the other. 14499781SMoriah.Waterland@Sun.COM */ 14509781SMoriah.Waterland@Sun.COM if (mstat->denied) { 14519781SMoriah.Waterland@Sun.COM /* 14529781SMoriah.Waterland@Sun.COM * If installation was denied AFTER the package 14539781SMoriah.Waterland@Sun.COM * database was updated, skip this. We've already 14549781SMoriah.Waterland@Sun.COM * announced the discrepancy and the verifications 14559781SMoriah.Waterland@Sun.COM * that follow will make faulty decisions based on 14569781SMoriah.Waterland@Sun.COM * the ftype, which may not be correct. 14579781SMoriah.Waterland@Sun.COM */ 14589781SMoriah.Waterland@Sun.COM progerr(ERR_COULD_NOT_INSTALL, ept->path); 14599781SMoriah.Waterland@Sun.COM warnflag++; 14609781SMoriah.Waterland@Sun.COM } else { 14619781SMoriah.Waterland@Sun.COM if (mstat->replace) 14629781SMoriah.Waterland@Sun.COM /* 14639781SMoriah.Waterland@Sun.COM * This replaces the old entry with the new 14649781SMoriah.Waterland@Sun.COM * one. This should never happen in the new 14659781SMoriah.Waterland@Sun.COM * DB since the entries are already identical. 14669781SMoriah.Waterland@Sun.COM */ 14679781SMoriah.Waterland@Sun.COM repl_cfent(ept, &(entry.cf_ent)); 14689781SMoriah.Waterland@Sun.COM 14699781SMoriah.Waterland@Sun.COM /* 14709781SMoriah.Waterland@Sun.COM * Validate this entry and change the status flag in 14719781SMoriah.Waterland@Sun.COM * the package database. 14729781SMoriah.Waterland@Sun.COM */ 14739781SMoriah.Waterland@Sun.COM if (ept->ftype == RM_RDY) { 14749781SMoriah.Waterland@Sun.COM (void) eptstat(&(entry.cf_ent), pkginst, 14759781SMoriah.Waterland@Sun.COM STAT_NEXT); 14769781SMoriah.Waterland@Sun.COM } else { 14779781SMoriah.Waterland@Sun.COM /* check the hard link now. */ 14789781SMoriah.Waterland@Sun.COM if (ept->ftype == 'l') { 14799781SMoriah.Waterland@Sun.COM if (averify(0, &ept->ftype, 14809781SMoriah.Waterland@Sun.COM ept->path, &ept->ainfo)) { 14819781SMoriah.Waterland@Sun.COM echo(MSG_HRDLINK, 14829781SMoriah.Waterland@Sun.COM ept->path); 14839781SMoriah.Waterland@Sun.COM mstat->attrchg++; 14849781SMoriah.Waterland@Sun.COM } 14859781SMoriah.Waterland@Sun.COM } 14869781SMoriah.Waterland@Sun.COM 14879781SMoriah.Waterland@Sun.COM /* 14889781SMoriah.Waterland@Sun.COM * Don't install or verify objects for 14899781SMoriah.Waterland@Sun.COM * remote, read-only filesystems. We need 14909781SMoriah.Waterland@Sun.COM * only flag them as shared from some server. 14919781SMoriah.Waterland@Sun.COM * Otherwise, ok to do final check. 14929781SMoriah.Waterland@Sun.COM */ 14939781SMoriah.Waterland@Sun.COM if (is_remote_fs(ept->path, 14949781SMoriah.Waterland@Sun.COM &(extlist[idx]->fsys_value)) && 14959781SMoriah.Waterland@Sun.COM !is_fs_writeable(ept->path, 14969781SMoriah.Waterland@Sun.COM &(extlist[idx]->fsys_value))) { 14979781SMoriah.Waterland@Sun.COM flag = -1; 14989781SMoriah.Waterland@Sun.COM } else { 14999781SMoriah.Waterland@Sun.COM boolean_t inheritedFlag; 15009781SMoriah.Waterland@Sun.COM inheritedFlag = 15019781SMoriah.Waterland@Sun.COM z_path_is_inherited(ept->path, 15029781SMoriah.Waterland@Sun.COM ept->ftype, get_inst_root()); 15039781SMoriah.Waterland@Sun.COM flag = finalck(ept, mstat->attrchg, 15049781SMoriah.Waterland@Sun.COM (ckflag ? mstat->contchg : 15059781SMoriah.Waterland@Sun.COM (-1)), inheritedFlag); 15069781SMoriah.Waterland@Sun.COM } 15079781SMoriah.Waterland@Sun.COM 15089781SMoriah.Waterland@Sun.COM pinfo = entry.cf_ent.pinfo; 15099781SMoriah.Waterland@Sun.COM 15109781SMoriah.Waterland@Sun.COM /* Find this package in the list. */ 15119781SMoriah.Waterland@Sun.COM while (pinfo) { 15129781SMoriah.Waterland@Sun.COM if (strcmp(pkginst, pinfo->pkg) == 0) { 15139781SMoriah.Waterland@Sun.COM break; 15149781SMoriah.Waterland@Sun.COM } 15159781SMoriah.Waterland@Sun.COM pinfo = pinfo->next; 15169781SMoriah.Waterland@Sun.COM } 15179781SMoriah.Waterland@Sun.COM 15189781SMoriah.Waterland@Sun.COM /* 15199781SMoriah.Waterland@Sun.COM * If this package owns this file, then store 15209781SMoriah.Waterland@Sun.COM * it in the database with the appropriate 15219781SMoriah.Waterland@Sun.COM * status. Need to check pinfo in case it 15229781SMoriah.Waterland@Sun.COM * points to NULL which could happen if 15239781SMoriah.Waterland@Sun.COM * pinfo->next = NULL above. 15249781SMoriah.Waterland@Sun.COM */ 15259781SMoriah.Waterland@Sun.COM if (pinfo) { 15269781SMoriah.Waterland@Sun.COM if (flag < 0 || is_served(ept->path, 15279781SMoriah.Waterland@Sun.COM &(extlist[idx]->fsys_value))) { 15289781SMoriah.Waterland@Sun.COM /* 15299781SMoriah.Waterland@Sun.COM * This is provided to 15309781SMoriah.Waterland@Sun.COM * clients by a server. 15319781SMoriah.Waterland@Sun.COM */ 15329781SMoriah.Waterland@Sun.COM pinfo->status = SERVED_FILE; 15339781SMoriah.Waterland@Sun.COM } else { 15349781SMoriah.Waterland@Sun.COM /* 15359781SMoriah.Waterland@Sun.COM * It's either there or it's 15369781SMoriah.Waterland@Sun.COM * not. 15379781SMoriah.Waterland@Sun.COM */ 15389781SMoriah.Waterland@Sun.COM pinfo->status = (flag ? 15399781SMoriah.Waterland@Sun.COM NOT_FND : ENTRY_OK); 15409781SMoriah.Waterland@Sun.COM } 15419781SMoriah.Waterland@Sun.COM } 15429781SMoriah.Waterland@Sun.COM } 15439781SMoriah.Waterland@Sun.COM } 15449781SMoriah.Waterland@Sun.COM 15459781SMoriah.Waterland@Sun.COM /* 15469781SMoriah.Waterland@Sun.COM * If not installing from a partially spooled package, the 15479781SMoriah.Waterland@Sun.COM * "save/pspool" area, and the file contents can be 15489781SMoriah.Waterland@Sun.COM * changed (type is 'e' or 'v'), and the class IS "none": 15499781SMoriah.Waterland@Sun.COM * copy the installed volatile file into the appropriate 15509781SMoriah.Waterland@Sun.COM * location in the packages destination "save/pspool" area. 15519781SMoriah.Waterland@Sun.COM */ 15529781SMoriah.Waterland@Sun.COM 15539781SMoriah.Waterland@Sun.COM if ((!is_partial_inst()) && 15549781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || (ept->ftype == 'v')) && 15559781SMoriah.Waterland@Sun.COM (strcmp(ept->pkg_class, "none") == 0)) { 15569781SMoriah.Waterland@Sun.COM 15579781SMoriah.Waterland@Sun.COM if (absolutepath(extlist[idx]->map_path) == B_TRUE && 15589781SMoriah.Waterland@Sun.COM parametricpath(extlist[idx]->cf_ent.ainfo.local, 15599781SMoriah.Waterland@Sun.COM &relocpath) == B_FALSE) { 15609781SMoriah.Waterland@Sun.COM pspool_loc = ROOT; 15619781SMoriah.Waterland@Sun.COM } else { 15629781SMoriah.Waterland@Sun.COM pspool_loc = RELOC; 15639781SMoriah.Waterland@Sun.COM } 15649781SMoriah.Waterland@Sun.COM 15659781SMoriah.Waterland@Sun.COM n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 15669781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, pspool_loc, 15679781SMoriah.Waterland@Sun.COM relocpath ? relocpath : extlist[idx]->map_path); 15689781SMoriah.Waterland@Sun.COM 15699781SMoriah.Waterland@Sun.COM if (n >= PATH_MAX) { 15709781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 15719781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 15729781SMoriah.Waterland@Sun.COM extlist[idx]->map_path); 15739781SMoriah.Waterland@Sun.COM quit(99); 15749781SMoriah.Waterland@Sun.COM } 15759781SMoriah.Waterland@Sun.COM 15769781SMoriah.Waterland@Sun.COM /* copy, preserve source file mode */ 15779781SMoriah.Waterland@Sun.COM 15789781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) { 15799781SMoriah.Waterland@Sun.COM warnflag++; 15809781SMoriah.Waterland@Sun.COM } 15819781SMoriah.Waterland@Sun.COM } 15829781SMoriah.Waterland@Sun.COM 15839781SMoriah.Waterland@Sun.COM /* 15849781SMoriah.Waterland@Sun.COM * Now insert this potentially changed package database 15859781SMoriah.Waterland@Sun.COM * entry. 15869781SMoriah.Waterland@Sun.COM */ 15879781SMoriah.Waterland@Sun.COM if (entry.cf_ent.npkgs) { 15889781SMoriah.Waterland@Sun.COM if (putcvfpfile(&(entry.cf_ent), *a_cfTmpVfp)) { 15899781SMoriah.Waterland@Sun.COM quit(99); 15909781SMoriah.Waterland@Sun.COM } 15919781SMoriah.Waterland@Sun.COM } 15929781SMoriah.Waterland@Sun.COM } 15939781SMoriah.Waterland@Sun.COM 1594*9869SCasper.Dik@Sun.COM n = swapcfile(pkgserver, a_cfTmpVfp, pkginst, dbchg); 15959781SMoriah.Waterland@Sun.COM if (n == RESULT_WRN) { 15969781SMoriah.Waterland@Sun.COM warnflag++; 15979781SMoriah.Waterland@Sun.COM } else if (n == RESULT_ERR) { 15989781SMoriah.Waterland@Sun.COM quit(99); 15999781SMoriah.Waterland@Sun.COM } 16009781SMoriah.Waterland@Sun.COM } 16019781SMoriah.Waterland@Sun.COM 16029781SMoriah.Waterland@Sun.COM /* 16039781SMoriah.Waterland@Sun.COM * This function goes through and fixes all the attributes. This is called 16049781SMoriah.Waterland@Sun.COM * out by using DST_QKVERIFY=this_class in the pkginfo file. The primary 16059781SMoriah.Waterland@Sun.COM * use for this is to fix up files installed by a class action script 16069781SMoriah.Waterland@Sun.COM * which is time-critical and reliable enough to assume likely success. 16079781SMoriah.Waterland@Sun.COM * The first such format was for WOS compressed-cpio'd file sets. 16089781SMoriah.Waterland@Sun.COM * The second format is the Class Archive Format. 16099781SMoriah.Waterland@Sun.COM */ 16109781SMoriah.Waterland@Sun.COM static int 16119781SMoriah.Waterland@Sun.COM fix_attributes(struct cfextra **extlist, int idx) 16129781SMoriah.Waterland@Sun.COM { 16139781SMoriah.Waterland@Sun.COM struct cfextra *ext; 16149781SMoriah.Waterland@Sun.COM int i, retval = 1; 16159781SMoriah.Waterland@Sun.COM int nc = cl_getn(); 16169781SMoriah.Waterland@Sun.COM int n; 16179781SMoriah.Waterland@Sun.COM struct cfent *ept; 16189781SMoriah.Waterland@Sun.COM struct mergstat *mstat; 16199781SMoriah.Waterland@Sun.COM char scrpt_dst[PATH_MAX]; 16209781SMoriah.Waterland@Sun.COM char *pspool_loc; 16219781SMoriah.Waterland@Sun.COM char *relocpath = (char *)NULL; 16229781SMoriah.Waterland@Sun.COM 16239781SMoriah.Waterland@Sun.COM for (i = 0; extlist[i]; i++) { 16249781SMoriah.Waterland@Sun.COM ext = extlist[i]; 16259781SMoriah.Waterland@Sun.COM ept = &(extlist[i]->cf_ent); 16269781SMoriah.Waterland@Sun.COM mstat = &(extlist[i]->mstat); 16279781SMoriah.Waterland@Sun.COM 16289781SMoriah.Waterland@Sun.COM /* 16299781SMoriah.Waterland@Sun.COM * We don't care about 'i'nfo files because, they 16309781SMoriah.Waterland@Sun.COM * aren't laid down, 'e'ditable files can change 16319781SMoriah.Waterland@Sun.COM * anyway, so who cares and 's'ymlinks were already 16329781SMoriah.Waterland@Sun.COM * fixed in domerg(); however, certain old WOS 16339781SMoriah.Waterland@Sun.COM * package symlinks depend on a bug in the old 16349781SMoriah.Waterland@Sun.COM * pkgadd which has recently been expunged. For 16359781SMoriah.Waterland@Sun.COM * those packages in 2.2, we repeat the verification 16369781SMoriah.Waterland@Sun.COM * of symlinks. 16379781SMoriah.Waterland@Sun.COM * 16389781SMoriah.Waterland@Sun.COM * By 2.6 or so, ftype == 's' should be added to this. 16399781SMoriah.Waterland@Sun.COM */ 16409781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i' || ept->ftype == 'e' || 16419781SMoriah.Waterland@Sun.COM (mstat->shared && nocnflct)) 16429781SMoriah.Waterland@Sun.COM continue; 16439781SMoriah.Waterland@Sun.COM 16449781SMoriah.Waterland@Sun.COM if (mstat->denied) { 16459781SMoriah.Waterland@Sun.COM progerr(ERR_COULD_NOT_INSTALL, ept->path); 16469781SMoriah.Waterland@Sun.COM warnflag++; 16479781SMoriah.Waterland@Sun.COM continue; 16489781SMoriah.Waterland@Sun.COM } 16499781SMoriah.Waterland@Sun.COM 16509781SMoriah.Waterland@Sun.COM if (ept->pkg_class_idx < 0 || ept->pkg_class_idx > nc) { 16519781SMoriah.Waterland@Sun.COM progerr(ERR_CLIDX, ept->pkg_class_idx, 16529781SMoriah.Waterland@Sun.COM (ept->path && *ept->path) ? ept->path : "unknown"); 16539781SMoriah.Waterland@Sun.COM continue; 16549781SMoriah.Waterland@Sun.COM } 16559781SMoriah.Waterland@Sun.COM 16569781SMoriah.Waterland@Sun.COM /* If this is the right class, do the fast verify. */ 16579781SMoriah.Waterland@Sun.COM if (ept->pkg_class_idx == idx) { 16589781SMoriah.Waterland@Sun.COM if (fverify(1, &ept->ftype, ept->path, 16599781SMoriah.Waterland@Sun.COM &ept->ainfo, &ept->cinfo) == 0) { 16609781SMoriah.Waterland@Sun.COM mstat->attrchg = 0; 16619781SMoriah.Waterland@Sun.COM mstat->contchg = 0; 16629781SMoriah.Waterland@Sun.COM } else /* We'll try full verify later */ 16639781SMoriah.Waterland@Sun.COM retval = 0; 16649781SMoriah.Waterland@Sun.COM } 16659781SMoriah.Waterland@Sun.COM /* 16669781SMoriah.Waterland@Sun.COM * Need to copy the installed volitale file back to the 16679781SMoriah.Waterland@Sun.COM * partial spooled area if we are installing to a local zone 16689781SMoriah.Waterland@Sun.COM * or similar installation method. 16699781SMoriah.Waterland@Sun.COM */ 16709781SMoriah.Waterland@Sun.COM 16719781SMoriah.Waterland@Sun.COM if ((!is_partial_inst()) && 16729781SMoriah.Waterland@Sun.COM ((ept->ftype == 'e') || (ept->ftype == 'v')) && 16739781SMoriah.Waterland@Sun.COM (strcmp(ept->pkg_class, "none") == 0)) { 16749781SMoriah.Waterland@Sun.COM 16759781SMoriah.Waterland@Sun.COM if (absolutepath(ext->map_path) == B_TRUE && 16769781SMoriah.Waterland@Sun.COM parametricpath(ext->cf_ent.ainfo.local, 16779781SMoriah.Waterland@Sun.COM &relocpath) == B_FALSE) { 16789781SMoriah.Waterland@Sun.COM pspool_loc = ROOT; 16799781SMoriah.Waterland@Sun.COM } else { 16809781SMoriah.Waterland@Sun.COM pspool_loc = RELOC; 16819781SMoriah.Waterland@Sun.COM } 16829781SMoriah.Waterland@Sun.COM 16839781SMoriah.Waterland@Sun.COM n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", 16849781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, pspool_loc, 16859781SMoriah.Waterland@Sun.COM relocpath ? relocpath : ext->map_path); 16869781SMoriah.Waterland@Sun.COM 16879781SMoriah.Waterland@Sun.COM if (n >= PATH_MAX) { 16889781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 16899781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 16909781SMoriah.Waterland@Sun.COM ext->map_path); 16919781SMoriah.Waterland@Sun.COM quit(99); 16929781SMoriah.Waterland@Sun.COM } 16939781SMoriah.Waterland@Sun.COM 16949781SMoriah.Waterland@Sun.COM /* copy, preserve source file mode */ 16959781SMoriah.Waterland@Sun.COM 16969781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) { 16979781SMoriah.Waterland@Sun.COM warnflag++; 16989781SMoriah.Waterland@Sun.COM } 16999781SMoriah.Waterland@Sun.COM } 17009781SMoriah.Waterland@Sun.COM } 17019781SMoriah.Waterland@Sun.COM 17029781SMoriah.Waterland@Sun.COM return (retval); 17039781SMoriah.Waterland@Sun.COM } 17049781SMoriah.Waterland@Sun.COM 17059781SMoriah.Waterland@Sun.COM /* 17069781SMoriah.Waterland@Sun.COM * Check to see if first charcter in path is a '/'. 17079781SMoriah.Waterland@Sun.COM * 17089781SMoriah.Waterland@Sun.COM * Return: 17099781SMoriah.Waterland@Sun.COM * B_TRUE - if path is prepended with '/' 17109781SMoriah.Waterland@Sun.COM * B_FALSE - if not 17119781SMoriah.Waterland@Sun.COM */ 17129781SMoriah.Waterland@Sun.COM static boolean_t 17139781SMoriah.Waterland@Sun.COM absolutepath(char *path) 17149781SMoriah.Waterland@Sun.COM { 17159781SMoriah.Waterland@Sun.COM assert(path != NULL); 17169781SMoriah.Waterland@Sun.COM assert(path[0] != '\0'); 17179781SMoriah.Waterland@Sun.COM 17189781SMoriah.Waterland@Sun.COM return (path[0] == '/' ? B_TRUE : B_FALSE); 17199781SMoriah.Waterland@Sun.COM } 17209781SMoriah.Waterland@Sun.COM 17219781SMoriah.Waterland@Sun.COM /* 17229781SMoriah.Waterland@Sun.COM * Check to see if path contains a '$' which makes it 17239781SMoriah.Waterland@Sun.COM * a parametric path and therefore relocatable. 17249781SMoriah.Waterland@Sun.COM * 17259781SMoriah.Waterland@Sun.COM * Parameters: 17269781SMoriah.Waterland@Sun.COM * path - The path to determine if it is absolute 17279781SMoriah.Waterland@Sun.COM * relocpath - The value of the unconditioned path 17289781SMoriah.Waterland@Sun.COM * i.e. $OPTDIR/usr/ls 17299781SMoriah.Waterland@Sun.COM * Return: 17309781SMoriah.Waterland@Sun.COM * B_TRUE - if path is a parametric path 17319781SMoriah.Waterland@Sun.COM * B_FALSE - if not 17329781SMoriah.Waterland@Sun.COM */ 17339781SMoriah.Waterland@Sun.COM static boolean_t 17349781SMoriah.Waterland@Sun.COM parametricpath(char *path, char **relocpath) 17359781SMoriah.Waterland@Sun.COM { 17369781SMoriah.Waterland@Sun.COM assert(path != NULL); 17379781SMoriah.Waterland@Sun.COM assert(path[0] != '\0'); 17389781SMoriah.Waterland@Sun.COM 17399781SMoriah.Waterland@Sun.COM /* 17409781SMoriah.Waterland@Sun.COM * If this is a valid parametric path then a '$' MUST occur at the 17419781SMoriah.Waterland@Sun.COM * first or second character. 17429781SMoriah.Waterland@Sun.COM */ 17439781SMoriah.Waterland@Sun.COM 17449781SMoriah.Waterland@Sun.COM if (path[0] == '$' || path[1] == '$') { 17459781SMoriah.Waterland@Sun.COM /* 17469781SMoriah.Waterland@Sun.COM * If a parametric path exists then when copying the 17479781SMoriah.Waterland@Sun.COM * path to the pspool directoy from the installing 17489781SMoriah.Waterland@Sun.COM * pkgs reloc directory we want to use the uncononditional 17499781SMoriah.Waterland@Sun.COM * varaiable path. 17509781SMoriah.Waterland@Sun.COM */ 17519781SMoriah.Waterland@Sun.COM *relocpath = (path + 1); 17529781SMoriah.Waterland@Sun.COM return (B_TRUE); 17539781SMoriah.Waterland@Sun.COM } 17549781SMoriah.Waterland@Sun.COM return (B_FALSE); 17559781SMoriah.Waterland@Sun.COM } 17569781SMoriah.Waterland@Sun.COM 17579781SMoriah.Waterland@Sun.COM void 17589781SMoriah.Waterland@Sun.COM regfiles_free() 17599781SMoriah.Waterland@Sun.COM { 17609781SMoriah.Waterland@Sun.COM if (regfiles_head != NULL) { 17619781SMoriah.Waterland@Sun.COM struct reg_files *rfp = regfiles_head->next; 17629781SMoriah.Waterland@Sun.COM 17639781SMoriah.Waterland@Sun.COM while (rfp != NULL) { 17649781SMoriah.Waterland@Sun.COM free(regfiles_head); 17659781SMoriah.Waterland@Sun.COM regfiles_head = rfp; 17669781SMoriah.Waterland@Sun.COM rfp = regfiles_head->next; 17679781SMoriah.Waterland@Sun.COM } 17689781SMoriah.Waterland@Sun.COM free(regfiles_head); 17699781SMoriah.Waterland@Sun.COM regfiles_head = NULL; 17709781SMoriah.Waterland@Sun.COM } 17719781SMoriah.Waterland@Sun.COM } 1772