xref: /titanic_50/usr/src/cmd/svr4pkg/pkginstall/instvol.c (revision 62224350e5355e6834f7deb9d8a7d062a50cb7c2)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
225c51f124SMoriah Waterland /*
235c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245c51f124SMoriah Waterland  * Use is subject to license terms.
255c51f124SMoriah Waterland  */
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland 
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland #include <stdio.h>
325c51f124SMoriah Waterland #include <string.h>
335c51f124SMoriah Waterland #include <locale.h>
345c51f124SMoriah Waterland #include <libintl.h>
355c51f124SMoriah Waterland #include <dirent.h>
365c51f124SMoriah Waterland #include <pkgstrct.h>
375c51f124SMoriah Waterland #include <pkgdev.h>
385c51f124SMoriah Waterland #include <pkglocs.h>
395c51f124SMoriah Waterland #include <archives.h>
405c51f124SMoriah Waterland #include <errno.h>
415c51f124SMoriah Waterland #include <fcntl.h>
425c51f124SMoriah Waterland #include <sys/stat.h>
435c51f124SMoriah Waterland #include <sys/param.h>
445c51f124SMoriah Waterland #include <stdlib.h>
455c51f124SMoriah Waterland #include <unistd.h>
465c51f124SMoriah Waterland #include <assert.h>
475c51f124SMoriah Waterland #include <wait.h>
485c51f124SMoriah Waterland 
495c51f124SMoriah Waterland /*
505c51f124SMoriah Waterland  * libinstzones includes
515c51f124SMoriah Waterland  */
525c51f124SMoriah Waterland 
535c51f124SMoriah Waterland #include <instzones_api.h>
545c51f124SMoriah Waterland 
555c51f124SMoriah Waterland /*
565c51f124SMoriah Waterland  * consolidation pkg command library includes
575c51f124SMoriah Waterland  */
585c51f124SMoriah Waterland 
595c51f124SMoriah Waterland #include <pkglib.h>
605c51f124SMoriah Waterland #include <pkgweb.h>
615c51f124SMoriah Waterland 
625c51f124SMoriah Waterland /*
635c51f124SMoriah Waterland  * local pkg command library includes
645c51f124SMoriah Waterland  */
655c51f124SMoriah Waterland 
665c51f124SMoriah Waterland #include <install.h>
675c51f124SMoriah Waterland #include <libinst.h>
685c51f124SMoriah Waterland #include <libadm.h>
695c51f124SMoriah Waterland #include <dryrun.h>
705c51f124SMoriah Waterland #include <messages.h>
715c51f124SMoriah Waterland 
725c51f124SMoriah Waterland /*
735c51f124SMoriah Waterland  * pkginstall local includes
745c51f124SMoriah Waterland  */
755c51f124SMoriah Waterland 
765c51f124SMoriah Waterland #include "pkginstall.h"
775c51f124SMoriah Waterland 
785c51f124SMoriah Waterland extern int		pkgverbose;
795c51f124SMoriah Waterland extern fsblkcnt_t	pkgmap_blks; 		/* main.c */
805c51f124SMoriah Waterland 
815c51f124SMoriah Waterland extern struct pkgdev pkgdev;
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland extern char	tmpdir[];
845c51f124SMoriah Waterland extern char	pkgbin[];
855c51f124SMoriah Waterland extern char	instdir[];
865c51f124SMoriah Waterland extern char	saveSpoolInstallDir[];
875c51f124SMoriah Waterland extern char	*pkginst;
885c51f124SMoriah Waterland 
895c51f124SMoriah Waterland extern int	dbchg;
905c51f124SMoriah Waterland extern int	nosetuid;
915c51f124SMoriah Waterland extern int	nocnflct;
925c51f124SMoriah Waterland extern int	warnflag;
935c51f124SMoriah Waterland 
945c51f124SMoriah Waterland #define	DMRG_DONE	-1
955c51f124SMoriah Waterland 
965c51f124SMoriah Waterland #define	ck_efile(s, p)	\
975c51f124SMoriah Waterland 		((p->cinfo.modtime >= 0) && \
985c51f124SMoriah Waterland 		p->ainfo.local && \
995c51f124SMoriah Waterland 		cverify(0, &p->ftype, s, &p->cinfo, 1))
1005c51f124SMoriah Waterland 
1015c51f124SMoriah Waterland static int	eocflag;
1025c51f124SMoriah Waterland 
1035c51f124SMoriah Waterland /*
1045c51f124SMoriah Waterland  * The variable below indicates that fix_attributes() will be inadequate
1055c51f124SMoriah Waterland  * because a replacement was permitted.
1065c51f124SMoriah Waterland  */
1075c51f124SMoriah Waterland static int	repl_permitted = 0;
1085c51f124SMoriah Waterland 
1095c51f124SMoriah Waterland static int	domerg(struct cfextra **extlist, int part, int nparts,
1105c51f124SMoriah Waterland 			int myclass, char **srcp, char **dstp,
1115c51f124SMoriah Waterland 			char **r_updated, char **r_skipped,
1125c51f124SMoriah Waterland 			char **r_anyPathLocal);
1135c51f124SMoriah Waterland static void	endofclass(struct cfextra **extlist, int myclass,
114*62224350SCasper H.S. Dik 			int ckflag, PKGserver server, VFP_T **a_cfTmpVfp);
1155c51f124SMoriah Waterland static int	fix_attributes(struct cfextra **, int);
1165c51f124SMoriah Waterland static int	dir_is_populated(char *dirpath);
1175c51f124SMoriah Waterland static boolean_t absolutepath(char *path);
1185c51f124SMoriah Waterland static boolean_t parametricpath(char *path, char **relocpath);
1195c51f124SMoriah Waterland 
1205c51f124SMoriah Waterland /* Used to keep track of the entries in extlist that are regular files. */
1215c51f124SMoriah Waterland struct reg_files {
1225c51f124SMoriah Waterland 	struct reg_files *next;
1235c51f124SMoriah Waterland 	int val;
1245c51f124SMoriah Waterland };
1255c51f124SMoriah Waterland static struct reg_files *regfiles_head = NULL;
1265c51f124SMoriah Waterland 
1275c51f124SMoriah Waterland /*
1285c51f124SMoriah Waterland  * This is the function that actually installs one volume (usually that's
1295c51f124SMoriah Waterland  * all there is). Upon entry, the extlist is entirely correct:
1305c51f124SMoriah Waterland  *
1315c51f124SMoriah Waterland  *	1. It contains only those files which are to be installed
1325c51f124SMoriah Waterland  *	   from all volumes.
1335c51f124SMoriah Waterland  *	2. The mode bits in the ainfo structure for each file are set
1345c51f124SMoriah Waterland  *	   correctly in accordance with administrative defaults.
1355c51f124SMoriah Waterland  *	3. mstat.setuid/setgid reflect what the status *was* before
1365c51f124SMoriah Waterland  *	   pkgdbmerg() processed compliance.
1375c51f124SMoriah Waterland  */
1385c51f124SMoriah Waterland void
1395c51f124SMoriah Waterland instvol(struct cfextra **extlist, char *srcinst, int part,
140*62224350SCasper H.S. Dik 	int nparts, PKGserver pkgserver, VFP_T **a_cfTmpVfp,
1415c51f124SMoriah Waterland 	char **r_updated, char **r_skipped,
1425c51f124SMoriah Waterland 	char *a_zoneName)
1435c51f124SMoriah Waterland {
1445c51f124SMoriah Waterland 	FILE		*listfp;
1455c51f124SMoriah Waterland 	char		*updated = (char *)NULL;
1465c51f124SMoriah Waterland 	char		*skipped = (char *)NULL;
1475c51f124SMoriah Waterland 	char		*anyPathLocal = (char *)NULL;
1485c51f124SMoriah Waterland 	char		*relocpath = (char *)NULL;
1495c51f124SMoriah Waterland 	char		*dstp;
1505c51f124SMoriah Waterland 	char		*listfile;
1515c51f124SMoriah Waterland 	char		*srcp;
1525c51f124SMoriah Waterland 	char		*pspool_loc;
1535c51f124SMoriah Waterland 	char		scrpt_dst[PATH_MAX];
1545c51f124SMoriah Waterland 	int		count;
1555c51f124SMoriah Waterland 	int		entryidx;	/* array of current package objects */
1565c51f124SMoriah Waterland 	int		n;
1575c51f124SMoriah Waterland 	int		nc = 0;
1585c51f124SMoriah Waterland 	int		pass;		/* pass count through the for loop. */
1595c51f124SMoriah Waterland 	int		tcount;
1605c51f124SMoriah Waterland 	struct cfent	*ept;
1615c51f124SMoriah Waterland 	struct cfextra	*ext;
1625c51f124SMoriah Waterland 	struct mergstat	*mstat;
1635c51f124SMoriah Waterland 	struct reg_files *rfp = NULL;
1645c51f124SMoriah Waterland 
1655c51f124SMoriah Waterland 	/*
1665c51f124SMoriah Waterland 	 * r_updated and r_skipped are optional parameters that can be passed in
1675c51f124SMoriah Waterland 	 * by the caller if the caller wants to know if any objects are either
1685c51f124SMoriah Waterland 	 * updated or skipped. Do not initialize either r_updated or r_skipped;
1695c51f124SMoriah Waterland 	 * the call to instvol could be cumulative and any previous update or
1705c51f124SMoriah Waterland 	 * skipped indication must not be disturbed - these flags are only set,
1715c51f124SMoriah Waterland 	 * they must never be reset. These flags are "char *" pointers so that
1725c51f124SMoriah Waterland 	 * the object that was skipped or updated can be displayed in debugging
1735c51f124SMoriah Waterland 	 * output.
1745c51f124SMoriah Waterland 	 */
1755c51f124SMoriah Waterland 
1765c51f124SMoriah Waterland 	if (part == 1) {
1775c51f124SMoriah Waterland 		pkgvolume(&pkgdev, srcinst, part, nparts);
1785c51f124SMoriah Waterland 	}
1795c51f124SMoriah Waterland 
1805c51f124SMoriah Waterland 	tcount = 0;
1815c51f124SMoriah Waterland 	nc = cl_getn();
1825c51f124SMoriah Waterland 
1835c51f124SMoriah Waterland 	/*
1845c51f124SMoriah Waterland 	 * For each class in this volume, install those files.
1855c51f124SMoriah Waterland 	 *
1865c51f124SMoriah Waterland 	 * NOTE : This loop index may be decremented by code below forcing a
1875c51f124SMoriah Waterland 	 * second trip through for the same class. This happens only when a
1885c51f124SMoriah Waterland 	 * class is split between an archive and the tree. Examples would be
1895c51f124SMoriah Waterland 	 * old WOS packages and the occasional class containing dynamic
1905c51f124SMoriah Waterland 	 * libraries which require special treatment.
1915c51f124SMoriah Waterland 	 */
1925c51f124SMoriah Waterland 
1935c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB() == B_FALSE) {
1945c51f124SMoriah Waterland 	    int		classidx;	/* the current class */
1955c51f124SMoriah Waterland 
1965c51f124SMoriah Waterland 	    for (classidx = 0; classidx < nc; classidx++) {
1975c51f124SMoriah Waterland 		int pass_relative = 0;
1985c51f124SMoriah Waterland 		int rel_init = 0;
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland 		eocflag = count = pass = 0;
2015c51f124SMoriah Waterland 		listfp = (FILE *)0;
2025c51f124SMoriah Waterland 		listfile = NULL;
2035c51f124SMoriah Waterland 
2045c51f124SMoriah Waterland 		/* Now what do we pass to the class action script */
2055c51f124SMoriah Waterland 
2065c51f124SMoriah Waterland 		if (cl_pthrel(classidx) == REL_2_CAS) {
2075c51f124SMoriah Waterland 			pass_relative = 1;
2085c51f124SMoriah Waterland 		}
2095c51f124SMoriah Waterland 
2105c51f124SMoriah Waterland 		for (;;) {
2115c51f124SMoriah Waterland 			if (!tcount++) {
2125c51f124SMoriah Waterland 				/* first file to install */
2135c51f124SMoriah Waterland 				if (a_zoneName == (char *)NULL) {
2145c51f124SMoriah Waterland 					echo(MSG_INS_N_N, part, nparts);
2155c51f124SMoriah Waterland 				} else {
2165c51f124SMoriah Waterland 					echo(MSG_INS_N_N_LZ, part, nparts,
2175c51f124SMoriah Waterland 						a_zoneName);
2185c51f124SMoriah Waterland 				}
2195c51f124SMoriah Waterland 			}
2205c51f124SMoriah Waterland 
2215c51f124SMoriah Waterland 			/*
2225c51f124SMoriah Waterland 			 * If there's an install class action script and no
2235c51f124SMoriah Waterland 			 * list file has been created yet, create that file
2245c51f124SMoriah Waterland 			 * and provide the pointer in listfp.
2255c51f124SMoriah Waterland 			 */
2265c51f124SMoriah Waterland 			if (cl_iscript(classidx) && !listfp) {
2275c51f124SMoriah Waterland 				/* create list file */
2285c51f124SMoriah Waterland 				putparam("TMPDIR", tmpdir);
2295c51f124SMoriah Waterland 				listfile = tempnam(tmpdir, "list");
2305c51f124SMoriah Waterland 				if ((listfp = fopen(listfile, "w")) == NULL) {
2315c51f124SMoriah Waterland 					progerr(ERR_WTMPFILE, listfile);
2325c51f124SMoriah Waterland 					quit(99);
2335c51f124SMoriah Waterland 				}
2345c51f124SMoriah Waterland 			}
2355c51f124SMoriah Waterland 
2365c51f124SMoriah Waterland 			/*
2375c51f124SMoriah Waterland 			 * The following function goes through the package
2385c51f124SMoriah Waterland 			 * object list returning the array index of the next
2395c51f124SMoriah Waterland 			 * regular file. If it encounters a directory,
2405c51f124SMoriah Waterland 			 * symlink, named pipe or device, it just creates it.
2415c51f124SMoriah Waterland 			 */
2425c51f124SMoriah Waterland 
2435c51f124SMoriah Waterland 			entryidx = domerg(extlist, (pass++ ? 0 : part), nparts,
2445c51f124SMoriah Waterland 				classidx, &srcp, &dstp, &updated, &skipped,
2455c51f124SMoriah Waterland 				&anyPathLocal);
2465c51f124SMoriah Waterland 
2475c51f124SMoriah Waterland 			/* Evaluate the return code */
2485c51f124SMoriah Waterland 			if (entryidx == DMRG_DONE) {
2495c51f124SMoriah Waterland 				/*
2505c51f124SMoriah Waterland 				 * Set ept to the first entry in extlist
2515c51f124SMoriah Waterland 				 * which is guaranteed to exist so
2525c51f124SMoriah Waterland 				 * later checks against ept->ftype are
2535c51f124SMoriah Waterland 				 * not compared to NULL.
2545c51f124SMoriah Waterland 				 */
2555c51f124SMoriah Waterland 				ext = extlist[0];
2565c51f124SMoriah Waterland 				ept = &(ext->cf_ent);
2575c51f124SMoriah Waterland 				break; /* no more entries to process */
2585c51f124SMoriah Waterland 			}
2595c51f124SMoriah Waterland 
2605c51f124SMoriah Waterland 			ext = extlist[entryidx];
2615c51f124SMoriah Waterland 			ept = &(ext->cf_ent);
2625c51f124SMoriah Waterland 			mstat = &(ext->mstat);
2635c51f124SMoriah Waterland 
2645c51f124SMoriah Waterland 			/*
2655c51f124SMoriah Waterland 			 * If not installing from a partially spooled package
2665c51f124SMoriah Waterland 			 * (the "save/pspool" area), and the file contents can
2675c51f124SMoriah Waterland 			 * be changed (type is 'e' or 'v'), and the class is not
2685c51f124SMoriah Waterland 			 * "none": copy the file from the package (in pristine
2695c51f124SMoriah Waterland 			 * state with no actions performed) into the appropriate
2705c51f124SMoriah Waterland 			 * location in the packages destination "save/pspool"
2715c51f124SMoriah Waterland 			 * area.
2725c51f124SMoriah Waterland 			 */
2735c51f124SMoriah Waterland 
2745c51f124SMoriah Waterland 			if ((!is_partial_inst()) &&
2755c51f124SMoriah Waterland 				((ept->ftype == 'e') || (ept->ftype == 'v')) &&
2765c51f124SMoriah Waterland 				(strcmp(ept->pkg_class, "none") != 0)) {
2775c51f124SMoriah Waterland 
2785c51f124SMoriah Waterland 				if (absolutepath(ext->map_path) == B_TRUE &&
2795c51f124SMoriah Waterland 					parametricpath(ext->cf_ent.ainfo.local,
2805c51f124SMoriah Waterland 						&relocpath) == B_FALSE) {
2815c51f124SMoriah Waterland 					pspool_loc = ROOT;
2825c51f124SMoriah Waterland 				} else {
2835c51f124SMoriah Waterland 					pspool_loc = RELOC;
2845c51f124SMoriah Waterland 				}
2855c51f124SMoriah Waterland 
2865c51f124SMoriah Waterland 				n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s",
2875c51f124SMoriah Waterland 					saveSpoolInstallDir, pspool_loc,
2885c51f124SMoriah Waterland 					relocpath ? relocpath : ext->map_path);
2895c51f124SMoriah Waterland 
2905c51f124SMoriah Waterland 				if (n >= PATH_MAX) {
2915c51f124SMoriah Waterland 					progerr(ERR_CREATE_PATH_2,
2925c51f124SMoriah Waterland 						saveSpoolInstallDir,
2935c51f124SMoriah Waterland 						ext->map_path);
2945c51f124SMoriah Waterland 					quit(99);
2955c51f124SMoriah Waterland 				}
2965c51f124SMoriah Waterland 
2975c51f124SMoriah Waterland 				/* copy, preserve source file mode */
2985c51f124SMoriah Waterland 
2995c51f124SMoriah Waterland 				if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) {
3005c51f124SMoriah Waterland 					warnflag++;
3015c51f124SMoriah Waterland 				}
3025c51f124SMoriah Waterland 			}
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland 			/*
3055c51f124SMoriah Waterland 			 * If this isn't writeable anyway, it's not going
3065c51f124SMoriah Waterland 			 * into the list file. Only count it if it's going
3075c51f124SMoriah Waterland 			 * into the list file.
3085c51f124SMoriah Waterland 			 */
3095c51f124SMoriah Waterland 			if (is_fs_writeable(ext->cf_ent.path,
3105c51f124SMoriah Waterland 				&(ext->fsys_value)))
3115c51f124SMoriah Waterland 				count++;
3125c51f124SMoriah Waterland 
3135c51f124SMoriah Waterland 			pkgvolume(&pkgdev, srcinst, part, nparts);
3145c51f124SMoriah Waterland 
3155c51f124SMoriah Waterland 			/*
3165c51f124SMoriah Waterland 			 * If source verification is OK for this class, make
3175c51f124SMoriah Waterland 			 * sure the source we're passing to the class action
3185c51f124SMoriah Waterland 			 * script is useable.
3195c51f124SMoriah Waterland 			 */
3205c51f124SMoriah Waterland 			if (cl_svfy(classidx) != NOVERIFY) {
3215c51f124SMoriah Waterland 				if (cl_iscript(classidx) ||
3225c51f124SMoriah Waterland 					((ept->ftype == 'e') ||
3235c51f124SMoriah Waterland 					(ept->ftype == 'n'))) {
3245c51f124SMoriah Waterland 					if (ck_efile(srcp, ept)) {
3255c51f124SMoriah Waterland 						progerr(ERR_CORRUPT,
3265c51f124SMoriah Waterland 							srcp);
3275c51f124SMoriah Waterland 						logerr(getErrbufAddr());
3285c51f124SMoriah Waterland 						warnflag++;
3295c51f124SMoriah Waterland 						continue;
3305c51f124SMoriah Waterland 					}
3315c51f124SMoriah Waterland 				}
3325c51f124SMoriah Waterland 			}
3335c51f124SMoriah Waterland 
3345c51f124SMoriah Waterland 			/*
3355c51f124SMoriah Waterland 			 * If there's a class action script for this class,
3365c51f124SMoriah Waterland 			 * just collect names in a temporary file
3375c51f124SMoriah Waterland 			 * that will be used as the stdin when the
3385c51f124SMoriah Waterland 			 * class action script is invoked.
3395c51f124SMoriah Waterland 			 */
3405c51f124SMoriah Waterland 
3415c51f124SMoriah Waterland 			if ((cl_iscript(classidx)) &&
3425c51f124SMoriah Waterland 					((is_fs_writeable(ept->path,
3435c51f124SMoriah Waterland 						&(ext->fsys_value))))) {
3445c51f124SMoriah Waterland 				if (pass_relative) {
3455c51f124SMoriah Waterland 					if (!rel_init) {
3465c51f124SMoriah Waterland 						(void) fputs(instdir, listfp);
3475c51f124SMoriah Waterland 						(void) putc('\n', listfp);
3485c51f124SMoriah Waterland 						rel_init++;
3495c51f124SMoriah Waterland 					}
3505c51f124SMoriah Waterland 					(void) fputs(ext->map_path, listfp);
3515c51f124SMoriah Waterland 					(void) putc('\n', listfp);
3525c51f124SMoriah Waterland 				} else {
3535c51f124SMoriah Waterland 					(void) fputs(srcp ?
3545c51f124SMoriah Waterland 						srcp : "/dev/null", listfp);
3555c51f124SMoriah Waterland 					(void) putc(' ', listfp);
3565c51f124SMoriah Waterland 					(void) fputs(dstp, listfp);
3575c51f124SMoriah Waterland 					(void) putc('\n', listfp);
3585c51f124SMoriah Waterland 				}
3595c51f124SMoriah Waterland 				/*
3605c51f124SMoriah Waterland 				 * Note which entries in extlist are regular
3615c51f124SMoriah Waterland 				 * files to be installed via the class action
3625c51f124SMoriah Waterland 				 * script.
3635c51f124SMoriah Waterland 				 */
3645c51f124SMoriah Waterland 				if (regfiles_head == NULL) {
3655c51f124SMoriah Waterland 					assert(rfp == NULL);
3665c51f124SMoriah Waterland 					regfiles_head =
3675c51f124SMoriah Waterland 					    malloc(sizeof (struct reg_files));
3685c51f124SMoriah Waterland 					if (regfiles_head == NULL) {
3695c51f124SMoriah Waterland 						progerr(ERR_MEMORY, errno);
3705c51f124SMoriah Waterland 						quit(99);
3715c51f124SMoriah Waterland 					}
3725c51f124SMoriah Waterland 					regfiles_head->next = NULL;
3735c51f124SMoriah Waterland 					regfiles_head->val = entryidx;
3745c51f124SMoriah Waterland 					rfp = regfiles_head;
3755c51f124SMoriah Waterland 				} else {
3765c51f124SMoriah Waterland 					assert(rfp != NULL);
3775c51f124SMoriah Waterland 					rfp->next =
3785c51f124SMoriah Waterland 					    malloc(sizeof (struct reg_files));
3795c51f124SMoriah Waterland 					if (rfp->next == NULL) {
3805c51f124SMoriah Waterland 						progerr(ERR_MEMORY, errno);
3815c51f124SMoriah Waterland 						quit(99);
3825c51f124SMoriah Waterland 					}
3835c51f124SMoriah Waterland 					rfp = rfp->next;
3845c51f124SMoriah Waterland 					rfp->next = NULL;
3855c51f124SMoriah Waterland 					rfp->val = entryidx;
3865c51f124SMoriah Waterland 				}
3875c51f124SMoriah Waterland 
3885c51f124SMoriah Waterland 				/*
3895c51f124SMoriah Waterland 				 * A warning message about unwritable targets
3905c51f124SMoriah Waterland 				 * in a class may be appropriate here.
3915c51f124SMoriah Waterland 				 */
3925c51f124SMoriah Waterland 				continue;
3935c51f124SMoriah Waterland 			}
3945c51f124SMoriah Waterland 
3955c51f124SMoriah Waterland 			/*
3965c51f124SMoriah Waterland 			 * If not installing from a partially spooled package
3975c51f124SMoriah Waterland 			 * (the "save/pspool" area), and the file contents can
3985c51f124SMoriah Waterland 			 * be changed (type is 'e' or 'v') and the class
3995c51f124SMoriah Waterland 			 * identifier is not "none": copy the file from the
4005c51f124SMoriah Waterland 			 * package (in pristine state with no actions performed)
4015c51f124SMoriah Waterland 			 * into the appropriate location in the packages
4025c51f124SMoriah Waterland 			 * destination "save/pspool" area.
4035c51f124SMoriah Waterland 			 */
4045c51f124SMoriah Waterland 
4055c51f124SMoriah Waterland 			if ((!is_partial_inst()) &&
4065c51f124SMoriah Waterland 			    ((ept->ftype == 'e') || (ept->ftype == 'v') &&
4075c51f124SMoriah Waterland 			    (strcmp(ept->pkg_class, "none") != 0))) {
4085c51f124SMoriah Waterland 
4095c51f124SMoriah Waterland 				if (absolutepath(ext->map_path) == B_TRUE &&
4105c51f124SMoriah Waterland 					parametricpath(ext->cf_ent.ainfo.local,
4115c51f124SMoriah Waterland 						&relocpath) == B_FALSE) {
4125c51f124SMoriah Waterland 					pspool_loc = ROOT;
4135c51f124SMoriah Waterland 				} else {
4145c51f124SMoriah Waterland 					pspool_loc = RELOC;
4155c51f124SMoriah Waterland 				}
4165c51f124SMoriah Waterland 
4175c51f124SMoriah Waterland 				n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s",
4185c51f124SMoriah Waterland 					saveSpoolInstallDir, pspool_loc,
4195c51f124SMoriah Waterland 					relocpath ? relocpath : ext->map_path);
4205c51f124SMoriah Waterland 
4215c51f124SMoriah Waterland 				if (n >= PATH_MAX) {
4225c51f124SMoriah Waterland 					progerr(ERR_CREATE_PATH_2,
4235c51f124SMoriah Waterland 						saveSpoolInstallDir,
4245c51f124SMoriah Waterland 						ext->map_path);
4255c51f124SMoriah Waterland 					quit(99);
4265c51f124SMoriah Waterland 				}
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 				/* copy, preserve source file mode */
4295c51f124SMoriah Waterland 
4305c51f124SMoriah Waterland 				if (cppath(MODE_SRC, srcp, scrpt_dst, 0644)) {
4315c51f124SMoriah Waterland 					warnflag++;
4325c51f124SMoriah Waterland 				}
4335c51f124SMoriah Waterland 			}
4345c51f124SMoriah Waterland 
4355c51f124SMoriah Waterland 			/*
4365c51f124SMoriah Waterland 			 * There are several tests here to determine
4375c51f124SMoriah Waterland 			 * how we're going to deal with objects
4385c51f124SMoriah Waterland 			 * intended for remote read-only filesystems.
4395c51f124SMoriah Waterland 			 * We don't use is_served() because this may be
4405c51f124SMoriah Waterland 			 * a server. We're actually interested in if
4415c51f124SMoriah Waterland 			 * it's *really* remote and *really* not
4425c51f124SMoriah Waterland 			 * writeable.
4435c51f124SMoriah Waterland 			 */
4445c51f124SMoriah Waterland 
4455c51f124SMoriah Waterland 			n = is_remote_fs(ept->path, &(ext->fsys_value));
4465c51f124SMoriah Waterland 			if ((n != 0) &&
4475c51f124SMoriah Waterland 				!is_fs_writeable(ept->path,
4485c51f124SMoriah Waterland 				&(ext->fsys_value))) {
4495c51f124SMoriah Waterland 
4505c51f124SMoriah Waterland 				/*
4515c51f124SMoriah Waterland 				 * Don't change the file, we can't write
4525c51f124SMoriah Waterland 				 * to it anyway.
4535c51f124SMoriah Waterland 				 */
4545c51f124SMoriah Waterland 
4555c51f124SMoriah Waterland 				mstat->attrchg = 0;
4565c51f124SMoriah Waterland 				mstat->contchg = 0;
4575c51f124SMoriah Waterland 
4585c51f124SMoriah Waterland 				/*
4595c51f124SMoriah Waterland 				 * If it's currently mounted, we can
4605c51f124SMoriah Waterland 				 * at least test it for existence.
4615c51f124SMoriah Waterland 				 */
4625c51f124SMoriah Waterland 
4635c51f124SMoriah Waterland 				if (is_mounted(ept->path, &(ext->fsys_value))) {
4645c51f124SMoriah Waterland 					if (!isfile(NULL, dstp)) {
4655c51f124SMoriah Waterland 						echo(MSG_IS_PRESENT, dstp);
4665c51f124SMoriah Waterland 					} else {
4675c51f124SMoriah Waterland 						echo(WRN_INSTVOL_NONE, dstp);
4685c51f124SMoriah Waterland 					}
4695c51f124SMoriah Waterland 				} else {
4705c51f124SMoriah Waterland 					char *server_host;
4715c51f124SMoriah Waterland 
4725c51f124SMoriah Waterland 					server_host = get_server_host(
4735c51f124SMoriah Waterland 						ext->fsys_value);
4745c51f124SMoriah Waterland 
4755c51f124SMoriah Waterland 					/* If not, we're just stuck. */
4765c51f124SMoriah Waterland 					echo(WRN_INSTVOL_NOVERIFY,
4775c51f124SMoriah Waterland 						dstp, server_host);
4785c51f124SMoriah Waterland 				}
4795c51f124SMoriah Waterland 
4805c51f124SMoriah Waterland 				continue;
4815c51f124SMoriah Waterland 			}
4825c51f124SMoriah Waterland 
4835c51f124SMoriah Waterland 			/* echo output destination name */
4845c51f124SMoriah Waterland 
4855c51f124SMoriah Waterland 			echo("%s", dstp);
4865c51f124SMoriah Waterland 
4875c51f124SMoriah Waterland 			/*
4885c51f124SMoriah Waterland 			 * if no source then no need to copy/verify
4895c51f124SMoriah Waterland 			 */
4905c51f124SMoriah Waterland 
4915c51f124SMoriah Waterland 			if (srcp == (char *)NULL) {
4925c51f124SMoriah Waterland 				continue;
4935c51f124SMoriah Waterland 			}
4945c51f124SMoriah Waterland 
4955c51f124SMoriah Waterland 			/*
4965c51f124SMoriah Waterland 			 * If doing a partial installation (creating a
4975c51f124SMoriah Waterland 			 * non-global zone), extra steps need to be taken:
4985c51f124SMoriah Waterland 			 *
4995c51f124SMoriah Waterland 			 * 1) if the file is not type 'e' and not type 'v' and
5005c51f124SMoriah Waterland 			 * the class is "none": then the file must already
5015c51f124SMoriah Waterland 			 * exist (as a result of the initial non-global zone
5025c51f124SMoriah Waterland 			 * installation which caused all non-e/v files to be
5035c51f124SMoriah Waterland 			 * copied from the global zone to the non-global
5045c51f124SMoriah Waterland 			 * zone). If this is the case, verify that the file
5055c51f124SMoriah Waterland 			 * exists and has the correct attributes.
5065c51f124SMoriah Waterland 			 *
5075c51f124SMoriah Waterland 			 * 2) if the file is not type 'e' and not type 'v'
5085c51f124SMoriah Waterland 			 * and the class is NOT "none", *OR* if the file is
5095c51f124SMoriah Waterland 			 * type 'e' or type 'v': then check to see if the
5105c51f124SMoriah Waterland 			 * file is located in an area inherited from the
5115c51f124SMoriah Waterland 			 * global zone. If so, then there is no ability to
5125c51f124SMoriah Waterland 			 * change the file since inherited file systems are
5135c51f124SMoriah Waterland 			 * "read only" - just verify that the file exists and
5145c51f124SMoriah Waterland 			 * verify attributes only if not 'e' or 'v'.
5155c51f124SMoriah Waterland 			 */
5165c51f124SMoriah Waterland 
5175c51f124SMoriah Waterland 			if (is_partial_inst() != 0) {
5185c51f124SMoriah Waterland 
5195c51f124SMoriah Waterland 				/*
5205c51f124SMoriah Waterland 				 * determine if the destination package is in an
5215c51f124SMoriah Waterland 				 * area inherited from the global zone
5225c51f124SMoriah Waterland 				 */
5235c51f124SMoriah Waterland 
5245c51f124SMoriah Waterland 				n = pkgMatchInherited(srcp, dstp,
5255c51f124SMoriah Waterland 					get_inst_root(), ept->ainfo.mode,
5265c51f124SMoriah Waterland 					ept->cinfo.modtime, ept->ftype,
5275c51f124SMoriah Waterland 					ept->cinfo.cksum);
5285c51f124SMoriah Waterland 
5295c51f124SMoriah Waterland 				echoDebug(DBG_INSTVOL_PARTIAL_INST,
5305c51f124SMoriah Waterland 					srcp ? srcp : "", dstp ? dstp: "",
5315c51f124SMoriah Waterland 					((get_inst_root()) &&
5325c51f124SMoriah Waterland 					(strcmp(get_inst_root(), "/") != 0)) ?
5335c51f124SMoriah Waterland 					get_inst_root() : "",
5345c51f124SMoriah Waterland 					ept->ainfo.mode, ept->cinfo.modtime,
5355c51f124SMoriah Waterland 					ept->ftype, ept->cinfo.cksum, n);
5365c51f124SMoriah Waterland 
5375c51f124SMoriah Waterland 				/*
5385c51f124SMoriah Waterland 				 * if not type 'e|v' and class 'none', then the
5395c51f124SMoriah Waterland 				 * file must already exist.
5405c51f124SMoriah Waterland 				 */
5415c51f124SMoriah Waterland 
5425c51f124SMoriah Waterland 				if ((ept->ftype != 'e') &&
5435c51f124SMoriah Waterland 					(ept->ftype != 'v') &&
5445c51f124SMoriah Waterland 					(strcmp(cl_nam(ept->pkg_class_idx),
5455c51f124SMoriah Waterland 								"none") == 0)) {
5465c51f124SMoriah Waterland 
5475c51f124SMoriah Waterland 					/*
5485c51f124SMoriah Waterland 					 * if the file is in a space inherited
5495c51f124SMoriah Waterland 					 * from the global zone, and if the
5505c51f124SMoriah Waterland 					 * contents or attributes are incorrect,
5515c51f124SMoriah Waterland 					 * then generate a warning that the
5525c51f124SMoriah Waterland 					 * global zone file contents and/or file
5535c51f124SMoriah Waterland 					 * attributes have been modified and
5545c51f124SMoriah Waterland 					 * that the modifications are extended
5555c51f124SMoriah Waterland 					 * to the non-global zone (inherited
5565c51f124SMoriah Waterland 					 * from the global zone).
5575c51f124SMoriah Waterland 					 */
5585c51f124SMoriah Waterland 
5595c51f124SMoriah Waterland 					if (n == 0) {
5605c51f124SMoriah Waterland 						/* is file changed? */
5615c51f124SMoriah Waterland 						n = finalck(ept, 1, 1, B_TRUE);
5625c51f124SMoriah Waterland 
5635c51f124SMoriah Waterland 						/* no - ok - continue */
5645c51f124SMoriah Waterland 						if (n == 0) {
5655c51f124SMoriah Waterland 							continue;
5665c51f124SMoriah Waterland 						}
5675c51f124SMoriah Waterland 
5685c51f124SMoriah Waterland 						/* output warning message */
5695c51f124SMoriah Waterland 						logerr(NOTE_INSTVOL_FINALCKFAIL,
5705c51f124SMoriah Waterland 							pkginst, ext->map_path,
5715c51f124SMoriah Waterland 							a_zoneName, ept->path);
5725c51f124SMoriah Waterland 						continue;
5735c51f124SMoriah Waterland 					} else if (!finalck(ept, 1, 1,
5745c51f124SMoriah Waterland 								B_FALSE)) {
5755c51f124SMoriah Waterland 						/*
5765c51f124SMoriah Waterland 						 * non-e/v file of class "none"
5775c51f124SMoriah Waterland 						 * not inherited from the global
5785c51f124SMoriah Waterland 						 * zone: verify file already
5795c51f124SMoriah Waterland 						 * exists:everything checks here
5805c51f124SMoriah Waterland 						 */
5815c51f124SMoriah Waterland 						mstat->attrchg = 0;
5825c51f124SMoriah Waterland 						mstat->contchg = 0;
5835c51f124SMoriah Waterland 					}
5845c51f124SMoriah Waterland 					continue;
5855c51f124SMoriah Waterland 				}
5865c51f124SMoriah Waterland 
5875c51f124SMoriah Waterland 				/*
5885c51f124SMoriah Waterland 				 * non-e/v file with class action script, or
5895c51f124SMoriah Waterland 				 * e/v file: if the file is in an area inherited
5905c51f124SMoriah Waterland 				 * from the global zone, then no need (or the
5915c51f124SMoriah Waterland 				 * ability) to update just accept the file as is
5925c51f124SMoriah Waterland 				 */
5935c51f124SMoriah Waterland 
5945c51f124SMoriah Waterland 				if (n == B_TRUE) {
5955c51f124SMoriah Waterland 					/*
5965c51f124SMoriah Waterland 					 * the object is in an area inherited
5975c51f124SMoriah Waterland 					 * from the global zone and the objects
5985c51f124SMoriah Waterland 					 * attributes are verified
5995c51f124SMoriah Waterland 					 */
6005c51f124SMoriah Waterland 
6015c51f124SMoriah Waterland 					mstat->attrchg = 0;
6025c51f124SMoriah Waterland 					mstat->contchg = 0;
6035c51f124SMoriah Waterland 
6045c51f124SMoriah Waterland 					/* NOTE: package object skipped */
6055c51f124SMoriah Waterland 
6065c51f124SMoriah Waterland 					if (skipped == (char *)NULL) {
6075c51f124SMoriah Waterland 						skipped = dstp;
6085c51f124SMoriah Waterland 					echoDebug(DBG_INSTVOL_OBJ_SKIPPED,
6095c51f124SMoriah Waterland 								skipped);
6105c51f124SMoriah Waterland 					}
6115c51f124SMoriah Waterland 					continue;
6125c51f124SMoriah Waterland 				}
6135c51f124SMoriah Waterland 			}
6145c51f124SMoriah Waterland 
6155c51f124SMoriah Waterland 			/*
6165c51f124SMoriah Waterland 			 * Copy from source media to target path and fix file
6175c51f124SMoriah Waterland 			 * mode and permission now in case installation halted.
6185c51f124SMoriah Waterland 			 */
6195c51f124SMoriah Waterland 
6205c51f124SMoriah Waterland 			if (z_path_is_inherited(dstp, ept->ftype,
6215c51f124SMoriah Waterland 			    get_inst_root()) == B_FALSE) {
6225c51f124SMoriah Waterland 
6235c51f124SMoriah Waterland 				/*
6245c51f124SMoriah Waterland 				 * If the filesystem is read-only don't attempt
6255c51f124SMoriah Waterland 				 * to copy a file. Just check that the content
6265c51f124SMoriah Waterland 				 * and attributes of the file are correct.
6275c51f124SMoriah Waterland 				 *
6285c51f124SMoriah Waterland 				 * Normally this doesn't happen, because files,
6295c51f124SMoriah Waterland 				 * which don't change, are not returned by
6305c51f124SMoriah Waterland 				 * domerg(). However when installing a patch in
6315c51f124SMoriah Waterland 				 * a sparse zone, which was already installed
6325c51f124SMoriah Waterland 				 * in global zone with -G option, NGZ's
6335c51f124SMoriah Waterland 				 * contents db still contains the old record
6345c51f124SMoriah Waterland 				 * for this file and therefore domerg()
6355c51f124SMoriah Waterland 				 * considers these files to be different even
6365c51f124SMoriah Waterland 				 * though they are the same.
6375c51f124SMoriah Waterland 				 */
6385c51f124SMoriah Waterland 				n = 0;
6395c51f124SMoriah Waterland 				if (is_fs_writeable(ept->path,
6405c51f124SMoriah Waterland 				    &(ext->fsys_value)))
6415c51f124SMoriah Waterland 					n = cppath(MODE_SET|DIR_DISPLAY, srcp,
6425c51f124SMoriah Waterland 					    dstp, ept->ainfo.mode);
6435c51f124SMoriah Waterland 
6445c51f124SMoriah Waterland 				if (n != 0) {
6455c51f124SMoriah Waterland 					warnflag++;
6465c51f124SMoriah Waterland 				} else if (!finalck(ept, 1, 1, B_FALSE)) {
6475c51f124SMoriah Waterland 					/*
6485c51f124SMoriah Waterland 					 * everything checks here
6495c51f124SMoriah Waterland 					 */
6505c51f124SMoriah Waterland 					mstat->attrchg = 0;
6515c51f124SMoriah Waterland 					mstat->contchg = 0;
6525c51f124SMoriah Waterland 				}
6535c51f124SMoriah Waterland 			}
6545c51f124SMoriah Waterland 
6555c51f124SMoriah Waterland 			/* NOTE: a package object was updated */
6565c51f124SMoriah Waterland 
6575c51f124SMoriah Waterland 			if (updated == (char *)NULL) {
6585c51f124SMoriah Waterland 				echoDebug(DBG_INSTVOL_OBJ_UPDATED, dstp);
6595c51f124SMoriah Waterland 				updated = dstp;
6605c51f124SMoriah Waterland 			}
6615c51f124SMoriah Waterland 		}
6625c51f124SMoriah Waterland 
6635c51f124SMoriah Waterland 		/*
6645c51f124SMoriah Waterland 		 * We have now completed processing of all pathnames
6655c51f124SMoriah Waterland 		 * associated with this volume and class.
6665c51f124SMoriah Waterland 		 */
6675c51f124SMoriah Waterland 		if (cl_iscript(classidx)) {
6685c51f124SMoriah Waterland 			/*
6695c51f124SMoriah Waterland 			 * Execute appropriate class action script
6705c51f124SMoriah Waterland 			 * with list of source/destination pathnames
6715c51f124SMoriah Waterland 			 * as the input to the script.
6725c51f124SMoriah Waterland 			 */
6735c51f124SMoriah Waterland 
6745c51f124SMoriah Waterland 			if (chdir(pkgbin)) {
6755c51f124SMoriah Waterland 				progerr(ERR_CHGDIR, pkgbin);
6765c51f124SMoriah Waterland 				quit(99);
6775c51f124SMoriah Waterland 			}
6785c51f124SMoriah Waterland 
6795c51f124SMoriah Waterland 			if (listfp) {
6805c51f124SMoriah Waterland 				(void) fclose(listfp);
6815c51f124SMoriah Waterland 			}
6825c51f124SMoriah Waterland 
6835c51f124SMoriah Waterland 			/*
6845c51f124SMoriah Waterland 			 * if the object associated with the class action script
6855c51f124SMoriah Waterland 			 * is in an area inherited from the global zone, then
6865c51f124SMoriah Waterland 			 * there is no need to run the class action script -
6875c51f124SMoriah Waterland 			 * assume that anything the script would do has already
6885c51f124SMoriah Waterland 			 * been done in the area shared from the global zone.
6895c51f124SMoriah Waterland 			 */
6905c51f124SMoriah Waterland 
6915c51f124SMoriah Waterland 			/* nothing updated, nothing skipped */
6925c51f124SMoriah Waterland 
6935c51f124SMoriah Waterland 			echoDebug(DBG_INSTVOL_CAS_INFO, is_partial_inst(),
6945c51f124SMoriah Waterland 				updated ? updated : "",
6955c51f124SMoriah Waterland 				skipped ? skipped : "",
6965c51f124SMoriah Waterland 				anyPathLocal ? anyPathLocal : "");
6975c51f124SMoriah Waterland 
6985c51f124SMoriah Waterland 			if ((is_partial_inst() != 0) &&
6995c51f124SMoriah Waterland 					(updated == (char *)NULL) &&
7005c51f124SMoriah Waterland 					(anyPathLocal == (char *)NULL)) {
7015c51f124SMoriah Waterland 
7025c51f124SMoriah Waterland 				/*
7035c51f124SMoriah Waterland 				 * installing in non-global zone, and no object
7045c51f124SMoriah Waterland 				 * has been updated (installed/verified in non-
7055c51f124SMoriah Waterland 				 * inherited area), and no path delivered by the
7065c51f124SMoriah Waterland 				 * package is in an area not inherited from the
7075c51f124SMoriah Waterland 				 * global zone (all paths delivered are in
7085c51f124SMoriah Waterland 				 * areas inherited from the global zone): do not
7095c51f124SMoriah Waterland 				 * run the class action script because the only
7105c51f124SMoriah Waterland 				 * affected areas are inherited (read only).
7115c51f124SMoriah Waterland 				 */
7125c51f124SMoriah Waterland 
7135c51f124SMoriah Waterland 				echoDebug(DBG_INSTVOL_NOT_RUNNING_CAS,
7145c51f124SMoriah Waterland 					a_zoneName ? a_zoneName : "?",
7155c51f124SMoriah Waterland 					eocflag ? "ENDOFCLASS" :
7165c51f124SMoriah Waterland 							cl_iscript(classidx),
7175c51f124SMoriah Waterland 					cl_nam(classidx),
7185c51f124SMoriah Waterland 					cl_iscript(classidx));
7195c51f124SMoriah Waterland 
7205c51f124SMoriah Waterland 				if ((r_skipped != (char **)NULL) &&
7215c51f124SMoriah Waterland 					(*r_skipped == (char *)NULL) &&
7225c51f124SMoriah Waterland 					(skipped == (char *)NULL)) {
7235c51f124SMoriah Waterland 					skipped = "postinstall";
7245c51f124SMoriah Waterland 					echoDebug(DBG_INSTVOL_OBJ_SKIPPED,
7255c51f124SMoriah Waterland 								skipped);
7265c51f124SMoriah Waterland 				}
7275c51f124SMoriah Waterland 			} else {
7285c51f124SMoriah Waterland 				/* run the class action script */
7295c51f124SMoriah Waterland 
7305c51f124SMoriah Waterland 				echoDebug(DBG_INSTVOL_RUNNING_CAS,
7315c51f124SMoriah Waterland 					a_zoneName ? a_zoneName : "?",
7325c51f124SMoriah Waterland 					eocflag ? "ENDOFCLASS" :
7335c51f124SMoriah Waterland 							cl_iscript(classidx),
7345c51f124SMoriah Waterland 					cl_nam(classidx),
7355c51f124SMoriah Waterland 					cl_iscript(classidx));
7365c51f124SMoriah Waterland 
7375c51f124SMoriah Waterland 				/* Use ULIMIT if supplied. */
7385c51f124SMoriah Waterland 				set_ulimit(cl_iscript(classidx), ERR_CASFAIL);
7395c51f124SMoriah Waterland 
7405c51f124SMoriah Waterland 				if (eocflag) {
7415c51f124SMoriah Waterland 					/*
7425c51f124SMoriah Waterland 					 * end of class detected.
7435c51f124SMoriah Waterland 					 * Since there are no more volumes which
7445c51f124SMoriah Waterland 					 * contain pathnames associated with
7455c51f124SMoriah Waterland 					 * this class, execute class action
7465c51f124SMoriah Waterland 					 * script with the ENDOFCLASS argument;
7475c51f124SMoriah Waterland 					 * we do this even if none of the path
7485c51f124SMoriah Waterland 					 * names associated with this class and
7495c51f124SMoriah Waterland 					 * volume needed installation to
7505c51f124SMoriah Waterland 					 * guarantee the class action script is
7515c51f124SMoriah Waterland 					 * executed at least once during package
7525c51f124SMoriah Waterland 					 * installation.
7535c51f124SMoriah Waterland 					 */
7545c51f124SMoriah Waterland 					if (pkgverbose) {
7555c51f124SMoriah Waterland 						n = pkgexecl((listfp ?
7565c51f124SMoriah Waterland 							listfile : CAS_STDIN),
7575c51f124SMoriah Waterland 							CAS_STDOUT,
7585c51f124SMoriah Waterland 							CAS_USER, CAS_GRP,
7595c51f124SMoriah Waterland 							SHELL, "-x",
7605c51f124SMoriah Waterland 							cl_iscript(classidx),
7615c51f124SMoriah Waterland 							"ENDOFCLASS", NULL);
7625c51f124SMoriah Waterland 					} else {
7635c51f124SMoriah Waterland 						n = pkgexecl(
7645c51f124SMoriah Waterland 							(listfp ?
7655c51f124SMoriah Waterland 							listfile : CAS_STDIN),
7665c51f124SMoriah Waterland 							CAS_STDOUT, CAS_USER,
7675c51f124SMoriah Waterland 							CAS_GRP, SHELL,
7685c51f124SMoriah Waterland 							cl_iscript(classidx),
7695c51f124SMoriah Waterland 							"ENDOFCLASS", NULL);
7705c51f124SMoriah Waterland 					}
7715c51f124SMoriah Waterland 					ckreturn(n, ERR_CASFAIL);
7725c51f124SMoriah Waterland 				} else if (count) {
7735c51f124SMoriah Waterland 					/* execute class action script */
7745c51f124SMoriah Waterland 					if (pkgverbose) {
7755c51f124SMoriah Waterland 						n = pkgexecl(listfile,
7765c51f124SMoriah Waterland 							CAS_STDOUT, CAS_USER,
7775c51f124SMoriah Waterland 							CAS_GRP, SHELL, "-x",
7785c51f124SMoriah Waterland 							cl_iscript(classidx),
7795c51f124SMoriah Waterland 							NULL);
7805c51f124SMoriah Waterland 					} else {
7815c51f124SMoriah Waterland 						n = pkgexecl(listfile,
7825c51f124SMoriah Waterland 							CAS_STDOUT, CAS_USER,
7835c51f124SMoriah Waterland 							CAS_GRP, SHELL,
7845c51f124SMoriah Waterland 							cl_iscript(classidx),
7855c51f124SMoriah Waterland 							NULL);
7865c51f124SMoriah Waterland 					}
7875c51f124SMoriah Waterland 					ckreturn(n, ERR_CASFAIL);
7885c51f124SMoriah Waterland 				}
7895c51f124SMoriah Waterland 
7905c51f124SMoriah Waterland 				/*
7915c51f124SMoriah Waterland 				 * Ensure the mod times on disk match those
7925c51f124SMoriah Waterland 				 * in the pkgmap. In this case, call cverify
7935c51f124SMoriah Waterland 				 * with checksumming disabled, since the only
7945c51f124SMoriah Waterland 				 * action that needs to be done is to verify
7955c51f124SMoriah Waterland 				 * that the attributes are correct.
7965c51f124SMoriah Waterland 				 */
7975c51f124SMoriah Waterland 
7985c51f124SMoriah Waterland 				if ((rfp = regfiles_head) != NULL) {
7995c51f124SMoriah Waterland 					while (rfp != NULL) {
8005c51f124SMoriah Waterland 					    ept = &(extlist[rfp->val]->cf_ent);
8015c51f124SMoriah Waterland 					    cverify(1, &ept->ftype, ept->path,
8025c51f124SMoriah Waterland 						&ept->cinfo, 0);
8035c51f124SMoriah Waterland 					    rfp = rfp->next;
8045c51f124SMoriah Waterland 					}
8055c51f124SMoriah Waterland 					regfiles_free();
8065c51f124SMoriah Waterland 				}
8075c51f124SMoriah Waterland 
8085c51f124SMoriah Waterland 				clr_ulimit();
8095c51f124SMoriah Waterland 
8105c51f124SMoriah Waterland 				if ((r_updated != (char **)NULL) &&
8115c51f124SMoriah Waterland 					(*r_updated == (char *)NULL) &&
8125c51f124SMoriah Waterland 					(updated == (char *)NULL)) {
8135c51f124SMoriah Waterland 					updated = "postinstall";
8145c51f124SMoriah Waterland 					echoDebug(DBG_INSTVOL_OBJ_UPDATED,
8155c51f124SMoriah Waterland 								updated);
8165c51f124SMoriah Waterland 				}
8175c51f124SMoriah Waterland 			}
8185c51f124SMoriah Waterland 			if (listfile) {
8195c51f124SMoriah Waterland 				(void) remove(listfile);
8205c51f124SMoriah Waterland 			}
8215c51f124SMoriah Waterland 		}
8225c51f124SMoriah Waterland 
8235c51f124SMoriah Waterland 		if (eocflag && (!is_partial_inst() || (is_partial_inst() &&
8245c51f124SMoriah Waterland 			strcmp(cl_nam(classidx), "none") != 0))) {
8255c51f124SMoriah Waterland 			if (cl_dvfy(classidx) == QKVERIFY && !repl_permitted) {
8265c51f124SMoriah Waterland 				/*
8275c51f124SMoriah Waterland 				 * The quick verify just fixes everything.
8285c51f124SMoriah Waterland 				 * If it returns 0, all is well. If it
8295c51f124SMoriah Waterland 				 * returns 1, then the class installation
8305c51f124SMoriah Waterland 				 * was incomplete and we retry on the
8315c51f124SMoriah Waterland 				 * stuff that failed in the conventional
8325c51f124SMoriah Waterland 				 * way (without a CAS). this is primarily
8335c51f124SMoriah Waterland 				 * to accomodate old archives such as are
8345c51f124SMoriah Waterland 				 * found in pre-2.5 WOS; but, it is also
8355c51f124SMoriah Waterland 				 * used when a critical dynamic library
8365c51f124SMoriah Waterland 				 * is not archived with its class.
8375c51f124SMoriah Waterland 				 */
8385c51f124SMoriah Waterland 				if (!fix_attributes(extlist, classidx)) {
8395c51f124SMoriah Waterland 					/*
8405c51f124SMoriah Waterland 					 * Reset the CAS pointer. If the
8415c51f124SMoriah Waterland 					 * function returns 0 then there
8425c51f124SMoriah Waterland 					 * was no script there in the first
8435c51f124SMoriah Waterland 					 * place and we'll just have to
8445c51f124SMoriah Waterland 					 * call this a miss.
8455c51f124SMoriah Waterland 					 */
8465c51f124SMoriah Waterland 					if (cl_deliscript(classidx))
8475c51f124SMoriah Waterland 						/*
8485c51f124SMoriah Waterland 						 * Decrement classidx for
8495c51f124SMoriah Waterland 						 * next pass.
8505c51f124SMoriah Waterland 						 */
8515c51f124SMoriah Waterland 						classidx--;
8525c51f124SMoriah Waterland 				}
8535c51f124SMoriah Waterland 			} else {
8545c51f124SMoriah Waterland 				/*
8555c51f124SMoriah Waterland 				 * Finalize merge. This checks to make sure
8565c51f124SMoriah Waterland 				 * file attributes are correct and any links
8575c51f124SMoriah Waterland 				 * specified are created.
8585c51f124SMoriah Waterland 				 */
8595c51f124SMoriah Waterland 				(void) endofclass(extlist, classidx,
8605c51f124SMoriah Waterland 					(cl_iscript(classidx) ? 0 : 1),
861*62224350SCasper H.S. Dik 					pkgserver, a_cfTmpVfp);
8625c51f124SMoriah Waterland 			}
8635c51f124SMoriah Waterland 		}
8645c51f124SMoriah Waterland 	    }
8655c51f124SMoriah Waterland 	}
8665c51f124SMoriah Waterland 
8675c51f124SMoriah Waterland 	/*
8685c51f124SMoriah Waterland 	 * Instead of creating links back to the GZ files the logic is
8695c51f124SMoriah Waterland 	 * to let zdo recreate the files from the GZ then invoke pkgadd to
8705c51f124SMoriah Waterland 	 * install the editable files and skip over any 'f'type files.
8715c51f124SMoriah Waterland 	 * The commented out block is to create the links which should be
8725c51f124SMoriah Waterland 	 * removed once the current code is tested to be correct.
8735c51f124SMoriah Waterland 	 */
8745c51f124SMoriah Waterland 
8755c51f124SMoriah Waterland 	/*
8765c51f124SMoriah Waterland 	 * Go through extlist creating links for 'f'type files
8775c51f124SMoriah Waterland 	 * if we're in a global zone. Note that this code lies
8785c51f124SMoriah Waterland 	 * here instead of in the main loop to support CAF packages.
8795c51f124SMoriah Waterland 	 * In a CAF package the files are installed by the i.none script
8805c51f124SMoriah Waterland 	 * and don't exist until all files are done being processed, thus
8815c51f124SMoriah Waterland 	 * the additional loop through extlist.
8825c51f124SMoriah Waterland 	 */
8835c51f124SMoriah Waterland 
8845c51f124SMoriah Waterland 	/*
8855c51f124SMoriah Waterland 	 * output appropriate completion message
8865c51f124SMoriah Waterland 	 */
8875c51f124SMoriah Waterland 
8885c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB() == B_TRUE) {
8895c51f124SMoriah Waterland 		/* updating database only (hollow package) */
8905c51f124SMoriah Waterland 		if (a_zoneName == (char *)NULL) {
8915c51f124SMoriah Waterland 			echo(MSG_DBUPD_N_N, part, nparts);
8925c51f124SMoriah Waterland 		} else {
8935c51f124SMoriah Waterland 			echo(MSG_DBUPD_N_N_LZ, part, nparts, a_zoneName);
8945c51f124SMoriah Waterland 		}
8955c51f124SMoriah Waterland 	} else if (tcount == 0) {
8965c51f124SMoriah Waterland 		/* updating package (non-hollow package) */
8975c51f124SMoriah Waterland 		if (a_zoneName == (char *)NULL) {
8985c51f124SMoriah Waterland 			echo(MSG_INST_N_N, part, nparts);
8995c51f124SMoriah Waterland 		} else {
9005c51f124SMoriah Waterland 			echo(MSG_INST_N_N_LZ, part, nparts, a_zoneName);
9015c51f124SMoriah Waterland 		}
9025c51f124SMoriah Waterland 	}
9035c51f124SMoriah Waterland 
9045c51f124SMoriah Waterland 	/*
9055c51f124SMoriah Waterland 	 * if any package objects were updated (not inherited from the
9065c51f124SMoriah Waterland 	 * global zone or otherwise already in existence), set the updated
9075c51f124SMoriah Waterland 	 * flag as appropriate
9085c51f124SMoriah Waterland 	 */
9095c51f124SMoriah Waterland 
9105c51f124SMoriah Waterland 	if (updated != (char *)NULL) {
9115c51f124SMoriah Waterland 		echoDebug(DBG_INSTVOL_OBJ_UPDATED, updated);
9125c51f124SMoriah Waterland 		if (r_updated != (char **)NULL) {
9135c51f124SMoriah Waterland 			*r_updated = updated;
9145c51f124SMoriah Waterland 		}
9155c51f124SMoriah Waterland 	}
9165c51f124SMoriah Waterland 
9175c51f124SMoriah Waterland 	/*
9185c51f124SMoriah Waterland 	 * if any package objects were skipped (verified inherited from the
9195c51f124SMoriah Waterland 	 * global zone), set the skipped flag as appropriate
9205c51f124SMoriah Waterland 	 */
9215c51f124SMoriah Waterland 
9225c51f124SMoriah Waterland 	if (skipped != (char *)NULL) {
9235c51f124SMoriah Waterland 		echoDebug(DBG_INSTVOL_OBJ_SKIPPED, skipped);
9245c51f124SMoriah Waterland 		if (r_skipped != (char **)NULL) {
9255c51f124SMoriah Waterland 			*r_skipped = skipped;
9265c51f124SMoriah Waterland 		}
9275c51f124SMoriah Waterland 	}
9285c51f124SMoriah Waterland }
9295c51f124SMoriah Waterland 
9305c51f124SMoriah Waterland /*
9315c51f124SMoriah Waterland  * Name:	domerg
9325c51f124SMoriah Waterland  * Description: For the specified class, review each entry and return the array
9335c51f124SMoriah Waterland  *		index number of the next regular file to process. Hard links are
9345c51f124SMoriah Waterland  *		skipped (they are created in endofclass() and directories,
9355c51f124SMoriah Waterland  *		symlinks, pipes and devices are created here, as well as any
9365c51f124SMoriah Waterland  *		file that already exists and has the correct attributes.
9375c51f124SMoriah Waterland  * Arguments:	struct cfextra **extlist - [RO, *RW]
9385c51f124SMoriah Waterland  *			- Pointer to list of cfextra structures representing
9395c51f124SMoriah Waterland  *			  the pkgmap of the package to be installed
9405c51f124SMoriah Waterland  *		int part - [RO, *RO]
9415c51f124SMoriah Waterland  *			- the part of the package currently being processed;
9425c51f124SMoriah Waterland  *			  packages begin with part "1" and proceed for the
9435c51f124SMoriah Waterland  *			  number (nparts) that comprise the package (volume).
9445c51f124SMoriah Waterland  *		int nparts - [RO, *RO]
9455c51f124SMoriah Waterland  *			- the number of parts the package is divided into
9465c51f124SMoriah Waterland  *		int myclass - [RO, *RO]
9475c51f124SMoriah Waterland  *			- index into class array of the current class
9485c51f124SMoriah Waterland  *		char **srcp - [RW, *RW]
9495c51f124SMoriah Waterland  *			- pointer to pointer to string representing the source
9505c51f124SMoriah Waterland  *			  path for the next package to process - if this
9515c51f124SMoriah Waterland  *			  function returns != DMRG_DONE then this pointer is
9525c51f124SMoriah Waterland  *			  set to a pointer to a string representing the source
9535c51f124SMoriah Waterland  *			  path for the next object from the package to process
9545c51f124SMoriah Waterland  *		char **dstp - [RW, *RW]
9555c51f124SMoriah Waterland  *			- pointer to pointer to string representing the target
9565c51f124SMoriah Waterland  *			  path for the next package to process - if this
9575c51f124SMoriah Waterland  *			  function returns != DMRG_DONE then this pointer is
9585c51f124SMoriah Waterland  *			  set to a pointer to a string representing the target
9595c51f124SMoriah Waterland  *			  path for the next object from the package to process
9605c51f124SMoriah Waterland  *		char **r_updated - [RO, *RW]
9615c51f124SMoriah Waterland  *			- pointer to pointer to string - set if the last path
9625c51f124SMoriah Waterland  *			  returned exists or does not need updating and the
9635c51f124SMoriah Waterland  *			  object is NOT located in an area inherited from the
9645c51f124SMoriah Waterland  *			  global zone. This is used to determine if the last
9655c51f124SMoriah Waterland  *			  path object returned DOES exist in an area that is
9665c51f124SMoriah Waterland  *			  inherited from the global zone. If no paths are
9675c51f124SMoriah Waterland  *			  inherited from the global zone, this is always set
9685c51f124SMoriah Waterland  *			  when a path to be installed exists and has the
9695c51f124SMoriah Waterland  *			  correct contents.
9705c51f124SMoriah Waterland  *		char **r_skipped - [RO, *RW]
9715c51f124SMoriah Waterland  *			- pointer to pointer to string - set if the last path
9725c51f124SMoriah Waterland  *			  returned exists or does not need updating and the
9735c51f124SMoriah Waterland  *			  object IS located in an area inherited from the
9745c51f124SMoriah Waterland  *			  global zone. This is used to determine if the last
9755c51f124SMoriah Waterland  *			  path object returned does NOT exist in an area that
9765c51f124SMoriah Waterland  *			  is inherited from the global zone. If no paths are
9775c51f124SMoriah Waterland  *			  inherited from the global zone, this is never set.
9785c51f124SMoriah Waterland  *		char **r_anyPathLocal - [RO, *RW]
9795c51f124SMoriah Waterland  *			- pointer to pointer to string - set if any object
9805c51f124SMoriah Waterland  *			  belonging to the package is NOT located in an area
9815c51f124SMoriah Waterland  *			  inherited from the global zone. This is used to
9825c51f124SMoriah Waterland  *			  determine if the package references ANY objects that
9835c51f124SMoriah Waterland  *			  are NOT located in an area inherited from the global
9845c51f124SMoriah Waterland  *			  zone - regardless of whether or not they need to be
9855c51f124SMoriah Waterland  *			  updated (installed/copied). If no paths are inherited
9865c51f124SMoriah Waterland  *			  from the global zone, this is always set when a path
9875c51f124SMoriah Waterland  *			  to be installed already exists and has the correct
9885c51f124SMoriah Waterland  *			  contents.
9895c51f124SMoriah Waterland  * Returns:	int
9905c51f124SMoriah Waterland  *			!= DMRG_DONE - index into extlist of the next path to
9915c51f124SMoriah Waterland  *				be processed - that needs to be installed/copied
9925c51f124SMoriah Waterland  *			== DMRG_DONE - all entries processed
9935c51f124SMoriah Waterland  */
9945c51f124SMoriah Waterland 
9955c51f124SMoriah Waterland static int
9965c51f124SMoriah Waterland domerg(struct cfextra **extlist, int part, int nparts,
9975c51f124SMoriah Waterland 	int myclass, char **srcp, char **dstp,
9985c51f124SMoriah Waterland 	char **r_updated, char **r_skipped,
9995c51f124SMoriah Waterland 	char **r_anyPathLocal)
10005c51f124SMoriah Waterland {
10015c51f124SMoriah Waterland 	boolean_t	stateFlag = B_FALSE;
10025c51f124SMoriah Waterland 	int		i;
10035c51f124SMoriah Waterland 	int		msg_ugid;
10045c51f124SMoriah Waterland 	static int	maxvol = 0;
10055c51f124SMoriah Waterland 	static int	svindx = 0;
10065c51f124SMoriah Waterland 	static int	svpart = 0;
10075c51f124SMoriah Waterland 	struct cfent	*ept = (struct cfent *)NULL;
10085c51f124SMoriah Waterland 	struct mergstat *mstat = (struct mergstat *)NULL;
10095c51f124SMoriah Waterland 
10105c51f124SMoriah Waterland 	/* reset returned path pointers */
10115c51f124SMoriah Waterland 
10125c51f124SMoriah Waterland 	*dstp = (char *)NULL;
10135c51f124SMoriah Waterland 	*srcp = (char *)NULL;
10145c51f124SMoriah Waterland 
10155c51f124SMoriah Waterland 	/* set to start or continue based on which part being processed */
10165c51f124SMoriah Waterland 
10175c51f124SMoriah Waterland 	if (part != 0) {
10185c51f124SMoriah Waterland 		maxvol = 0;
10195c51f124SMoriah Waterland 		svindx = 0;
10205c51f124SMoriah Waterland 		svpart = part;
10215c51f124SMoriah Waterland 	} else {
10225c51f124SMoriah Waterland 		i = svindx;
10235c51f124SMoriah Waterland 		part = svpart;
10245c51f124SMoriah Waterland 	}
10255c51f124SMoriah Waterland 
10265c51f124SMoriah Waterland 	/*
10275c51f124SMoriah Waterland 	 * This goes through the pkgmap entries one by one testing them
10285c51f124SMoriah Waterland 	 * for inclusion in the package database as well as for validity
10295c51f124SMoriah Waterland 	 * against existing files.
10305c51f124SMoriah Waterland 	 */
10315c51f124SMoriah Waterland 	for (i = svindx; extlist[i]; i++) {
10325c51f124SMoriah Waterland 		ept = &(extlist[i]->cf_ent);
10335c51f124SMoriah Waterland 		mstat = &(extlist[i]->mstat);
10345c51f124SMoriah Waterland 
10355c51f124SMoriah Waterland 		/*
10365c51f124SMoriah Waterland 		 * as paths are processed, if the "anyPathLocal" flag has not
10375c51f124SMoriah Waterland 		 * been set, if the object is not of type 'i' (package script),
10385c51f124SMoriah Waterland 		 * check to see if the object is in an area inherited from the
10395c51f124SMoriah Waterland 		 * global zone - if not, set "anyPathLocal" to the path found,
10405c51f124SMoriah Waterland 		 * indicating that at least one path is in an area that is not
10415c51f124SMoriah Waterland 		 * inherited from the global zone.
10425c51f124SMoriah Waterland 		 */
10435c51f124SMoriah Waterland 
10445c51f124SMoriah Waterland 		if ((r_anyPathLocal != (char **)NULL) &&
10455c51f124SMoriah Waterland 			(*r_anyPathLocal == (char *)NULL) &&
10465c51f124SMoriah Waterland 			(ept->ftype != 'i') &&
10475c51f124SMoriah Waterland 			(z_path_is_inherited(ept->path, ept->ftype,
10485c51f124SMoriah Waterland 						get_inst_root()) == B_FALSE)) {
10495c51f124SMoriah Waterland 			echoDebug(DBG_INSTVOL_OBJ_LOCAL, ept->path);
10505c51f124SMoriah Waterland 			*r_anyPathLocal = ept->path;
10515c51f124SMoriah Waterland 		}
10525c51f124SMoriah Waterland 
10535c51f124SMoriah Waterland 		/* if this isn't the class of current interest, skip it */
10545c51f124SMoriah Waterland 
10555c51f124SMoriah Waterland 		if (myclass != ept->pkg_class_idx) {
10565c51f124SMoriah Waterland 			continue;
10575c51f124SMoriah Waterland 		}
10585c51f124SMoriah Waterland 
10595c51f124SMoriah Waterland 		/* if the class is invalid, announce it & exit */
10605c51f124SMoriah Waterland 		if (ept->pkg_class_idx == -1) {
10615c51f124SMoriah Waterland 			progerr(ERR_CLIDX, ept->pkg_class_idx,
10625c51f124SMoriah Waterland 			    (ept->path && *ept->path) ? ept->path : "unknown");
1063*62224350SCasper H.S. Dik 			logerr(gettext("pathname=%s"),
10645c51f124SMoriah Waterland 			    (ept->path && *ept->path) ? ept->path : "unknown");
1065*62224350SCasper H.S. Dik 			logerr(gettext("class=<%s>"),
10665c51f124SMoriah Waterland 			    (ept->pkg_class && *ept->pkg_class) ?
10675c51f124SMoriah Waterland 			    ept->pkg_class : "Unknown");
1068*62224350SCasper H.S. Dik 			logerr(gettext("CLASSES=<%s>"),
10695c51f124SMoriah Waterland 			    getenv("CLASSES") ? getenv("CLASSES") : "Not Set");
10705c51f124SMoriah Waterland 			quit(99);
10715c51f124SMoriah Waterland 		}
10725c51f124SMoriah Waterland 
10735c51f124SMoriah Waterland 		/*
10745c51f124SMoriah Waterland 		 * Next check to see if we are going to try to delete a
10755c51f124SMoriah Waterland 		 * populated directory in some distressing way.
10765c51f124SMoriah Waterland 		 */
10775c51f124SMoriah Waterland 		if (mstat->dir2nondir)
10785c51f124SMoriah Waterland 			if (dir_is_populated(ept->path)) {
10795c51f124SMoriah Waterland 				logerr(WRN_INSTVOL_NOTDIR, ept->path);
10805c51f124SMoriah Waterland 				warnflag++;
10815c51f124SMoriah Waterland 				mstat->denied = 1;	/* install denied! */
10825c51f124SMoriah Waterland 				continue;
10835c51f124SMoriah Waterland 			} else {	/* Replace is OK. */
10845c51f124SMoriah Waterland 				/*
10855c51f124SMoriah Waterland 				 * Remove this directory, so it won't
10865c51f124SMoriah Waterland 				 * interfere with creation of the new object.
10875c51f124SMoriah Waterland 				 */
10885c51f124SMoriah Waterland 				if (rmdir(ept->path)) {
10895c51f124SMoriah Waterland 					/*
10905c51f124SMoriah Waterland 					 * If it didn't work, there's nothing
10915c51f124SMoriah Waterland 					 * we can do. To continue would
10925c51f124SMoriah Waterland 					 * likely corrupt the filesystem
10935c51f124SMoriah Waterland 					 * which is unacceptable.
10945c51f124SMoriah Waterland 					 */
10955c51f124SMoriah Waterland 					progerr(ERR_RMDIR, ept->path);
10965c51f124SMoriah Waterland 					quit(99);
10975c51f124SMoriah Waterland 				}
10985c51f124SMoriah Waterland 
10995c51f124SMoriah Waterland 				repl_permitted = 1;	/* flag it */
11005c51f124SMoriah Waterland 			}
11015c51f124SMoriah Waterland 
11025c51f124SMoriah Waterland 		/* adjust the max volume number appropriately */
11035c51f124SMoriah Waterland 
11045c51f124SMoriah Waterland 		if (ept->volno > maxvol) {
11055c51f124SMoriah Waterland 			maxvol = ept->volno;
11065c51f124SMoriah Waterland 		}
11075c51f124SMoriah Waterland 
11085c51f124SMoriah Waterland 		/* if this part goes into another volume, skip it */
11095c51f124SMoriah Waterland 
11105c51f124SMoriah Waterland 		if (part != ept->volno) {
11115c51f124SMoriah Waterland 			continue;
11125c51f124SMoriah Waterland 		}
11135c51f124SMoriah Waterland 
11145c51f124SMoriah Waterland 		/*
11155c51f124SMoriah Waterland 		 * If it's a conflicting file and it's not supposed to be
11165c51f124SMoriah Waterland 		 * installed, note it and skip.
11175c51f124SMoriah Waterland 		 */
11185c51f124SMoriah Waterland 		if (nocnflct && mstat->shared && ept->ftype != 'e') {
11195c51f124SMoriah Waterland 			if (mstat->contchg || mstat->attrchg) {
11205c51f124SMoriah Waterland 				echo(MSG_SHIGN, ept->path);
11215c51f124SMoriah Waterland 			}
11225c51f124SMoriah Waterland 			continue;
11235c51f124SMoriah Waterland 		}
11245c51f124SMoriah Waterland 
11255c51f124SMoriah Waterland 		/*
11265c51f124SMoriah Waterland 		 * If we want to set uid or gid but user says no, note it.
11275c51f124SMoriah Waterland 		 * Remember that the actual mode bits in the structure have
11285c51f124SMoriah Waterland 		 * already been adjusted and the mstat flag is telling us
11295c51f124SMoriah Waterland 		 * about the original mode.
11305c51f124SMoriah Waterland 		 */
11315c51f124SMoriah Waterland 		if (nosetuid && (mstat->setuid || mstat->setgid)) {
11325c51f124SMoriah Waterland 			msg_ugid = 1;	/* don't repeat attribute message. */
11335c51f124SMoriah Waterland 			if (is_fs_writeable(ept->path,
11345c51f124SMoriah Waterland 				&(extlist[i]->fsys_value))) {
11355c51f124SMoriah Waterland 				if (!(mstat->contchg) && mstat->attrchg) {
11365c51f124SMoriah Waterland 					echo(MSG_UGMOD, ept->path);
11375c51f124SMoriah Waterland 				} else {
11385c51f124SMoriah Waterland 					echo(MSG_UGID, ept->path);
11395c51f124SMoriah Waterland 				}
11405c51f124SMoriah Waterland 			}
11415c51f124SMoriah Waterland 		} else {
11425c51f124SMoriah Waterland 			msg_ugid = 0;
11435c51f124SMoriah Waterland 		}
11445c51f124SMoriah Waterland 
11455c51f124SMoriah Waterland 		switch (ept->ftype) {
11465c51f124SMoriah Waterland 			case 'l':	/* hard link */
11475c51f124SMoriah Waterland 				/* links treated as object "update/skip" */
11485c51f124SMoriah Waterland 				stateFlag = B_TRUE;
11495c51f124SMoriah Waterland 				continue; /* defer to final proc */
11505c51f124SMoriah Waterland 
11515c51f124SMoriah Waterland 			case 's': /* for symlink, verify without fix first */
11525c51f124SMoriah Waterland 				/* links treated as object "update/skip" */
11535c51f124SMoriah Waterland 				stateFlag = B_TRUE;
11545c51f124SMoriah Waterland 
11555c51f124SMoriah Waterland 				/* Do this only for default verify */
11565c51f124SMoriah Waterland 				if (cl_dvfy(myclass) == DEFAULT) {
11575c51f124SMoriah Waterland 					if (averify(0, &ept->ftype,
11585c51f124SMoriah Waterland 						ept->path, &ept->ainfo))
11595c51f124SMoriah Waterland 						echo(MSG_SLINK, ept->path);
11605c51f124SMoriah Waterland 				}
11615c51f124SMoriah Waterland 
11625c51f124SMoriah Waterland 				/*FALLTHRU*/
11635c51f124SMoriah Waterland 
11645c51f124SMoriah Waterland 			case 'd':	/* directory */
11655c51f124SMoriah Waterland 			case 'x':	/* exclusive directory */
11665c51f124SMoriah Waterland 			case 'c':	/* character special device */
11675c51f124SMoriah Waterland 			case 'b':	/* block special device */
11685c51f124SMoriah Waterland 			case 'p':	/* named pipe */
11695c51f124SMoriah Waterland 				/* these NOT treated as object "update/skip" */
11705c51f124SMoriah Waterland 				stateFlag = B_FALSE;
11715c51f124SMoriah Waterland 
11725c51f124SMoriah Waterland 				/*
11735c51f124SMoriah Waterland 				 * If we can't get to it for legitimate reasons,
11745c51f124SMoriah Waterland 				 * don't try to verify it.
11755c51f124SMoriah Waterland 				 */
11765c51f124SMoriah Waterland 				if ((z_path_is_inherited(ept->path, ept->ftype,
11775c51f124SMoriah Waterland 				    get_inst_root())) ||
11785c51f124SMoriah Waterland 				    is_remote_fs(ept->path,
11795c51f124SMoriah Waterland 				    &(extlist[i]->fsys_value)) &&
11805c51f124SMoriah Waterland 				    !is_fs_writeable(ept->path,
11815c51f124SMoriah Waterland 				    &(extlist[i]->fsys_value))) {
11825c51f124SMoriah Waterland 					mstat->attrchg = 0;
11835c51f124SMoriah Waterland 					mstat->contchg = 0;
11845c51f124SMoriah Waterland 					break;
11855c51f124SMoriah Waterland 				}
11865c51f124SMoriah Waterland 
11875c51f124SMoriah Waterland 				if (averify(1, &ept->ftype, ept->path,
11885c51f124SMoriah Waterland 							&ept->ainfo) == 0) {
11895c51f124SMoriah Waterland 					mstat->contchg = mstat->attrchg = 0;
11905c51f124SMoriah Waterland 				} else {
11915c51f124SMoriah Waterland 					progerr(ERR_CREATE_PKGOBJ, ept->path);
11925c51f124SMoriah Waterland 					logerr(getErrbufAddr());
11935c51f124SMoriah Waterland 					warnflag++;
11945c51f124SMoriah Waterland 				}
11955c51f124SMoriah Waterland 
11965c51f124SMoriah Waterland 				break;
11975c51f124SMoriah Waterland 
11985c51f124SMoriah Waterland 			case 'i':	/* information file */
11995c51f124SMoriah Waterland 				/* not treated as object "update/skip" */
12005c51f124SMoriah Waterland 				stateFlag = B_FALSE;
12015c51f124SMoriah Waterland 				break;
12025c51f124SMoriah Waterland 
12035c51f124SMoriah Waterland 			default:
12045c51f124SMoriah Waterland 				/* all files treated as object "update/skip" */
12055c51f124SMoriah Waterland 				stateFlag = B_TRUE;
12065c51f124SMoriah Waterland 				break;
12075c51f124SMoriah Waterland 		}
12085c51f124SMoriah Waterland 
12095c51f124SMoriah Waterland 		/*
12105c51f124SMoriah Waterland 		 * Both contchg and shared flags have to be taken into
12115c51f124SMoriah Waterland 		 * account. contchg is set if the file is already present
12125c51f124SMoriah Waterland 		 * in the package database, if it does not exist or if it
12135c51f124SMoriah Waterland 		 * exists and is modified.
12145c51f124SMoriah Waterland 		 * The shared flag is set when 'e' or 'v' file is not
12155c51f124SMoriah Waterland 		 * present in the package database, exists and is not
12165c51f124SMoriah Waterland 		 * modified. It also has to be checked here.
12175c51f124SMoriah Waterland 		 * Shared flag is also set when file is present in package
12185c51f124SMoriah Waterland 		 * database and owned by more than one package, but for
12195c51f124SMoriah Waterland 		 * this case contchg has already been set.
12205c51f124SMoriah Waterland 		 */
12215c51f124SMoriah Waterland 		if (mstat->contchg || (mstat->shared &&
12225c51f124SMoriah Waterland 		    ((ept->ftype == 'e') || (ept->ftype == 'v')))) {
12235c51f124SMoriah Waterland 			*dstp = ept->path;
12245c51f124SMoriah Waterland 			if ((ept->ftype == 'f') || (ept->ftype == 'e') ||
12255c51f124SMoriah Waterland 				(ept->ftype == 'v')) {
12265c51f124SMoriah Waterland 				*srcp = ept->ainfo.local;
12275c51f124SMoriah Waterland 				if (is_partial_inst() != 0) {
12285c51f124SMoriah Waterland 					if (*srcp[0] == '~') {
12295c51f124SMoriah Waterland 						/* translate source pathname */
12305c51f124SMoriah Waterland 						*srcp = srcpath(instdir,
12315c51f124SMoriah Waterland 							extlist[i]->map_path,
12325c51f124SMoriah Waterland 							part, nparts);
12335c51f124SMoriah Waterland 					} else {
12345c51f124SMoriah Waterland 						*srcp = extlist[i]->map_path;
12355c51f124SMoriah Waterland 					}
12365c51f124SMoriah Waterland 				} else {
12375c51f124SMoriah Waterland 					if (*srcp[0] == '~') {
12385c51f124SMoriah Waterland 						/* translate source pathname */
12395c51f124SMoriah Waterland 						*srcp = srcpath(instdir,
12405c51f124SMoriah Waterland 						    &(ept->ainfo.local[1]),
12415c51f124SMoriah Waterland 						    part, nparts);
12425c51f124SMoriah Waterland 					}
12435c51f124SMoriah Waterland 				}
12445c51f124SMoriah Waterland 
12455c51f124SMoriah Waterland 				echoDebug(DBG_DOMERG_NO_SUCH_FILE,
12465c51f124SMoriah Waterland 					ept->ftype, cl_nam(ept->pkg_class_idx),
12475c51f124SMoriah Waterland 					ept->path);
12485c51f124SMoriah Waterland 			} else {
12495c51f124SMoriah Waterland 				/*
12505c51f124SMoriah Waterland 				 * At this point, we're returning a non-file
12515c51f124SMoriah Waterland 				 * that couldn't be created in the standard
12525c51f124SMoriah Waterland 				 * way. If it refers to a filesystem that is
12535c51f124SMoriah Waterland 				 * not writeable by us, don't waste the
12545c51f124SMoriah Waterland 				 * calling process's time.
12555c51f124SMoriah Waterland 				 */
12565c51f124SMoriah Waterland 				if (!is_fs_writeable(ept->path,
12575c51f124SMoriah Waterland 					&(extlist[i]->fsys_value))) {
12585c51f124SMoriah Waterland 					echoDebug(DBG_DOMERG_NOT_WRITABLE,
12595c51f124SMoriah Waterland 						ept->ftype,
12605c51f124SMoriah Waterland 						cl_nam(ept->pkg_class_idx),
12615c51f124SMoriah Waterland 						ept->path);
12625c51f124SMoriah Waterland 					continue;
12635c51f124SMoriah Waterland 				}
12645c51f124SMoriah Waterland 
12655c51f124SMoriah Waterland 				*srcp = NULL;
12665c51f124SMoriah Waterland 				echoDebug(DBG_DOMERG_NOT_THERE,
12675c51f124SMoriah Waterland 					ept->ftype, cl_nam(ept->pkg_class_idx),
12685c51f124SMoriah Waterland 					ept->path);
12695c51f124SMoriah Waterland 			}
12705c51f124SMoriah Waterland 
12715c51f124SMoriah Waterland 			svindx = i+1;
12725c51f124SMoriah Waterland 			backup(*dstp, 1);
12735c51f124SMoriah Waterland 			return (i);
12745c51f124SMoriah Waterland 		}
12755c51f124SMoriah Waterland 
12765c51f124SMoriah Waterland 		if (mstat->attrchg) {
12775c51f124SMoriah Waterland 			backup(ept->path, 0);
12785c51f124SMoriah Waterland 			if (!msg_ugid)
12795c51f124SMoriah Waterland 				echo(MSG_ATTRIB, ept->path);
12805c51f124SMoriah Waterland 
12815c51f124SMoriah Waterland 			/* fix the attributes now for robustness sake */
12825c51f124SMoriah Waterland 			if (averify(1, &ept->ftype,
12835c51f124SMoriah Waterland 				ept->path,
12845c51f124SMoriah Waterland 				&ept->ainfo) == 0) {
12855c51f124SMoriah Waterland 				mstat->attrchg = 0;
12865c51f124SMoriah Waterland 			}
12875c51f124SMoriah Waterland 		}
12885c51f124SMoriah Waterland 
12895c51f124SMoriah Waterland 		/*
12905c51f124SMoriah Waterland 		 * package object exists, or does not need updating: if the path
12915c51f124SMoriah Waterland 		 * is in an area inherited from the global zone, then treat
12925c51f124SMoriah Waterland 		 * the object as if it were "skipped" - if the path is not in an
12935c51f124SMoriah Waterland 		 * area inherited from the global zone, then treat the object as
12945c51f124SMoriah Waterland 		 * if it were "updated"
12955c51f124SMoriah Waterland 		 */
12965c51f124SMoriah Waterland 
12975c51f124SMoriah Waterland 		/* LINTED warning: statement has no consequent: if */
12985c51f124SMoriah Waterland 		if ((stateFlag == B_FALSE) || (ept == (struct cfent *)NULL)) {
12995c51f124SMoriah Waterland 			/*
13005c51f124SMoriah Waterland 			 * the object in question is a directory or special
13015c51f124SMoriah Waterland 			 * file - the fact that this type of object already
13025c51f124SMoriah Waterland 			 * exists or does not need updating must not trigger
13035c51f124SMoriah Waterland 			 * the object updated/object skipped indication -
13045c51f124SMoriah Waterland 			 * that would cause class action scripts to be run
13055c51f124SMoriah Waterland 			 * when installing a new non-global zone - that action
13065c51f124SMoriah Waterland 			 * must only be done when a file object that is in
13075c51f124SMoriah Waterland 			 * an area inherited from the global zone is present.
13085c51f124SMoriah Waterland 			 */
13095c51f124SMoriah Waterland 		} else if (z_path_is_inherited(ept->path, ept->ftype,
13105c51f124SMoriah Waterland 						get_inst_root()) == B_TRUE) {
13115c51f124SMoriah Waterland 			if (r_skipped != (char **)NULL) {
13125c51f124SMoriah Waterland 				if (*r_skipped == (char *)NULL) {
13135c51f124SMoriah Waterland 					echoDebug(DBG_INSTVOL_OBJ_SKIPPED,
13145c51f124SMoriah Waterland 								ept->path);
13155c51f124SMoriah Waterland 					*r_skipped = ept->path;
13165c51f124SMoriah Waterland 				}
13175c51f124SMoriah Waterland 			}
13185c51f124SMoriah Waterland 		} else {
13195c51f124SMoriah Waterland 			if (r_updated != (char **)NULL) {
13205c51f124SMoriah Waterland 				if (*r_updated == (char *)NULL) {
13215c51f124SMoriah Waterland 					echoDebug(DBG_INSTVOL_OBJ_UPDATED,
13225c51f124SMoriah Waterland 								ept->path);
13235c51f124SMoriah Waterland 				}
13245c51f124SMoriah Waterland 				*r_updated = ept->path;
13255c51f124SMoriah Waterland 			}
13265c51f124SMoriah Waterland 		}
13275c51f124SMoriah Waterland 	}
13285c51f124SMoriah Waterland 
13295c51f124SMoriah Waterland 	if (maxvol == part) {
13305c51f124SMoriah Waterland 		eocflag++;	/* endofclass */
13315c51f124SMoriah Waterland 	}
13325c51f124SMoriah Waterland 
13335c51f124SMoriah Waterland 	return (DMRG_DONE);	/* no remaining entries on this volume */
13345c51f124SMoriah Waterland }
13355c51f124SMoriah Waterland 
13365c51f124SMoriah Waterland /*
13375c51f124SMoriah Waterland  * Determine if the provided directory is populated. Return 0 if so and 1 if
13385c51f124SMoriah Waterland  * not. This also returns 0 if the dirpath is not a directory or if it does
13395c51f124SMoriah Waterland  * not exist.
13405c51f124SMoriah Waterland  */
13415c51f124SMoriah Waterland static int
13425c51f124SMoriah Waterland dir_is_populated(char *dirpath) {
13435c51f124SMoriah Waterland 	DIR	*dirfp;
13445c51f124SMoriah Waterland 	struct	dirent *drp;
13455c51f124SMoriah Waterland 	int	retcode = 0;
13465c51f124SMoriah Waterland 
13475c51f124SMoriah Waterland 	if ((dirfp = opendir(dirpath)) != NULL) {
13485c51f124SMoriah Waterland 		while ((drp = readdir(dirfp)) != NULL) {
13495c51f124SMoriah Waterland 			if (strcmp(drp->d_name, ".") == 0) {
13505c51f124SMoriah Waterland 				continue;
13515c51f124SMoriah Waterland 			}
13525c51f124SMoriah Waterland 			if (strcmp(drp->d_name, "..") == 0) {
13535c51f124SMoriah Waterland 				continue;
13545c51f124SMoriah Waterland 			}
13555c51f124SMoriah Waterland 			/*
13565c51f124SMoriah Waterland 			 * If we get here, there's a real file in the
13575c51f124SMoriah Waterland 			 * directory
13585c51f124SMoriah Waterland 			 */
13595c51f124SMoriah Waterland 			retcode = 1;
13605c51f124SMoriah Waterland 			break;
13615c51f124SMoriah Waterland 		}
13625c51f124SMoriah Waterland 		(void) closedir(dirfp);
13635c51f124SMoriah Waterland 	}
13645c51f124SMoriah Waterland 
13655c51f124SMoriah Waterland 	return (retcode);
13665c51f124SMoriah Waterland }
13675c51f124SMoriah Waterland 
13685c51f124SMoriah Waterland /*
13695c51f124SMoriah Waterland  * This is the function that cleans up the installation of this class.
13705c51f124SMoriah Waterland  * This is where hard links get put in since the stuff they're linking
13715c51f124SMoriah Waterland  * probably exists by now.
13725c51f124SMoriah Waterland  */
13735c51f124SMoriah Waterland static void
13745c51f124SMoriah Waterland endofclass(struct cfextra **extlist, int myclass, int ckflag,
1375*62224350SCasper H.S. Dik 	PKGserver pkgserver, VFP_T **a_cfTmpVfp)
13765c51f124SMoriah Waterland {
13775c51f124SMoriah Waterland 	char		*temppath;
13785c51f124SMoriah Waterland 	char 		*pspool_loc;
13795c51f124SMoriah Waterland 	char 		*relocpath = (char *)NULL;
13805c51f124SMoriah Waterland 	char 		scrpt_dst[PATH_MAX];
13815c51f124SMoriah Waterland 	int		flag;
13825c51f124SMoriah Waterland 	int		idx;
13835c51f124SMoriah Waterland 	int		n;
13845c51f124SMoriah Waterland 	struct cfent	*ept;	/* entry from the internal list */
13855c51f124SMoriah Waterland 	struct cfextra	entry;	/* entry from the package database */
13865c51f124SMoriah Waterland 	struct mergstat	*mstat;	/* merge status */
13875c51f124SMoriah Waterland 	struct pinfo	*pinfo;
13885c51f124SMoriah Waterland 
13895c51f124SMoriah Waterland 	/* open the package database (contents) file */
13905c51f124SMoriah Waterland 
1391*62224350SCasper H.S. Dik 	if (!ocfile(&pkgserver, a_cfTmpVfp, pkgmap_blks)) {
13925c51f124SMoriah Waterland 		quit(99);
13935c51f124SMoriah Waterland 	}
13945c51f124SMoriah Waterland 
13955c51f124SMoriah Waterland 	echo(MSG_VERIFYING_CLASS, cl_nam(myclass));
13965c51f124SMoriah Waterland 
13975c51f124SMoriah Waterland 	for (idx = 0; /* void */; idx++) {
13985c51f124SMoriah Waterland 		/* find next package object in this class */
13995c51f124SMoriah Waterland 		while (extlist[idx]) {
14005c51f124SMoriah Waterland 			if ((extlist[idx]->cf_ent.ftype != 'i') &&
14015c51f124SMoriah Waterland 				extlist[idx]->cf_ent.pkg_class_idx == myclass) {
14025c51f124SMoriah Waterland 				break;
14035c51f124SMoriah Waterland 			}
14045c51f124SMoriah Waterland 			idx++;
14055c51f124SMoriah Waterland 		}
14065c51f124SMoriah Waterland 
1407*62224350SCasper H.S. Dik 		if (extlist[idx] == NULL)
14085c51f124SMoriah Waterland 			break;
1409*62224350SCasper H.S. Dik 
14105c51f124SMoriah Waterland 
14115c51f124SMoriah Waterland 		ept = &(extlist[idx]->cf_ent);
14125c51f124SMoriah Waterland 		mstat = &(extlist[idx]->mstat);
14135c51f124SMoriah Waterland 
1414*62224350SCasper H.S. Dik 		temppath = extlist[idx]->client_path;
14155c51f124SMoriah Waterland 
14165c51f124SMoriah Waterland 		/*
14175c51f124SMoriah Waterland 		 * At this point  the only difference between the entry
14185c51f124SMoriah Waterland 		 * in the contents file and the entry in extlist[] is
14195c51f124SMoriah Waterland 		 * that the status indicator contains CONFIRM_CONT.
1420*62224350SCasper H.S. Dik 		 * This function should return one or something is wrong.
14215c51f124SMoriah Waterland 		 */
14225c51f124SMoriah Waterland 
1423*62224350SCasper H.S. Dik 		n = srchcfile(&(entry.cf_ent), temppath, pkgserver);
14245c51f124SMoriah Waterland 
1425*62224350SCasper H.S. Dik 		if (n < 0) {
14265c51f124SMoriah Waterland 			char	*errstr = getErrstr();
14275c51f124SMoriah Waterland 			progerr(ERR_CFBAD);
1428*62224350SCasper H.S. Dik 			logerr(gettext("pathname=%s"),
14295c51f124SMoriah Waterland 				entry.cf_ent.path && *entry.cf_ent.path ?
14305c51f124SMoriah Waterland 				entry.cf_ent.path : "Unknown");
1431*62224350SCasper H.S. Dik 			logerr(gettext("problem=%s"),
14325c51f124SMoriah Waterland 				(errstr && *errstr) ? errstr : "Unknown");
14335c51f124SMoriah Waterland 			quit(99);
14345c51f124SMoriah Waterland 		} else if (n != 1) {
14355c51f124SMoriah Waterland 			/*
14365c51f124SMoriah Waterland 			 * Check if path should be in the package
14375c51f124SMoriah Waterland 			 * database.
14385c51f124SMoriah Waterland 			 */
14395c51f124SMoriah Waterland 			if ((mstat->shared && nocnflct)) {
14405c51f124SMoriah Waterland 				continue;
14415c51f124SMoriah Waterland 			}
14425c51f124SMoriah Waterland 			progerr(ERR_CFMISSING, ept->path);
14435c51f124SMoriah Waterland 			quit(99);
14445c51f124SMoriah Waterland 		}
14455c51f124SMoriah Waterland 
14465c51f124SMoriah Waterland 		/*
14475c51f124SMoriah Waterland 		 * If merge was not appropriate for this object, now is the
14485c51f124SMoriah Waterland 		 * time to choose one or the other.
14495c51f124SMoriah Waterland 		 */
14505c51f124SMoriah Waterland 		if (mstat->denied) {
14515c51f124SMoriah Waterland 			/*
14525c51f124SMoriah Waterland 			 * If installation was denied AFTER the package
14535c51f124SMoriah Waterland 			 * database was updated, skip this. We've already
14545c51f124SMoriah Waterland 			 * announced the discrepancy and the verifications
14555c51f124SMoriah Waterland 			 * that follow will make faulty decisions based on
14565c51f124SMoriah Waterland 			 * the ftype, which may not be correct.
14575c51f124SMoriah Waterland 			 */
14585c51f124SMoriah Waterland 			progerr(ERR_COULD_NOT_INSTALL, ept->path);
14595c51f124SMoriah Waterland 			warnflag++;
14605c51f124SMoriah Waterland 		} else {
14615c51f124SMoriah Waterland 			if (mstat->replace)
14625c51f124SMoriah Waterland 				/*
14635c51f124SMoriah Waterland 				 * This replaces the old entry with the new
14645c51f124SMoriah Waterland 				 * one. This should never happen in the new
14655c51f124SMoriah Waterland 				 * DB since the entries are already identical.
14665c51f124SMoriah Waterland 				 */
14675c51f124SMoriah Waterland 				repl_cfent(ept, &(entry.cf_ent));
14685c51f124SMoriah Waterland 
14695c51f124SMoriah Waterland 			/*
14705c51f124SMoriah Waterland 			 * Validate this entry and change the status flag in
14715c51f124SMoriah Waterland 			 * the package database.
14725c51f124SMoriah Waterland 			 */
14735c51f124SMoriah Waterland 			if (ept->ftype == RM_RDY) {
14745c51f124SMoriah Waterland 				(void) eptstat(&(entry.cf_ent), pkginst,
14755c51f124SMoriah Waterland 					STAT_NEXT);
14765c51f124SMoriah Waterland 			} else {
14775c51f124SMoriah Waterland 				/* check the hard link now. */
14785c51f124SMoriah Waterland 				if (ept->ftype == 'l') {
14795c51f124SMoriah Waterland 					if (averify(0, &ept->ftype,
14805c51f124SMoriah Waterland 						ept->path, &ept->ainfo)) {
14815c51f124SMoriah Waterland 						echo(MSG_HRDLINK,
14825c51f124SMoriah Waterland 							ept->path);
14835c51f124SMoriah Waterland 						mstat->attrchg++;
14845c51f124SMoriah Waterland 					}
14855c51f124SMoriah Waterland 				}
14865c51f124SMoriah Waterland 
14875c51f124SMoriah Waterland 				/*
14885c51f124SMoriah Waterland 				 * Don't install or verify objects for
14895c51f124SMoriah Waterland 				 * remote, read-only filesystems.  We need
14905c51f124SMoriah Waterland 				 * only flag them as shared from some server.
14915c51f124SMoriah Waterland 				 * Otherwise, ok to do final check.
14925c51f124SMoriah Waterland 				 */
14935c51f124SMoriah Waterland 				if (is_remote_fs(ept->path,
14945c51f124SMoriah Waterland 					&(extlist[idx]->fsys_value)) &&
14955c51f124SMoriah Waterland 					!is_fs_writeable(ept->path,
14965c51f124SMoriah Waterland 					&(extlist[idx]->fsys_value))) {
14975c51f124SMoriah Waterland 					flag = -1;
14985c51f124SMoriah Waterland 				} else {
14995c51f124SMoriah Waterland 					boolean_t inheritedFlag;
15005c51f124SMoriah Waterland 					inheritedFlag =
15015c51f124SMoriah Waterland 					    z_path_is_inherited(ept->path,
15025c51f124SMoriah Waterland 						ept->ftype, get_inst_root());
15035c51f124SMoriah Waterland 					flag = finalck(ept, mstat->attrchg,
15045c51f124SMoriah Waterland 						(ckflag ? mstat->contchg :
15055c51f124SMoriah Waterland 						(-1)), inheritedFlag);
15065c51f124SMoriah Waterland 				}
15075c51f124SMoriah Waterland 
15085c51f124SMoriah Waterland 				pinfo = entry.cf_ent.pinfo;
15095c51f124SMoriah Waterland 
15105c51f124SMoriah Waterland 				/* Find this package in the list. */
15115c51f124SMoriah Waterland 				while (pinfo) {
15125c51f124SMoriah Waterland 					if (strcmp(pkginst, pinfo->pkg) == 0) {
15135c51f124SMoriah Waterland 						break;
15145c51f124SMoriah Waterland 					}
15155c51f124SMoriah Waterland 					pinfo = pinfo->next;
15165c51f124SMoriah Waterland 				}
15175c51f124SMoriah Waterland 
15185c51f124SMoriah Waterland 				/*
15195c51f124SMoriah Waterland 				 * If this package owns this file, then store
15205c51f124SMoriah Waterland 				 * it in the database with the appropriate
15215c51f124SMoriah Waterland 				 * status. Need to check pinfo in case it
15225c51f124SMoriah Waterland 				 * points to NULL which could happen if
15235c51f124SMoriah Waterland 				 * pinfo->next = NULL above.
15245c51f124SMoriah Waterland 				 */
15255c51f124SMoriah Waterland 				if (pinfo) {
15265c51f124SMoriah Waterland 					if (flag < 0 || is_served(ept->path,
15275c51f124SMoriah Waterland 						&(extlist[idx]->fsys_value))) {
15285c51f124SMoriah Waterland 						/*
15295c51f124SMoriah Waterland 						 * This is provided to
15305c51f124SMoriah Waterland 						 * clients by a server.
15315c51f124SMoriah Waterland 						 */
15325c51f124SMoriah Waterland 						pinfo->status = SERVED_FILE;
15335c51f124SMoriah Waterland 					} else {
15345c51f124SMoriah Waterland 						/*
15355c51f124SMoriah Waterland 						 * It's either there or it's
15365c51f124SMoriah Waterland 						 * not.
15375c51f124SMoriah Waterland 						 */
15385c51f124SMoriah Waterland 						pinfo->status = (flag ?
15395c51f124SMoriah Waterland 							NOT_FND : ENTRY_OK);
15405c51f124SMoriah Waterland 					}
15415c51f124SMoriah Waterland 				}
15425c51f124SMoriah Waterland 			}
15435c51f124SMoriah Waterland 		}
15445c51f124SMoriah Waterland 
15455c51f124SMoriah Waterland 		/*
15465c51f124SMoriah Waterland 		 * If not installing from a partially spooled package, the
15475c51f124SMoriah Waterland 		 * "save/pspool" area, and the file contents can be
15485c51f124SMoriah Waterland 		 * changed (type is 'e' or 'v'), and the class IS "none":
15495c51f124SMoriah Waterland 		 * copy the installed volatile file into the appropriate
15505c51f124SMoriah Waterland 		 * location in the packages destination "save/pspool" area.
15515c51f124SMoriah Waterland 		 */
15525c51f124SMoriah Waterland 
15535c51f124SMoriah Waterland 		if ((!is_partial_inst()) &&
15545c51f124SMoriah Waterland 			((ept->ftype == 'e') || (ept->ftype == 'v')) &&
15555c51f124SMoriah Waterland 			(strcmp(ept->pkg_class, "none") == 0)) {
15565c51f124SMoriah Waterland 
15575c51f124SMoriah Waterland 			if (absolutepath(extlist[idx]->map_path) == B_TRUE &&
15585c51f124SMoriah Waterland 				parametricpath(extlist[idx]->cf_ent.ainfo.local,
15595c51f124SMoriah Waterland 					&relocpath) == B_FALSE) {
15605c51f124SMoriah Waterland 				pspool_loc = ROOT;
15615c51f124SMoriah Waterland 			} else {
15625c51f124SMoriah Waterland 				pspool_loc = RELOC;
15635c51f124SMoriah Waterland 			}
15645c51f124SMoriah Waterland 
15655c51f124SMoriah Waterland 			n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s",
15665c51f124SMoriah Waterland 				saveSpoolInstallDir, pspool_loc,
15675c51f124SMoriah Waterland 				relocpath ? relocpath : extlist[idx]->map_path);
15685c51f124SMoriah Waterland 
15695c51f124SMoriah Waterland 			if (n >= PATH_MAX) {
15705c51f124SMoriah Waterland 				progerr(ERR_CREATE_PATH_2,
15715c51f124SMoriah Waterland 					saveSpoolInstallDir,
15725c51f124SMoriah Waterland 					extlist[idx]->map_path);
15735c51f124SMoriah Waterland 				quit(99);
15745c51f124SMoriah Waterland 			}
15755c51f124SMoriah Waterland 
15765c51f124SMoriah Waterland 			/* copy, preserve source file mode */
15775c51f124SMoriah Waterland 
15785c51f124SMoriah Waterland 			if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) {
15795c51f124SMoriah Waterland 				warnflag++;
15805c51f124SMoriah Waterland 			}
15815c51f124SMoriah Waterland 		}
15825c51f124SMoriah Waterland 
15835c51f124SMoriah Waterland 		/*
15845c51f124SMoriah Waterland 		 * Now insert this potentially changed package database
15855c51f124SMoriah Waterland 		 * entry.
15865c51f124SMoriah Waterland 		 */
15875c51f124SMoriah Waterland 		if (entry.cf_ent.npkgs) {
15885c51f124SMoriah Waterland 			if (putcvfpfile(&(entry.cf_ent), *a_cfTmpVfp)) {
15895c51f124SMoriah Waterland 				quit(99);
15905c51f124SMoriah Waterland 			}
15915c51f124SMoriah Waterland 		}
15925c51f124SMoriah Waterland 	}
15935c51f124SMoriah Waterland 
1594*62224350SCasper H.S. Dik 	n = swapcfile(pkgserver, a_cfTmpVfp, pkginst, dbchg);
15955c51f124SMoriah Waterland 	if (n == RESULT_WRN) {
15965c51f124SMoriah Waterland 		warnflag++;
15975c51f124SMoriah Waterland 	} else if (n == RESULT_ERR) {
15985c51f124SMoriah Waterland 		quit(99);
15995c51f124SMoriah Waterland 	}
16005c51f124SMoriah Waterland }
16015c51f124SMoriah Waterland 
16025c51f124SMoriah Waterland /*
16035c51f124SMoriah Waterland  * This function goes through and fixes all the attributes. This is called
16045c51f124SMoriah Waterland  * out by using DST_QKVERIFY=this_class in the pkginfo file. The primary
16055c51f124SMoriah Waterland  * use for this is to fix up files installed by a class action script
16065c51f124SMoriah Waterland  * which is time-critical and reliable enough to assume likely success.
16075c51f124SMoriah Waterland  * The first such format was for WOS compressed-cpio'd file sets.
16085c51f124SMoriah Waterland  * The second format is the Class Archive Format.
16095c51f124SMoriah Waterland  */
16105c51f124SMoriah Waterland static int
16115c51f124SMoriah Waterland fix_attributes(struct cfextra **extlist, int idx)
16125c51f124SMoriah Waterland {
16135c51f124SMoriah Waterland 	struct	cfextra *ext;
16145c51f124SMoriah Waterland 	int	i, retval = 1;
16155c51f124SMoriah Waterland 	int 	nc = cl_getn();
16165c51f124SMoriah Waterland 	int	n;
16175c51f124SMoriah Waterland 	struct cfent *ept;
16185c51f124SMoriah Waterland 	struct mergstat *mstat;
16195c51f124SMoriah Waterland 	char scrpt_dst[PATH_MAX];
16205c51f124SMoriah Waterland 	char *pspool_loc;
16215c51f124SMoriah Waterland 	char *relocpath = (char *)NULL;
16225c51f124SMoriah Waterland 
16235c51f124SMoriah Waterland 	for (i = 0; extlist[i]; i++) {
16245c51f124SMoriah Waterland 		ext = extlist[i];
16255c51f124SMoriah Waterland 		ept = &(extlist[i]->cf_ent);
16265c51f124SMoriah Waterland 		mstat = &(extlist[i]->mstat);
16275c51f124SMoriah Waterland 
16285c51f124SMoriah Waterland 		/*
16295c51f124SMoriah Waterland 		 * We don't care about 'i'nfo files because, they
16305c51f124SMoriah Waterland 		 * aren't laid down, 'e'ditable files can change
16315c51f124SMoriah Waterland 		 * anyway, so who cares and 's'ymlinks were already
16325c51f124SMoriah Waterland 		 * fixed in domerg(); however, certain old WOS
16335c51f124SMoriah Waterland 		 * package symlinks depend on a bug in the old
16345c51f124SMoriah Waterland 		 * pkgadd which has recently been expunged. For
16355c51f124SMoriah Waterland 		 * those packages in 2.2, we repeat the verification
16365c51f124SMoriah Waterland 		 * of symlinks.
16375c51f124SMoriah Waterland 		 *
16385c51f124SMoriah Waterland 		 * By 2.6 or so, ftype == 's' should be added to this.
16395c51f124SMoriah Waterland 		 */
16405c51f124SMoriah Waterland 		if (ept->ftype == 'i' || ept->ftype == 'e' ||
16415c51f124SMoriah Waterland 			(mstat->shared && nocnflct))
16425c51f124SMoriah Waterland 			continue;
16435c51f124SMoriah Waterland 
16445c51f124SMoriah Waterland 		if (mstat->denied) {
16455c51f124SMoriah Waterland 			progerr(ERR_COULD_NOT_INSTALL, ept->path);
16465c51f124SMoriah Waterland 			warnflag++;
16475c51f124SMoriah Waterland 			continue;
16485c51f124SMoriah Waterland 		}
16495c51f124SMoriah Waterland 
16505c51f124SMoriah Waterland 		if (ept->pkg_class_idx < 0 || ept->pkg_class_idx > nc) {
16515c51f124SMoriah Waterland 			progerr(ERR_CLIDX, ept->pkg_class_idx,
16525c51f124SMoriah Waterland 			    (ept->path && *ept->path) ? ept->path : "unknown");
16535c51f124SMoriah Waterland 			continue;
16545c51f124SMoriah Waterland 		}
16555c51f124SMoriah Waterland 
16565c51f124SMoriah Waterland 		/* If this is the right class, do the fast verify. */
16575c51f124SMoriah Waterland 		if (ept->pkg_class_idx == idx) {
16585c51f124SMoriah Waterland 			if (fverify(1, &ept->ftype, ept->path,
16595c51f124SMoriah Waterland 				&ept->ainfo, &ept->cinfo) == 0) {
16605c51f124SMoriah Waterland 				mstat->attrchg = 0;
16615c51f124SMoriah Waterland 				mstat->contchg =  0;
16625c51f124SMoriah Waterland 			} else	/* We'll try full verify later */
16635c51f124SMoriah Waterland 				retval = 0;
16645c51f124SMoriah Waterland 		}
16655c51f124SMoriah Waterland 		/*
16665c51f124SMoriah Waterland 		 * Need to copy the installed volitale file back to the
16675c51f124SMoriah Waterland 		 * partial spooled area if we are installing to a local zone
16685c51f124SMoriah Waterland 		 * or similar installation method.
16695c51f124SMoriah Waterland 		 */
16705c51f124SMoriah Waterland 
16715c51f124SMoriah Waterland 		if ((!is_partial_inst()) &&
16725c51f124SMoriah Waterland 			((ept->ftype == 'e') || (ept->ftype == 'v')) &&
16735c51f124SMoriah Waterland 			(strcmp(ept->pkg_class, "none") == 0)) {
16745c51f124SMoriah Waterland 
16755c51f124SMoriah Waterland 			if (absolutepath(ext->map_path) == B_TRUE &&
16765c51f124SMoriah Waterland 				parametricpath(ext->cf_ent.ainfo.local,
16775c51f124SMoriah Waterland 					&relocpath) == B_FALSE) {
16785c51f124SMoriah Waterland 				pspool_loc = ROOT;
16795c51f124SMoriah Waterland 			} else {
16805c51f124SMoriah Waterland 				pspool_loc = RELOC;
16815c51f124SMoriah Waterland 			}
16825c51f124SMoriah Waterland 
16835c51f124SMoriah Waterland 			n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s",
16845c51f124SMoriah Waterland 				saveSpoolInstallDir, pspool_loc,
16855c51f124SMoriah Waterland 				relocpath ? relocpath : ext->map_path);
16865c51f124SMoriah Waterland 
16875c51f124SMoriah Waterland 			if (n >= PATH_MAX) {
16885c51f124SMoriah Waterland 				progerr(ERR_CREATE_PATH_2,
16895c51f124SMoriah Waterland 					saveSpoolInstallDir,
16905c51f124SMoriah Waterland 					ext->map_path);
16915c51f124SMoriah Waterland 				quit(99);
16925c51f124SMoriah Waterland 			}
16935c51f124SMoriah Waterland 
16945c51f124SMoriah Waterland 			/* copy, preserve source file mode */
16955c51f124SMoriah Waterland 
16965c51f124SMoriah Waterland 			if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) {
16975c51f124SMoriah Waterland 				warnflag++;
16985c51f124SMoriah Waterland 			}
16995c51f124SMoriah Waterland 		}
17005c51f124SMoriah Waterland 	}
17015c51f124SMoriah Waterland 
17025c51f124SMoriah Waterland 	return (retval);
17035c51f124SMoriah Waterland }
17045c51f124SMoriah Waterland 
17055c51f124SMoriah Waterland /*
17065c51f124SMoriah Waterland  * Check to see if first charcter in path is a '/'.
17075c51f124SMoriah Waterland  *
17085c51f124SMoriah Waterland  * Return:
17095c51f124SMoriah Waterland  * 			B_TRUE - if path is prepended with '/'
17105c51f124SMoriah Waterland  * 			B_FALSE - if not
17115c51f124SMoriah Waterland  */
17125c51f124SMoriah Waterland static boolean_t
17135c51f124SMoriah Waterland absolutepath(char *path)
17145c51f124SMoriah Waterland {
17155c51f124SMoriah Waterland 	assert(path != NULL);
17165c51f124SMoriah Waterland 	assert(path[0] != '\0');
17175c51f124SMoriah Waterland 
17185c51f124SMoriah Waterland 	return (path[0] == '/' ? B_TRUE : B_FALSE);
17195c51f124SMoriah Waterland }
17205c51f124SMoriah Waterland 
17215c51f124SMoriah Waterland /*
17225c51f124SMoriah Waterland  * Check to see if path contains a '$' which makes it
17235c51f124SMoriah Waterland  * a parametric path and therefore relocatable.
17245c51f124SMoriah Waterland  *
17255c51f124SMoriah Waterland  * Parameters:
17265c51f124SMoriah Waterland  *             path - The path to determine if it is absolute
17275c51f124SMoriah Waterland  *             relocpath - The value of the unconditioned path
17285c51f124SMoriah Waterland  *                         i.e. $OPTDIR/usr/ls
17295c51f124SMoriah Waterland  * Return:
17305c51f124SMoriah Waterland  * 			B_TRUE - if path is a parametric path
17315c51f124SMoriah Waterland  * 			B_FALSE - if not
17325c51f124SMoriah Waterland  */
17335c51f124SMoriah Waterland static boolean_t
17345c51f124SMoriah Waterland parametricpath(char *path, char **relocpath)
17355c51f124SMoriah Waterland {
17365c51f124SMoriah Waterland 	assert(path != NULL);
17375c51f124SMoriah Waterland 	assert(path[0] != '\0');
17385c51f124SMoriah Waterland 
17395c51f124SMoriah Waterland 	/*
17405c51f124SMoriah Waterland 	 * If this is a valid parametric path then a '$' MUST occur at the
17415c51f124SMoriah Waterland 	 * first or second character.
17425c51f124SMoriah Waterland 	 */
17435c51f124SMoriah Waterland 
17445c51f124SMoriah Waterland 	if (path[0] == '$' || path[1] == '$') {
17455c51f124SMoriah Waterland 		/*
17465c51f124SMoriah Waterland 		 * If a parametric path exists then when copying the
17475c51f124SMoriah Waterland 		 * path to the pspool directoy from the installing
17485c51f124SMoriah Waterland 		 * pkgs reloc directory we want to use the uncononditional
17495c51f124SMoriah Waterland 		 * varaiable path.
17505c51f124SMoriah Waterland 		 */
17515c51f124SMoriah Waterland 		*relocpath = (path + 1);
17525c51f124SMoriah Waterland 		return (B_TRUE);
17535c51f124SMoriah Waterland 	}
17545c51f124SMoriah Waterland 	return (B_FALSE);
17555c51f124SMoriah Waterland }
17565c51f124SMoriah Waterland 
17575c51f124SMoriah Waterland void
17585c51f124SMoriah Waterland regfiles_free()
17595c51f124SMoriah Waterland {
17605c51f124SMoriah Waterland 	if (regfiles_head != NULL) {
17615c51f124SMoriah Waterland 		struct reg_files *rfp = regfiles_head->next;
17625c51f124SMoriah Waterland 
17635c51f124SMoriah Waterland 		while (rfp != NULL) {
17645c51f124SMoriah Waterland 			free(regfiles_head);
17655c51f124SMoriah Waterland 			regfiles_head = rfp;
17665c51f124SMoriah Waterland 			rfp = regfiles_head->next;
17675c51f124SMoriah Waterland 		}
17685c51f124SMoriah Waterland 		free(regfiles_head);
17695c51f124SMoriah Waterland 		regfiles_head = NULL;
17705c51f124SMoriah Waterland 	}
17715c51f124SMoriah Waterland }
1772