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