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
instvol(struct cfextra ** extlist,char * srcinst,int part,int nparts,PKGserver pkgserver,VFP_T ** a_cfTmpVfp,char ** r_updated,char * a_zoneName)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
domerg(struct cfextra ** extlist,int part,int nparts,int myclass,char ** srcp,char ** dstp,char ** r_updated)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
dir_is_populated(char * dirpath)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
endofclass(struct cfextra ** extlist,int myclass,int ckflag,PKGserver pkgserver,VFP_T ** a_cfTmpVfp)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
fix_attributes(struct cfextra ** extlist,int idx)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
absolutepath(char * path)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
parametricpath(char * path,char ** relocpath)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
regfiles_free()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