xref: /titanic_50/usr/src/cmd/svr4pkg/libinst/pkgdbmerg.c (revision b46ec01af51b4e66dbdba8ceb0a8e5ed36241df9)
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 <signal.h>
335c51f124SMoriah Waterland #include <string.h>
345c51f124SMoriah Waterland #include <errno.h>
355c51f124SMoriah Waterland #include <unistd.h>
365c51f124SMoriah Waterland #include <stdlib.h>
375c51f124SMoriah Waterland #include <assert.h>
385c51f124SMoriah Waterland #include <pkgstrct.h>
395c51f124SMoriah Waterland #include <sys/stat.h>
405c51f124SMoriah Waterland #include <locale.h>
415c51f124SMoriah Waterland #include <libintl.h>
425c51f124SMoriah Waterland #include <pkginfo.h>
435c51f124SMoriah Waterland #include <instzones_api.h>
445c51f124SMoriah Waterland #include <pkglib.h>
455c51f124SMoriah Waterland #include <libinst.h>
465c51f124SMoriah Waterland #include <messages.h>
475c51f124SMoriah Waterland 
485c51f124SMoriah Waterland /* merg() return codes */
495c51f124SMoriah Waterland #define	MRG_SAME	0
505c51f124SMoriah Waterland #define	MRG_DIFFERENT	1
515c51f124SMoriah Waterland #define	MRG_REPLACE	2
525c51f124SMoriah Waterland 
535c51f124SMoriah Waterland /* typechg() return codes */
545c51f124SMoriah Waterland #define	TYPE_OK		0
555c51f124SMoriah Waterland #define	TYPE_WARNING	1
565c51f124SMoriah Waterland #define	TYPE_IGNORED	2
575c51f124SMoriah Waterland #define	TYPE_REPLACE	3
585c51f124SMoriah Waterland #define	TYPE_FATAL	4
595c51f124SMoriah Waterland 
605c51f124SMoriah Waterland /* message pool */
615c51f124SMoriah Waterland #define	ERR_OUTPUT	"unable to update package database"
625c51f124SMoriah Waterland #define	ERR_PINFO	"missing pinfo structure for <%s>"
635c51f124SMoriah Waterland #define	INFO_PROCESS	"   %2ld%% of information processed; continuing ..."
645c51f124SMoriah Waterland 
655c51f124SMoriah Waterland #define	WRN_NOTFILE	"WARNING: %s <no longer a regular file>"
665c51f124SMoriah Waterland #define	WRN_NOTSYMLN	"WARNING: %s <no longer a symbolic link>"
675c51f124SMoriah Waterland #define	WRN_NOTLINK	"WARNING: %s <no longer a linked file>"
685c51f124SMoriah Waterland #define	WRN_NOTDIR	"WARNING: %s <no longer a directory>"
695c51f124SMoriah Waterland #define	WRN_NOTCHAR	"WARNING: %s <no longer a character special device>"
705c51f124SMoriah Waterland #define	WRN_NOTBLOCK	"WARNING: %s <no longer a block special device>"
715c51f124SMoriah Waterland #define	WRN_NOTPIPE	"WARNING: %s <no longer a named pipe>"
725c51f124SMoriah Waterland #define	WRN_TOEXCL	"WARNING: cannot convert %s to an exclusive directory."
735c51f124SMoriah Waterland #define	WRN_ODDVERIFY	"WARNING: quick verify disabled for class %s."
745c51f124SMoriah Waterland 
755c51f124SMoriah Waterland #define	MSG_TYPIGN	"Object type change ignored."
765c51f124SMoriah Waterland #define	MSG_TYPE_ERR	"Package attempts fatal object type change."
775c51f124SMoriah Waterland 
785c51f124SMoriah Waterland extern char	*pkginst;
795c51f124SMoriah Waterland extern int	nosetuid, nocnflct, otherstoo;
805c51f124SMoriah Waterland 
815c51f124SMoriah Waterland /* pkgobjmap.c */
825c51f124SMoriah Waterland extern int	cp_cfent(struct cfent *cf_ent, struct cfextra *el_ent);
835c51f124SMoriah Waterland 
845c51f124SMoriah Waterland /* setlist.c */
855c51f124SMoriah Waterland extern void	cl_def_dverify(int idx);
865c51f124SMoriah Waterland 
875c51f124SMoriah Waterland char dbst = '\0';	/* usually set by installf() or removef() */
885c51f124SMoriah Waterland 
895c51f124SMoriah Waterland int files_installed(void);	/* return number of files installed. */
905c51f124SMoriah Waterland 
915c51f124SMoriah Waterland static int	errflg = 0;
925c51f124SMoriah Waterland static int	eptnum;
935c51f124SMoriah Waterland static int	installed;	/* # of files, already properly installed. */
945c51f124SMoriah Waterland static struct	pinfo	*pkgpinfo = (struct pinfo *)0;
955c51f124SMoriah Waterland 
965c51f124SMoriah Waterland static int	is_setuid(struct cfent *ent);
975c51f124SMoriah Waterland static int	is_setgid(struct cfent *ent);
985c51f124SMoriah Waterland static int	merg(struct cfextra *el_ent, struct cfent *cf_ent);
995c51f124SMoriah Waterland static int	do_like_ent(VFP_T *vfpo, struct cfextra *el_ent,
1005c51f124SMoriah Waterland 		    struct cfent *cf_ent, int ctrl);
1015c51f124SMoriah Waterland static int	do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl);
102*b46ec01aSok199659 static int	typechg(struct cfent *el_ent, struct cfent *cf_ent,
1035c51f124SMoriah Waterland 		    struct mergstat *mstat);
1045c51f124SMoriah Waterland 
1055c51f124SMoriah Waterland static void	set_change(struct cfextra *el_ent);
1065c51f124SMoriah Waterland static void	chgclass(struct cfent *cf_ent, struct pinfo *pinfo);
1075c51f124SMoriah Waterland static void	output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo);
1085c51f124SMoriah Waterland 
1095c51f124SMoriah Waterland /*
11062224350SCasper H.S. Dik  * This scans the extlist (pkgmap) and matches them to the database, copying
11162224350SCasper H.S. Dik  * out the modified contents to the file at tmpfp. It updates the mergstat
1125c51f124SMoriah Waterland  * structures and deals with administrative defaults regarding setuid and
1135c51f124SMoriah Waterland  * conflict.
1145c51f124SMoriah Waterland  */
1155c51f124SMoriah Waterland 
1165c51f124SMoriah Waterland int
11762224350SCasper H.S. Dik pkgdbmerg(PKGserver server, VFP_T *tmpvfp, struct cfextra **extlist)
1185c51f124SMoriah Waterland {
1195c51f124SMoriah Waterland 	static	struct	cfent	cf_ent;	/* scratch area */
1205c51f124SMoriah Waterland 	struct	cfextra	*el_ent;	/* extlist entry under review */
1215c51f124SMoriah Waterland 	int	n;
1225c51f124SMoriah Waterland 	int	changed;
1235c51f124SMoriah Waterland 	int	assume_ok = 0;
1245c51f124SMoriah Waterland 
1255c51f124SMoriah Waterland 	cf_ent.pinfo = (NULL);
1265c51f124SMoriah Waterland 	errflg = 0;
1275c51f124SMoriah Waterland 	installed = changed = 0;
1285c51f124SMoriah Waterland 
1295c51f124SMoriah Waterland 	vfpRewind(tmpvfp);
1305c51f124SMoriah Waterland 
13162224350SCasper H.S. Dik 	for (eptnum = 0; (el_ent = extlist[eptnum]) != NULL; eptnum++) {
1325c51f124SMoriah Waterland 		/*
1335c51f124SMoriah Waterland 		 * If there's an entry in the extlist at this position,
1345c51f124SMoriah Waterland 		 * process that entry.
1355c51f124SMoriah Waterland 		 */
1365c51f124SMoriah Waterland 		/* Metafiles don't get merged. */
1375c51f124SMoriah Waterland 		if ((el_ent->cf_ent.ftype == 'i') ||
1385c51f124SMoriah Waterland 			(el_ent->cf_ent.ftype == 'n')) {
1395c51f124SMoriah Waterland 			continue;
1405c51f124SMoriah Waterland 		}
1415c51f124SMoriah Waterland 
1425c51f124SMoriah Waterland 		/*
1435c51f124SMoriah Waterland 		 * Copy cfextra structure for duplicated paths.
1445c51f124SMoriah Waterland 		 * This is not just an optimization, it is
1455c51f124SMoriah Waterland 		 * necessary for correct operation of algorithm.
1465c51f124SMoriah Waterland 		 */
1475c51f124SMoriah Waterland 		if ((eptnum > 0) && (strncmp(el_ent->cf_ent.path,
1485c51f124SMoriah Waterland 		    extlist[eptnum-1]->cf_ent.path, PATH_MAX) == 0)) {
1495c51f124SMoriah Waterland 			memcpy(extlist[eptnum], extlist[eptnum-1],
1505c51f124SMoriah Waterland 			    sizeof (struct cfextra));
1515c51f124SMoriah Waterland 			continue;
1525c51f124SMoriah Waterland 		}
1535c51f124SMoriah Waterland 
1545c51f124SMoriah Waterland 		/*
1555c51f124SMoriah Waterland 		 * Normally dbst comes to us from installf() or
1565c51f124SMoriah Waterland 		 * removef() in order to specify their special
1575c51f124SMoriah Waterland 		 * database status codes. They cannot implement a
1585c51f124SMoriah Waterland 		 * quick verify (it just doesn't make sense). For
1595c51f124SMoriah Waterland 		 * that reason, we can test to see if we already have
1605c51f124SMoriah Waterland 		 * a special database status. If we don't (it's from
1615c51f124SMoriah Waterland 		 * pkgadd) then we can test to see if this is calling
1625c51f124SMoriah Waterland 		 * for a quick verify wherein we assume the install
1635c51f124SMoriah Waterland 		 * will work and fix it if it doesn't. In that case
1645c51f124SMoriah Waterland 		 * we set our own dbst to be ENTRY_OK.
1655c51f124SMoriah Waterland 		 */
1665c51f124SMoriah Waterland 		if (dbst == '\0') {
1675c51f124SMoriah Waterland 			if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) ==
1685c51f124SMoriah Waterland 			    QKVERIFY) {
1695c51f124SMoriah Waterland 				assume_ok = 1;
1705c51f124SMoriah Waterland 			}
1715c51f124SMoriah Waterland 		} else {
1725c51f124SMoriah Waterland 			/*
1735c51f124SMoriah Waterland 			 * If we DO end up with an installf/quick
1745c51f124SMoriah Waterland 			 * verify combination, we fix that by simply
1755c51f124SMoriah Waterland 			 * denying the quick verify for this class.
1765c51f124SMoriah Waterland 			 * This forces everything to come out alright
1775c51f124SMoriah Waterland 			 * by forcing the standard assumptions as
1785c51f124SMoriah Waterland 			 * regards package database for the rest of
1795c51f124SMoriah Waterland 			 * the load.
1805c51f124SMoriah Waterland 			 */
1815c51f124SMoriah Waterland 			if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) ==
1825c51f124SMoriah Waterland 			    QKVERIFY) {
1835c51f124SMoriah Waterland 				logerr(gettext(WRN_ODDVERIFY),
18462224350SCasper H.S. Dik 				    cl_nam(el_ent->cf_ent.pkg_class_idx));
1855c51f124SMoriah Waterland 				/*
1865c51f124SMoriah Waterland 				 * Set destination verification to
1875c51f124SMoriah Waterland 				 * default.
1885c51f124SMoriah Waterland 				 */
18962224350SCasper H.S. Dik 				cl_def_dverify(el_ent->cf_ent.pkg_class_idx);
1905c51f124SMoriah Waterland 			}
1915c51f124SMoriah Waterland 		}
1925c51f124SMoriah Waterland 
1935c51f124SMoriah Waterland 		/*
1945c51f124SMoriah Waterland 		 * Comply with administrative requirements regarding
1955c51f124SMoriah Waterland 		 * setuid/setgid processes.
1965c51f124SMoriah Waterland 		 */
1975c51f124SMoriah Waterland 		if (is_setuid(&(el_ent->cf_ent))) {
1985c51f124SMoriah Waterland 			el_ent->mstat.setuid = 1;
1995c51f124SMoriah Waterland 		}
2005c51f124SMoriah Waterland 		if (is_setgid(&(el_ent->cf_ent))) {
2015c51f124SMoriah Waterland 			el_ent->mstat.setgid = 1;
2025c51f124SMoriah Waterland 		}
2035c51f124SMoriah Waterland 
2045c51f124SMoriah Waterland 		/*
2055c51f124SMoriah Waterland 		 * If setuid/setgid processes are not allowed, reset
2065c51f124SMoriah Waterland 		 * those bits.
2075c51f124SMoriah Waterland 		 */
2085c51f124SMoriah Waterland 		if (nosetuid && (el_ent->mstat.setgid ||
2095c51f124SMoriah Waterland 		    el_ent->mstat.setuid)) {
21062224350SCasper H.S. Dik 			el_ent->cf_ent.ainfo.mode &= ~(S_ISUID | S_ISGID);
2115c51f124SMoriah Waterland 		}
2125c51f124SMoriah Waterland 
2135c51f124SMoriah Waterland 		/* Search package database for this entry. */
21462224350SCasper H.S. Dik 		n = srchcfile(&cf_ent, el_ent->cf_ent.path, server);
2155c51f124SMoriah Waterland 
2165c51f124SMoriah Waterland 		/*
2175c51f124SMoriah Waterland 		 * If there was an error, note it and return an error
2185c51f124SMoriah Waterland 		 * flag.
2195c51f124SMoriah Waterland 		 */
2205c51f124SMoriah Waterland 		if (n < 0) {
2215c51f124SMoriah Waterland 			char	*errstr = getErrstr();
22262224350SCasper H.S. Dik 			progerr(ERR_CFBAD);
22362224350SCasper H.S. Dik 			logerr(gettext("pathname: %s"),
2245c51f124SMoriah Waterland 			    (cf_ent.path && *cf_ent.path) ?
2255c51f124SMoriah Waterland 			    cf_ent.path : "Unknown");
22662224350SCasper H.S. Dik 			logerr(gettext("problem: %s"),
2275c51f124SMoriah Waterland 			    (errstr && *errstr) ? errstr : "Unknown");
2285c51f124SMoriah Waterland 			return (-1);
2295c51f124SMoriah Waterland 		/*
2305c51f124SMoriah Waterland 		 * If there was a match, then merge them into a
2315c51f124SMoriah Waterland 		 * single entry.
2325c51f124SMoriah Waterland 		 */
2335c51f124SMoriah Waterland 		} else if (n == 1) {
2345c51f124SMoriah Waterland 			/*
2355c51f124SMoriah Waterland 			 * If this package is overwriting a setuid or
2365c51f124SMoriah Waterland 			 * setgid process, set the status bits so we
2375c51f124SMoriah Waterland 			 * can inform the administrator.
2385c51f124SMoriah Waterland 			 */
2395c51f124SMoriah Waterland 			if (is_setuid(&cf_ent)) {
2405c51f124SMoriah Waterland 				el_ent->mstat.osetuid = 1;
2415c51f124SMoriah Waterland 			}
2425c51f124SMoriah Waterland 
2435c51f124SMoriah Waterland 			if (is_setgid(&cf_ent)) {
2445c51f124SMoriah Waterland 				el_ent->mstat.osetgid = 1;
2455c51f124SMoriah Waterland 			}
2465c51f124SMoriah Waterland 			/*
2475c51f124SMoriah Waterland 			 * Detect if a symlink has changed to directory
2485c51f124SMoriah Waterland 			 * If so mark all the files/dir supposed to be
2495c51f124SMoriah Waterland 			 * iniside this dir, so that they are not miss
2505c51f124SMoriah Waterland 			 * understood by do_new_ent later as already
2515c51f124SMoriah Waterland 			 * installed.
2525c51f124SMoriah Waterland 			 */
25362224350SCasper H.S. Dik 			if ((cf_ent.ftype == 's') &&
2545c51f124SMoriah Waterland 			    (el_ent->cf_ent.ftype == 'd')) {
2555c51f124SMoriah Waterland 				int i;
2565c51f124SMoriah Waterland 				int plen = strlen(el_ent->cf_ent.path);
2575c51f124SMoriah Waterland 				for (i = eptnum + 1; extlist[i]; i++) {
2585c51f124SMoriah Waterland 					if (strncmp(el_ent->cf_ent.path,
2595c51f124SMoriah Waterland 					    extlist[i]->cf_ent.path,
2605c51f124SMoriah Waterland 					    plen) != 0)
2615c51f124SMoriah Waterland 						break;
2625c51f124SMoriah Waterland 					extlist[i]->mstat.parentsyml2dir
2635c51f124SMoriah Waterland 					    = 1;
2645c51f124SMoriah Waterland 				}
2655c51f124SMoriah Waterland 			}
2665c51f124SMoriah Waterland 
26762224350SCasper H.S. Dik 			if (do_like_ent(tmpvfp, el_ent, &cf_ent, assume_ok)) {
2685c51f124SMoriah Waterland 				changed++;
2695c51f124SMoriah Waterland 			}
2705c51f124SMoriah Waterland 
2715c51f124SMoriah Waterland 		} else {
2725c51f124SMoriah Waterland 			/*
27362224350SCasper H.S. Dik 			 * The file doesn't exist in the database.
2745c51f124SMoriah Waterland 			 */
2755c51f124SMoriah Waterland 			if (do_new_ent(tmpvfp, el_ent, assume_ok)) {
2765c51f124SMoriah Waterland 				changed++;
2775c51f124SMoriah Waterland 			}
2785c51f124SMoriah Waterland 		}
2795c51f124SMoriah Waterland 	}
2805c51f124SMoriah Waterland 
2815c51f124SMoriah Waterland 	return (errflg ? -1 : changed);
2825c51f124SMoriah Waterland }
2835c51f124SMoriah Waterland 
2845c51f124SMoriah Waterland /*
2855c51f124SMoriah Waterland  * Merge a new entry with an installed package object of the same name and
2865c51f124SMoriah Waterland  * insert that object into the package database. Obey administrative defaults
2875c51f124SMoriah Waterland  * as regards conflicting files.
2885c51f124SMoriah Waterland  */
2895c51f124SMoriah Waterland 
2905c51f124SMoriah Waterland static int
2915c51f124SMoriah Waterland do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, struct cfent *cf_ent, int ctrl)
2925c51f124SMoriah Waterland {
2935c51f124SMoriah Waterland 	int	stflag, ignore, changed, mrg_result;
2945c51f124SMoriah Waterland 
2955c51f124SMoriah Waterland 	ignore = changed = 0;
2965c51f124SMoriah Waterland 
2975c51f124SMoriah Waterland 	/*
2985c51f124SMoriah Waterland 	 * Construct the record defining the current package. If there are
2995c51f124SMoriah Waterland 	 * other packages involved, this will be appended to the existing
3005c51f124SMoriah Waterland 	 * list. If this is an update of the same package, it will get merged
3015c51f124SMoriah Waterland 	 * with the existing record. If this is a preloaded record (like from
3025c51f124SMoriah Waterland 	 * a dryrun file), it will keep it's current pinfo pointer and will
3035c51f124SMoriah Waterland 	 * pass it on to the record from the contents file - because on the
3045c51f124SMoriah Waterland 	 * final continuation, the contents file will be wrong.
3055c51f124SMoriah Waterland 	 */
3065c51f124SMoriah Waterland 	if (el_ent->mstat.preloaded) {
3075c51f124SMoriah Waterland 		struct pinfo *pkginfo;
3085c51f124SMoriah Waterland 
3095c51f124SMoriah Waterland 		/* Contents file is not to be trusted for this list. */
3105c51f124SMoriah Waterland 		pkginfo = cf_ent->pinfo;
3115c51f124SMoriah Waterland 
3125c51f124SMoriah Waterland 		/* Free the potentially bogus list. */
3135c51f124SMoriah Waterland 		while (pkginfo) {
3145c51f124SMoriah Waterland 			struct pinfo *next;
3155c51f124SMoriah Waterland 			next = pkginfo->next;
3165c51f124SMoriah Waterland 			free(pkginfo);
3175c51f124SMoriah Waterland 			pkginfo = next;
3185c51f124SMoriah Waterland 		}
3195c51f124SMoriah Waterland 
3205c51f124SMoriah Waterland 		cf_ent->pinfo = el_ent->cf_ent.pinfo;
3215c51f124SMoriah Waterland 	}
3225c51f124SMoriah Waterland 
3235c51f124SMoriah Waterland 	pkgpinfo = eptstat(cf_ent, pkginst, DUP_ENTRY);
3245c51f124SMoriah Waterland 
3255c51f124SMoriah Waterland 	stflag = pkgpinfo->status;
3265c51f124SMoriah Waterland 
3275c51f124SMoriah Waterland 	if (otherstoo)
3285c51f124SMoriah Waterland 		el_ent->mstat.shared = 1;
3295c51f124SMoriah Waterland 
3305c51f124SMoriah Waterland 	/* If it's marked for erasure, make it official */
3315c51f124SMoriah Waterland 	if (el_ent->cf_ent.ftype == RM_RDY) {
3325c51f124SMoriah Waterland 		if (!errflg) {
3335c51f124SMoriah Waterland 			pkgpinfo = eptstat(cf_ent, pkginst, RM_RDY);
3345c51f124SMoriah Waterland 
3355c51f124SMoriah Waterland 			/*
3365c51f124SMoriah Waterland 			 * Get copy of status character in case the object is
3375c51f124SMoriah Waterland 			 * "shared" by a server, in which case we need to
3385c51f124SMoriah Waterland 			 * maintain the shared status after the entry is
3395c51f124SMoriah Waterland 			 * written to the package database with RM_RDY
3405c51f124SMoriah Waterland 			 * status. This is needed to support the `removef'
3415c51f124SMoriah Waterland 			 * command.
3425c51f124SMoriah Waterland 			 */
3435c51f124SMoriah Waterland 			stflag = pkgpinfo->status;
3445c51f124SMoriah Waterland 			pkgpinfo->status = RM_RDY;
3455c51f124SMoriah Waterland 
3465c51f124SMoriah Waterland 			if (putcvfpfile(cf_ent, vfpo)) {
3475c51f124SMoriah Waterland 				progerr(gettext(ERR_OUTPUT));
3485c51f124SMoriah Waterland 				quit(99);
3495c51f124SMoriah Waterland 			}
3505c51f124SMoriah Waterland 
3515c51f124SMoriah Waterland 			/*
3525c51f124SMoriah Waterland 			 * If object is provided by a server, allocate an
3535c51f124SMoriah Waterland 			 * info block and set the status to indicate this.
3545c51f124SMoriah Waterland 			 * This is needed to support the `removef' command.
3555c51f124SMoriah Waterland 			 */
3565c51f124SMoriah Waterland 			if (stflag == SERVED_FILE) {
3575c51f124SMoriah Waterland 				el_ent->cf_ent.pinfo =
3585c51f124SMoriah Waterland 				    (struct pinfo *)calloc(1,
3595c51f124SMoriah Waterland 				    sizeof (struct pinfo));
3605c51f124SMoriah Waterland 				el_ent->cf_ent.pinfo->next = NULL;
3615c51f124SMoriah Waterland 				el_ent->cf_ent.pinfo->status = SERVED_FILE;
3625c51f124SMoriah Waterland 			}
3635c51f124SMoriah Waterland 		}
3645c51f124SMoriah Waterland 		return (1);
3655c51f124SMoriah Waterland 	}
3665c51f124SMoriah Waterland 
3675c51f124SMoriah Waterland 	/*
3685c51f124SMoriah Waterland 	 * If there is no package associated with it, there's something
3695c51f124SMoriah Waterland 	 * very wrong.
3705c51f124SMoriah Waterland 	 */
3715c51f124SMoriah Waterland 	if (!pkgpinfo) {
3725c51f124SMoriah Waterland 		progerr(gettext(ERR_PINFO), cf_ent->path);
3735c51f124SMoriah Waterland 		quit(99);
3745c51f124SMoriah Waterland 	}
3755c51f124SMoriah Waterland 
3765c51f124SMoriah Waterland 	/*
3775c51f124SMoriah Waterland 	 * Do not allow installation if nocnflct is set and other packages
3785c51f124SMoriah Waterland 	 * reference this pathname. The cp_cfent() function below writes the
3795c51f124SMoriah Waterland 	 * information from the installed file over the new entry, so the
3805c51f124SMoriah Waterland 	 * package database will be unchanged.
3815c51f124SMoriah Waterland 	 *
3825c51f124SMoriah Waterland 	 * By the way, ftype "e" is often shared and that's OK, so ftype
3835c51f124SMoriah Waterland 	 * "e" doesn't count here.
3845c51f124SMoriah Waterland 	 */
3855c51f124SMoriah Waterland 	if ((nocnflct && el_ent->mstat.shared && el_ent->cf_ent.ftype != 'e')) {
3865c51f124SMoriah Waterland 		/*
3875c51f124SMoriah Waterland 		 * First set the attrchg and contchg entries for proper
3885c51f124SMoriah Waterland 		 * messaging in the install phase.
3895c51f124SMoriah Waterland 		 */
3905c51f124SMoriah Waterland 		set_change(el_ent);
3915c51f124SMoriah Waterland 
3925c51f124SMoriah Waterland 		/*
3935c51f124SMoriah Waterland 		 * Now overwrite the new entry with the entry for the
3945c51f124SMoriah Waterland 		 * currently installed object.
3955c51f124SMoriah Waterland 		 */
3965c51f124SMoriah Waterland 		if (cp_cfent(cf_ent, el_ent) == 0)
3975c51f124SMoriah Waterland 			quit(99);
3985c51f124SMoriah Waterland 
3995c51f124SMoriah Waterland 		ignore++;
4005c51f124SMoriah Waterland 	} else {
4015c51f124SMoriah Waterland 		mrg_result = merg(el_ent, cf_ent);
4025c51f124SMoriah Waterland 
4035c51f124SMoriah Waterland 		switch (mrg_result) {
4045c51f124SMoriah Waterland 		    case MRG_SAME:
4055c51f124SMoriah Waterland 			break;
4065c51f124SMoriah Waterland 
4075c51f124SMoriah Waterland 		    case MRG_DIFFERENT:
4085c51f124SMoriah Waterland 			changed++;
4095c51f124SMoriah Waterland 			break;
4105c51f124SMoriah Waterland 
4115c51f124SMoriah Waterland 		    case MRG_REPLACE:
4125c51f124SMoriah Waterland 			/*
4135c51f124SMoriah Waterland 			 * We'll pick one or the other later. For now, cf_ent
4145c51f124SMoriah Waterland 			 * will have the fault value and el_ent will retain
4155c51f124SMoriah Waterland 			 * the other value. This is the only state that allows
4165c51f124SMoriah Waterland 			 * the database and the pkgmap to differ.
4175c51f124SMoriah Waterland 			 */
4185c51f124SMoriah Waterland 
4195c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;	/* subject to change */
4205c51f124SMoriah Waterland 			ignore++;
4215c51f124SMoriah Waterland 			break;
4225c51f124SMoriah Waterland 
4235c51f124SMoriah Waterland 		    default:
4245c51f124SMoriah Waterland 			break;
4255c51f124SMoriah Waterland 		}
4265c51f124SMoriah Waterland 	}
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 	/* el_ent structure now contains updated entry */
4295c51f124SMoriah Waterland 	if (!el_ent->mstat.contchg && !ignore) {
4305c51f124SMoriah Waterland 		/*
4315c51f124SMoriah Waterland 		 * We know the DB entry matches the pkgmap, so now we need to
4325c51f124SMoriah Waterland 		 * see if the actual object matches the pkgmap.
4335c51f124SMoriah Waterland 		 */
4345c51f124SMoriah Waterland 		set_change(el_ent);
4355c51f124SMoriah Waterland 	}
4365c51f124SMoriah Waterland 
4375c51f124SMoriah Waterland 	if (!errflg) {
4385c51f124SMoriah Waterland 		if (ctrl == 1) {	/* quick verify assumes OK */
4395c51f124SMoriah Waterland 			/*
4405c51f124SMoriah Waterland 			 * The pkgpinfo entry is already correctly
4415c51f124SMoriah Waterland 			 * constructed. Look into dropping this soon.
4425c51f124SMoriah Waterland 			 */
4435c51f124SMoriah Waterland 			pkgpinfo = eptstat(&(el_ent->cf_ent), pkginst,
4445c51f124SMoriah Waterland 			    ENTRY_OK);
4455c51f124SMoriah Waterland 
4465c51f124SMoriah Waterland 			if (stflag != DUP_ENTRY) {
4475c51f124SMoriah Waterland 				changed++;
4485c51f124SMoriah Waterland 			}
4495c51f124SMoriah Waterland 
4505c51f124SMoriah Waterland 			/*
4515c51f124SMoriah Waterland 			 * We could trust the prior pkginfo entry, but things
4525c51f124SMoriah Waterland 			 * could have changed and  we need to update the
4535c51f124SMoriah Waterland 			 * fs_tab[] anyway. We check for a server object
4545c51f124SMoriah Waterland 			 * here.
4555c51f124SMoriah Waterland 			 */
4565c51f124SMoriah Waterland 			if (is_served(el_ent->server_path,
4575c51f124SMoriah Waterland 			    &(el_ent->fsys_value)))
4585c51f124SMoriah Waterland 				pkgpinfo->status = SERVED_FILE;
4595c51f124SMoriah Waterland 		} else {
4605c51f124SMoriah Waterland 			if (!ignore && el_ent->mstat.contchg) {
4615c51f124SMoriah Waterland 				pkgpinfo =
4625c51f124SMoriah Waterland 				    eptstat(&(el_ent->cf_ent), pkginst,
4635c51f124SMoriah Waterland 				    (dbst ? dbst : CONFIRM_CONT));
4645c51f124SMoriah Waterland 			} else if (!ignore && el_ent->mstat.attrchg) {
4655c51f124SMoriah Waterland 				pkgpinfo =
4665c51f124SMoriah Waterland 				    eptstat(&(el_ent->cf_ent), pkginst,
4675c51f124SMoriah Waterland 				    (dbst ? dbst : CONFIRM_ATTR));
4685c51f124SMoriah Waterland 			} else if (!ignore && el_ent->mstat.shared) {
4695c51f124SMoriah Waterland 				pkgpinfo =
4705c51f124SMoriah Waterland 				    eptstat(&(el_ent->cf_ent), pkginst,
4715c51f124SMoriah Waterland 				    dbst);
4725c51f124SMoriah Waterland 				changed++;
4735c51f124SMoriah Waterland 			} else if (stflag != DUP_ENTRY) {
4745c51f124SMoriah Waterland 				pkgpinfo = eptstat(&(el_ent->cf_ent),
4755c51f124SMoriah Waterland 				    pkginst, '\0');
4765c51f124SMoriah Waterland 				if (stflag != ENTRY_OK) {
4775c51f124SMoriah Waterland 					changed++;
4785c51f124SMoriah Waterland 				}
4795c51f124SMoriah Waterland 			}
4805c51f124SMoriah Waterland 		}
4815c51f124SMoriah Waterland 
4825c51f124SMoriah Waterland 		if (mrg_result == MRG_REPLACE) {
4835c51f124SMoriah Waterland 			/*
4845c51f124SMoriah Waterland 			 * Put the original package database entry back into
4855c51f124SMoriah Waterland 			 * the package database for now.
4865c51f124SMoriah Waterland 			 */
4875c51f124SMoriah Waterland 			output(vfpo, cf_ent, pkgpinfo);
4885c51f124SMoriah Waterland 		} else {
4895c51f124SMoriah Waterland 			/* Put the merged entry into the package database. */
4905c51f124SMoriah Waterland 			output(vfpo, &(el_ent->cf_ent), pkgpinfo);
4915c51f124SMoriah Waterland 		}
4925c51f124SMoriah Waterland 	}
4935c51f124SMoriah Waterland 
4945c51f124SMoriah Waterland 	if (pkgpinfo->aclass[0] != '\0') {
4955c51f124SMoriah Waterland 		(void) strcpy(el_ent->cf_ent.pkg_class, pkgpinfo->aclass);
4965c51f124SMoriah Waterland 	}
4975c51f124SMoriah Waterland 
4985c51f124SMoriah Waterland 	/*
4995c51f124SMoriah Waterland 	 * If a sym link entry exists in the contents file and
5005c51f124SMoriah Waterland 	 * and the destination of the link does not exist on the the system
5015c51f124SMoriah Waterland 	 * then the contents file needs to be updated appropriately so a
5025c51f124SMoriah Waterland 	 * subsequent invocation of "installf -f" will create the destination.
5035c51f124SMoriah Waterland 	 */
5045c51f124SMoriah Waterland 	if (el_ent->mstat.contchg && pkgpinfo->status == INST_RDY) {
5055c51f124SMoriah Waterland 		changed++;
5065c51f124SMoriah Waterland 	}
5075c51f124SMoriah Waterland 
5085c51f124SMoriah Waterland 	if (!(el_ent->mstat.preloaded))
5095c51f124SMoriah Waterland 		el_ent->cf_ent.pinfo = NULL;
5105c51f124SMoriah Waterland 
5115c51f124SMoriah Waterland 	/*
5125c51f124SMoriah Waterland 	 * If no change during the merg and we don't have a case where types
5135c51f124SMoriah Waterland 	 * were different in odd ways, count this as installed.
5145c51f124SMoriah Waterland 	 */
5155c51f124SMoriah Waterland 	if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg &&
5165c51f124SMoriah Waterland 	    !el_ent->mstat.replace)
5175c51f124SMoriah Waterland 		installed++;
5185c51f124SMoriah Waterland 	return (changed);
5195c51f124SMoriah Waterland }
5205c51f124SMoriah Waterland 
5215c51f124SMoriah Waterland /* Insert an entirely new entry into the package database. */
5225c51f124SMoriah Waterland static int
5235c51f124SMoriah Waterland do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl)
5245c51f124SMoriah Waterland {
5255c51f124SMoriah Waterland 	struct pinfo	*pinfo;
5265c51f124SMoriah Waterland 	char		*tp;
5275c51f124SMoriah Waterland 	int		changed = 0;
5285c51f124SMoriah Waterland 
5295c51f124SMoriah Waterland 	if (el_ent->cf_ent.ftype == RM_RDY) {
5305c51f124SMoriah Waterland 		return (0);
5315c51f124SMoriah Waterland 	}
5325c51f124SMoriah Waterland 
5335c51f124SMoriah Waterland 	tp = el_ent->server_path;
5345c51f124SMoriah Waterland 	/*
5355c51f124SMoriah Waterland 	 * Check the file/dir existence only if any of the parent directory
5365c51f124SMoriah Waterland 	 * of the file/dir has not changed from symbolic link to directory.
5375c51f124SMoriah Waterland 	 * At this time we are only doing a dry run, the symlink is not yet
5385c51f124SMoriah Waterland 	 * replaced, so if this is done directly then access will result in
5395c51f124SMoriah Waterland 	 * incorrect information in case a file with the same attr and cont
5405c51f124SMoriah Waterland 	 * exists in the link target.
5415c51f124SMoriah Waterland 	 */
5425c51f124SMoriah Waterland 	if ((!el_ent->mstat.parentsyml2dir) && (access(tp, F_OK) == 0)) {
5435c51f124SMoriah Waterland 		/*
5445c51f124SMoriah Waterland 		 * Path exists, and although its not referenced by any
5455c51f124SMoriah Waterland 		 * package we make it look like it is so it appears as a
5465c51f124SMoriah Waterland 		 * conflicting file in case the user doesn't want it
5475c51f124SMoriah Waterland 		 * installed. We set the rogue flag to distinguish this from
5485c51f124SMoriah Waterland 		 * package object conflicts if the administrator is queried
5495c51f124SMoriah Waterland 		 * about this later. Note that noconflict means NO conflict
5505c51f124SMoriah Waterland 		 * at the file level. Even rogue files count.
5515c51f124SMoriah Waterland 		 */
5525c51f124SMoriah Waterland 		el_ent->mstat.shared = 1;
5535c51f124SMoriah Waterland 		el_ent->mstat.rogue = 1;
5545c51f124SMoriah Waterland 		set_change(el_ent);
5555c51f124SMoriah Waterland 	} else {
5565c51f124SMoriah Waterland 		/* since path doesn't exist, we're changing everything */
5575c51f124SMoriah Waterland 		el_ent->mstat.rogue = 0;
5585c51f124SMoriah Waterland 		el_ent->mstat.contchg = 1;
5595c51f124SMoriah Waterland 		el_ent->mstat.attrchg = 1;
5605c51f124SMoriah Waterland 	}
5615c51f124SMoriah Waterland 
5625c51f124SMoriah Waterland 	if (el_ent->cf_ent.ainfo.mode == WILDCARD) {
5635c51f124SMoriah Waterland 		if (el_ent->cf_ent.ftype == 'd') {
5645c51f124SMoriah Waterland 			el_ent->cf_ent.ainfo.mode = DEFAULT_MODE;
5655c51f124SMoriah Waterland 		} else {
5665c51f124SMoriah Waterland 			el_ent->cf_ent.ainfo.mode = DEFAULT_MODE_FILE;
5675c51f124SMoriah Waterland 		}
5685c51f124SMoriah Waterland 		logerr(WRN_SET_DEF_MODE, el_ent->cf_ent.path,
5695c51f124SMoriah Waterland 		    (int)el_ent->cf_ent.ainfo.mode);
5705c51f124SMoriah Waterland 	}
5715c51f124SMoriah Waterland 
5725c51f124SMoriah Waterland 	if (strcmp(el_ent->cf_ent.ainfo.owner, DB_UNDEFINED_ENTRY) == 0)
5735c51f124SMoriah Waterland 		(void) strcpy(el_ent->cf_ent.ainfo.owner,
5745c51f124SMoriah Waterland 				DEFAULT_OWNER);
5755c51f124SMoriah Waterland 	if (strcmp(el_ent->cf_ent.ainfo.group, DB_UNDEFINED_ENTRY) == 0)
5765c51f124SMoriah Waterland 		(void) strcpy(el_ent->cf_ent.ainfo.group,
5775c51f124SMoriah Waterland 				DEFAULT_GROUP);
5785c51f124SMoriah Waterland 
5795c51f124SMoriah Waterland 	/*
5805c51f124SMoriah Waterland 	 * Do not allow installation if nocnflct is set and this pathname is
5815c51f124SMoriah Waterland 	 * already in place. Since this entry is new (not associated with a
5825c51f124SMoriah Waterland 	 * package), we don't issue anything to the database we're building.
5835c51f124SMoriah Waterland 	 */
5845c51f124SMoriah Waterland 	if (nocnflct && el_ent->mstat.shared) {
5855c51f124SMoriah Waterland 		return (0);
5865c51f124SMoriah Waterland 	}
5875c51f124SMoriah Waterland 
5885c51f124SMoriah Waterland 	if (!errflg) {
5895c51f124SMoriah Waterland 		if (el_ent->mstat.preloaded) {
5905c51f124SMoriah Waterland 			/* Add this package to the already established list. */
5915c51f124SMoriah Waterland 			pinfo = eptstat(&(el_ent->cf_ent), pkginst, DUP_ENTRY);
5925c51f124SMoriah Waterland 		} else {
5935c51f124SMoriah Waterland 			el_ent->cf_ent.npkgs = 1;
5945c51f124SMoriah Waterland 			pinfo = (struct pinfo *)calloc(1,
5955c51f124SMoriah Waterland 			    sizeof (struct pinfo));
5965c51f124SMoriah Waterland 			if (!pinfo) {
5975c51f124SMoriah Waterland 				progerr(gettext(ERR_MEMORY), errno);
5985c51f124SMoriah Waterland 				quit(99);
5995c51f124SMoriah Waterland 			}
6005c51f124SMoriah Waterland 			el_ent->cf_ent.pinfo = pinfo;
6015c51f124SMoriah Waterland 			(void) strcpy(pinfo->pkg, pkginst);
6025c51f124SMoriah Waterland 		}
6035c51f124SMoriah Waterland 
6045c51f124SMoriah Waterland 		if (ctrl == 1) {	/* quick verify assumes OK */
6055c51f124SMoriah Waterland 			pinfo->status = dbst ? dbst : ENTRY_OK;
6065c51f124SMoriah Waterland 			/*
6075c51f124SMoriah Waterland 			 * The entry won't be verified, but the entry in the
6085c51f124SMoriah Waterland 			 * database isn't necessarily ENTRY_OK. If this is
6095c51f124SMoriah Waterland 			 * coming from a server, we need to note that
6105c51f124SMoriah Waterland 			 * instead.
6115c51f124SMoriah Waterland 			 */
6125c51f124SMoriah Waterland 			if (is_served(el_ent->server_path,
6135c51f124SMoriah Waterland 			    &(el_ent->fsys_value)))
6145c51f124SMoriah Waterland 				pinfo->status = SERVED_FILE;
6155c51f124SMoriah Waterland 		} else {
6165c51f124SMoriah Waterland 			pinfo->status = dbst ? dbst : CONFIRM_CONT;
6175c51f124SMoriah Waterland 		}
6185c51f124SMoriah Waterland 
6195c51f124SMoriah Waterland 		output(vfpo, &(el_ent->cf_ent), pinfo);
6205c51f124SMoriah Waterland 		changed++;
6215c51f124SMoriah Waterland 
6225c51f124SMoriah Waterland 		free(pinfo);
6235c51f124SMoriah Waterland 		el_ent->cf_ent.pinfo = NULL;
6245c51f124SMoriah Waterland 		}
6255c51f124SMoriah Waterland 	if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg) {
6265c51f124SMoriah Waterland 		installed++;
6275c51f124SMoriah Waterland 	}
6285c51f124SMoriah Waterland 
6295c51f124SMoriah Waterland 	return (changed);
6305c51f124SMoriah Waterland }
6315c51f124SMoriah Waterland 
6325c51f124SMoriah Waterland int
6335c51f124SMoriah Waterland files_installed(void)
6345c51f124SMoriah Waterland {
6355c51f124SMoriah Waterland 	return (installed);
6365c51f124SMoriah Waterland }
6375c51f124SMoriah Waterland 
6385c51f124SMoriah Waterland /*
6395c51f124SMoriah Waterland  * This function determines if there is a difference between the file on
6405c51f124SMoriah Waterland  * the disk and the file to be laid down. It set's mstat flags attrchg
6415c51f124SMoriah Waterland  * and contchg accordingly.
6425c51f124SMoriah Waterland  */
6435c51f124SMoriah Waterland static void
6445c51f124SMoriah Waterland set_change(struct cfextra *el_ent)
6455c51f124SMoriah Waterland {
6465c51f124SMoriah Waterland 	int	n;
6475c51f124SMoriah Waterland 	char 	*tp;
6485c51f124SMoriah Waterland 
6495c51f124SMoriah Waterland 	tp = el_ent->server_path;
6505c51f124SMoriah Waterland 	if ((el_ent->cf_ent.ftype == 'f') || (el_ent->cf_ent.ftype == 'e') ||
6515c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'v')) {
6525c51f124SMoriah Waterland 		if (cverify(0, &(el_ent->cf_ent.ftype), tp,
6535c51f124SMoriah Waterland 		    &(el_ent->cf_ent.cinfo), 1)) {
6545c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
6555c51f124SMoriah Waterland 		} else if (!el_ent->mstat.contchg && !el_ent->mstat.attrchg) {
6565c51f124SMoriah Waterland 			if (averify(0, &(el_ent->cf_ent.ftype), tp,
6575c51f124SMoriah Waterland 			    &(el_ent->cf_ent.ainfo)))
6585c51f124SMoriah Waterland 				el_ent->mstat.attrchg = 1;
6595c51f124SMoriah Waterland 		}
6605c51f124SMoriah Waterland 	} else if (!el_ent->mstat.attrchg &&
6615c51f124SMoriah Waterland 		((el_ent->cf_ent.ftype == 'd') ||
6625c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'x') ||
6635c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'c') ||
6645c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'b') ||
6655c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'p'))) {
6665c51f124SMoriah Waterland 		n = averify(0, &(el_ent->cf_ent.ftype), tp,
6675c51f124SMoriah Waterland 		    &(el_ent->cf_ent.ainfo));
6685c51f124SMoriah Waterland 		if (n == VE_ATTR)
6695c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 1;
6705c51f124SMoriah Waterland 		else if (n && (n != VE_EXIST)) {
6715c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
6725c51f124SMoriah Waterland 		}
6735c51f124SMoriah Waterland 	} else if (!el_ent->mstat.attrchg &&
6745c51f124SMoriah Waterland 		((el_ent->cf_ent.ftype == 's') ||
6755c51f124SMoriah Waterland 		(el_ent->cf_ent.ftype == 'l'))) {
6765c51f124SMoriah Waterland 		n = averify(0, &(el_ent->cf_ent.ftype), tp,
6775c51f124SMoriah Waterland 		    &(el_ent->cf_ent.ainfo));
6785c51f124SMoriah Waterland 		if (n == VE_ATTR)
6795c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 1;
6805c51f124SMoriah Waterland 		else if (n && (n == VE_EXIST)) {
6815c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
6825c51f124SMoriah Waterland 		}
6835c51f124SMoriah Waterland 	}
6845c51f124SMoriah Waterland }
6855c51f124SMoriah Waterland 
6865c51f124SMoriah Waterland static int
6875c51f124SMoriah Waterland is_setuid(struct cfent *ent)
6885c51f124SMoriah Waterland {
6895c51f124SMoriah Waterland 	return (((ent->ftype == 'f') || (ent->ftype == 'v') ||
6905c51f124SMoriah Waterland 		(ent->ftype == 'e')) &&
6915c51f124SMoriah Waterland 		(ent->ainfo.mode != BADMODE) &&
6925c51f124SMoriah Waterland 		(ent->ainfo.mode != WILDCARD) &&
6935c51f124SMoriah Waterland 		(ent->ainfo.mode & S_ISUID));
6945c51f124SMoriah Waterland }
6955c51f124SMoriah Waterland 
6965c51f124SMoriah Waterland static int
6975c51f124SMoriah Waterland is_setgid(struct cfent *ent)
6985c51f124SMoriah Waterland {
6995c51f124SMoriah Waterland 	return (((ent->ftype == 'f') || (ent->ftype == 'v') ||
7005c51f124SMoriah Waterland 		(ent->ftype == 'e')) && (ent->ainfo.mode != BADMODE) &&
7015c51f124SMoriah Waterland 		(ent->ainfo.mode != WILDCARD) &&
7025c51f124SMoriah Waterland 		(ent->ainfo.mode & S_ISGID) &&
7035c51f124SMoriah Waterland 		(ent->ainfo.mode & (S_IEXEC|S_IXUSR|S_IXOTH)));
7045c51f124SMoriah Waterland }
7055c51f124SMoriah Waterland 
7065c51f124SMoriah Waterland char *types[] = {
7075c51f124SMoriah Waterland 	"fev",	/* type 1, regular files */
7085c51f124SMoriah Waterland 	"s", 	/* type 2, symbolic links */
7095c51f124SMoriah Waterland 	"l", 	/* type 3, linked files */
7105c51f124SMoriah Waterland 	"dx", 	/* type 4, directories */
7115c51f124SMoriah Waterland 	"c", 	/* type 5, character special devices */
7125c51f124SMoriah Waterland 	"b", 	/* type 6, block special devices */
7135c51f124SMoriah Waterland 	"p", 	/* type 7, named pipes */
7145c51f124SMoriah Waterland 	NULL
7155c51f124SMoriah Waterland };
7165c51f124SMoriah Waterland 
7175c51f124SMoriah Waterland /*
7185c51f124SMoriah Waterland  * This determines if the ftype of the file on the disk and the file to be
7195c51f124SMoriah Waterland  * laid down are close enough. If they aren't, this either returns an error
7205c51f124SMoriah Waterland  * or displays a warning. This returns :
7215c51f124SMoriah Waterland  *	TYPE_OK		they're identical or close enough
7225c51f124SMoriah Waterland  *	TYPE_WARNING	they're pretty close (probably no problem)
7235c51f124SMoriah Waterland  *	TYPE_IGNORED	the type change was not allowed
7245c51f124SMoriah Waterland  *	TYPE_REPLACE	to be reviewed later - in endofclass() maybe
7255c51f124SMoriah Waterland  *	TYPE_FATAL	something awful happened
7265c51f124SMoriah Waterland  */
7275c51f124SMoriah Waterland static int
728*b46ec01aSok199659 typechg(struct cfent *el_ent, struct cfent *cf_ent, struct mergstat *mstat)
7295c51f124SMoriah Waterland {
7305c51f124SMoriah Waterland 	int	i, etype, itype, retcode;
7315c51f124SMoriah Waterland 
7325c51f124SMoriah Waterland 	/* If they are identical, return OK */
733*b46ec01aSok199659 	if (cf_ent->ftype == el_ent->ftype)
7345c51f124SMoriah Waterland 		return (TYPE_OK);
7355c51f124SMoriah Waterland 
7365c51f124SMoriah Waterland 	/*
7375c51f124SMoriah Waterland 	 * If package database entry is ambiguous, set it to the new entity's
7385c51f124SMoriah Waterland 	 * ftype
7395c51f124SMoriah Waterland 	 */
740*b46ec01aSok199659 	if (cf_ent->ftype == BADFTYPE) {
741*b46ec01aSok199659 		cf_ent->ftype = el_ent->ftype;
7425c51f124SMoriah Waterland 		return (TYPE_OK); /* do nothing; not really different */
7435c51f124SMoriah Waterland 	}
7445c51f124SMoriah Waterland 
7455c51f124SMoriah Waterland 	/* If the new entity is ambiguous, wait for the verify */
7465c51f124SMoriah Waterland 	if (el_ent->ftype == BADFTYPE)
7475c51f124SMoriah Waterland 		return (TYPE_OK);
7485c51f124SMoriah Waterland 
7495c51f124SMoriah Waterland 	/*
7505c51f124SMoriah Waterland 	 * If we're trying to convert an existing regular directory to an
7515c51f124SMoriah Waterland 	 * exclusive directory, this is very dangerous. We will continue, but
7525c51f124SMoriah Waterland 	 * we will deny the conversion.
7535c51f124SMoriah Waterland 	 */
754*b46ec01aSok199659 	if (el_ent->ftype == 'x' && cf_ent->ftype == 'd') {
7555c51f124SMoriah Waterland 		logerr(gettext(WRN_TOEXCL), el_ent->path);
7565c51f124SMoriah Waterland 		return (TYPE_IGNORED);
7575c51f124SMoriah Waterland 	}
7585c51f124SMoriah Waterland 
7595c51f124SMoriah Waterland 	etype = itype = 0;
7605c51f124SMoriah Waterland 
7615c51f124SMoriah Waterland 	/* Set etype to that of the new entity */
7625c51f124SMoriah Waterland 	for (i = 0; types[i]; ++i) {
7635c51f124SMoriah Waterland 		if (strchr(types[i], el_ent->ftype)) {
7645c51f124SMoriah Waterland 			etype = i+1;
7655c51f124SMoriah Waterland 			break;
7665c51f124SMoriah Waterland 		}
7675c51f124SMoriah Waterland 	}
7685c51f124SMoriah Waterland 
7695c51f124SMoriah Waterland 	/* Set itype to that in the package database. */
7705c51f124SMoriah Waterland 	for (i = 0; types[i]; ++i) {
771*b46ec01aSok199659 		if (strchr(types[i], cf_ent->ftype)) {
7725c51f124SMoriah Waterland 			itype = i+1;
7735c51f124SMoriah Waterland 			break;
7745c51f124SMoriah Waterland 		}
7755c51f124SMoriah Waterland 	}
7765c51f124SMoriah Waterland 
7775c51f124SMoriah Waterland 	if (itype == etype) {
7785c51f124SMoriah Waterland 		/* same basic object type */
7795c51f124SMoriah Waterland 		return (TYPE_OK);
7805c51f124SMoriah Waterland 	}
7815c51f124SMoriah Waterland 
7825c51f124SMoriah Waterland 	retcode = TYPE_WARNING;
7835c51f124SMoriah Waterland 
7845c51f124SMoriah Waterland 	/*
7855c51f124SMoriah Waterland 	 * If a simple object (like a file) is overwriting a directory, mark
7865c51f124SMoriah Waterland 	 * it for full inspection during installation.
7875c51f124SMoriah Waterland 	 */
7885c51f124SMoriah Waterland 	if (etype != 4 && itype == 4) {
7895c51f124SMoriah Waterland 		mstat->dir2nondir = 1;
7905c51f124SMoriah Waterland 		retcode = TYPE_REPLACE;
7915c51f124SMoriah Waterland 	}
7925c51f124SMoriah Waterland 
7935c51f124SMoriah Waterland 	/* allow change, but warn user of possible problems */
7945c51f124SMoriah Waterland 	switch (itype) {
7955c51f124SMoriah Waterland 	    case 1:
7965c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTFILE), el_ent->path);
7975c51f124SMoriah Waterland 		break;
7985c51f124SMoriah Waterland 
7995c51f124SMoriah Waterland 	    case 2:
8005c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTSYMLN), el_ent->path);
8015c51f124SMoriah Waterland 		break;
8025c51f124SMoriah Waterland 
8035c51f124SMoriah Waterland 	    case 3:
8045c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTLINK), el_ent->path);
8055c51f124SMoriah Waterland 		break;
8065c51f124SMoriah Waterland 
8075c51f124SMoriah Waterland 	    case 4:
8085c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTDIR), el_ent->path);
8095c51f124SMoriah Waterland 		break;
8105c51f124SMoriah Waterland 
8115c51f124SMoriah Waterland 	    case 5:
8125c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTCHAR), el_ent->path);
8135c51f124SMoriah Waterland 		break;
8145c51f124SMoriah Waterland 
8155c51f124SMoriah Waterland 	    case 6:
8165c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTBLOCK), el_ent->path);
8175c51f124SMoriah Waterland 		break;
8185c51f124SMoriah Waterland 
8195c51f124SMoriah Waterland 	    case 7:
8205c51f124SMoriah Waterland 		logerr(gettext(WRN_NOTPIPE), el_ent->path);
8215c51f124SMoriah Waterland 		break;
8225c51f124SMoriah Waterland 
8235c51f124SMoriah Waterland 	    default:
8245c51f124SMoriah Waterland 		break;
8255c51f124SMoriah Waterland 	}
8265c51f124SMoriah Waterland 	return (retcode);
8275c51f124SMoriah Waterland }
8285c51f124SMoriah Waterland 
8295c51f124SMoriah Waterland /*
8305c51f124SMoriah Waterland  * This function takes el_ent (the entry from the pkgmap) and cf_ent (the
8315c51f124SMoriah Waterland  * entry from the package database) and merge them into el_ent. The rules
8325c51f124SMoriah Waterland  * are still being figured out, but the comments should make the approach
8335c51f124SMoriah Waterland  * pretty clear.
8345c51f124SMoriah Waterland  *
8355c51f124SMoriah Waterland  * RETURN CODES:
8365c51f124SMoriah Waterland  *	MRG_DIFFERENT	The two entries are different and el_ent now contains
8375c51f124SMoriah Waterland  *			the intended new entry to be installed.
8385c51f124SMoriah Waterland  *	MRG_SAME	The two entries were identical and the old database
8395c51f124SMoriah Waterland  *			entry will be replaced unchanged.
8405c51f124SMoriah Waterland  *	MRG_REPLACE	One or the other entry will be used but the decision
8415c51f124SMoriah Waterland  *			has to be made at install time.
8425c51f124SMoriah Waterland  */
8435c51f124SMoriah Waterland static int
8445c51f124SMoriah Waterland merg(struct cfextra *el_ent, struct cfent *cf_ent)
8455c51f124SMoriah Waterland {
8465c51f124SMoriah Waterland 	int	n, changed = 0;
8475c51f124SMoriah Waterland 
8485c51f124SMoriah Waterland 	/*
8495c51f124SMoriah Waterland 	 * We need to change the original entry to make it look like the new
8505c51f124SMoriah Waterland 	 * entry (the eptstat() routine has already added appropriate package
8515c51f124SMoriah Waterland 	 * information, but not about 'aclass' which may represent a change
8525c51f124SMoriah Waterland 	 * in class from the previous installation.
8535c51f124SMoriah Waterland 	 *
8545c51f124SMoriah Waterland 	 * NOTE: elent->cf_ent.pinfo (the list of associated packages) is NULL
8555c51f124SMoriah Waterland 	 * upon entry to this function.
8565c51f124SMoriah Waterland 	 */
8575c51f124SMoriah Waterland 
8585c51f124SMoriah Waterland 	el_ent->cf_ent.pinfo = cf_ent->pinfo;
8595c51f124SMoriah Waterland 
8605c51f124SMoriah Waterland 	if (dbst == INST_RDY && el_ent->cf_ent.ftype == '?') {
8615c51f124SMoriah Waterland 		el_ent->cf_ent.ftype = cf_ent->ftype;
8625c51f124SMoriah Waterland 	}
8635c51f124SMoriah Waterland 
8645c51f124SMoriah Waterland 	/*
8655c51f124SMoriah Waterland 	 * Evaluate the ftype change. Usually the ftype won't change. If it
8665c51f124SMoriah Waterland 	 * does it may be easy (s -> f), not allowed (d -> x), so complex we
8675c51f124SMoriah Waterland 	 * can't figure it 'til later (d -> s) or fatal (a hook for later).
8685c51f124SMoriah Waterland 	 */
8695c51f124SMoriah Waterland 	if (cf_ent->ftype != el_ent->cf_ent.ftype) {
870*b46ec01aSok199659 		n = typechg(&(el_ent->cf_ent), cf_ent, &(el_ent->mstat));
8715c51f124SMoriah Waterland 
8725c51f124SMoriah Waterland 		switch (n) {
8735c51f124SMoriah Waterland 		    case TYPE_OK:
8745c51f124SMoriah Waterland 			break;
8755c51f124SMoriah Waterland 
8765c51f124SMoriah Waterland 		    /* This is an allowable change. */
8775c51f124SMoriah Waterland 		    case TYPE_WARNING:
8785c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
8795c51f124SMoriah Waterland 			break;
8805c51f124SMoriah Waterland 
8815c51f124SMoriah Waterland 		    /* Not allowed, but leaving it as is is OK. */
8825c51f124SMoriah Waterland 		    case TYPE_IGNORED:
8835c51f124SMoriah Waterland 			logerr(gettext(MSG_TYPIGN));
8845c51f124SMoriah Waterland 			if (cp_cfent(cf_ent, el_ent) == 0)
8855c51f124SMoriah Waterland 				quit(99);
8865c51f124SMoriah Waterland 			return (MRG_SAME);
8875c51f124SMoriah Waterland 
8885c51f124SMoriah Waterland 		    /* Future analysis will reveal if this is OK. */
8895c51f124SMoriah Waterland 		    case TYPE_REPLACE:
8905c51f124SMoriah Waterland 			el_ent->mstat.replace = 1;
8915c51f124SMoriah Waterland 			return (MRG_REPLACE);
8925c51f124SMoriah Waterland 
8935c51f124SMoriah Waterland 		    /* Kill it before it does any damage. */
8945c51f124SMoriah Waterland 		    case TYPE_FATAL:
8955c51f124SMoriah Waterland 			logerr(gettext(MSG_TYPE_ERR));
8965c51f124SMoriah Waterland 			quit(99);
8975c51f124SMoriah Waterland 
8985c51f124SMoriah Waterland 		    default:
8995c51f124SMoriah Waterland 			break;
9005c51f124SMoriah Waterland 		}
9015c51f124SMoriah Waterland 
9025c51f124SMoriah Waterland 		changed++;
9035c51f124SMoriah Waterland 	}
9045c51f124SMoriah Waterland 
9055c51f124SMoriah Waterland 	/* Evaluate and merge the class. */
9065c51f124SMoriah Waterland 	if (strcmp(cf_ent->pkg_class, el_ent->cf_ent.pkg_class)) {
9075c51f124SMoriah Waterland 		/*
9085c51f124SMoriah Waterland 		 * we always allow a class change as long as we have
9095c51f124SMoriah Waterland 		 * consistent ftypes, which at this point we must
9105c51f124SMoriah Waterland 		 */
9115c51f124SMoriah Waterland 		changed++;
9125c51f124SMoriah Waterland 		if (strcmp(cf_ent->pkg_class, "?")) {
9135c51f124SMoriah Waterland 			(void) strcpy(pkgpinfo->aclass,
9145c51f124SMoriah Waterland 			    el_ent->cf_ent.pkg_class);
9155c51f124SMoriah Waterland 			(void) strcpy(el_ent->cf_ent.pkg_class,
9165c51f124SMoriah Waterland 			    cf_ent->pkg_class);
9175c51f124SMoriah Waterland 			chgclass(&(el_ent->cf_ent), pkgpinfo);
9185c51f124SMoriah Waterland 		}
9195c51f124SMoriah Waterland 	}
9205c51f124SMoriah Waterland 
9215c51f124SMoriah Waterland 	/*
9225c51f124SMoriah Waterland 	 * Evaluate and merge based upon the ftype of the intended package
9235c51f124SMoriah Waterland 	 * database entry.
9245c51f124SMoriah Waterland 	 */
9255c51f124SMoriah Waterland 	if (((el_ent->cf_ent.ftype == 's') || (el_ent->cf_ent.ftype == 'l'))) {
9265c51f124SMoriah Waterland 
9275c51f124SMoriah Waterland 		/* If both have link sources, then they need to be merged. */
9285c51f124SMoriah Waterland 		if (cf_ent->ainfo.local && el_ent->cf_ent.ainfo.local) {
9295c51f124SMoriah Waterland 			/*
9305c51f124SMoriah Waterland 			 * If both sources are identical, the merge is
9315c51f124SMoriah Waterland 			 * already done.
9325c51f124SMoriah Waterland 			 */
9335c51f124SMoriah Waterland 			if (strcmp(cf_ent->ainfo.local,
9345c51f124SMoriah Waterland 			    el_ent->cf_ent.ainfo.local) != NULL) {
9355c51f124SMoriah Waterland 				changed++;
9365c51f124SMoriah Waterland 
9375c51f124SMoriah Waterland 				/*
9385c51f124SMoriah Waterland 				 * Otherwise, if the pkgmap entry is
9395c51f124SMoriah Waterland 				 * ambiguous, it will inherit the database
9405c51f124SMoriah Waterland 				 * entry.
9415c51f124SMoriah Waterland 				 */
9425c51f124SMoriah Waterland 				if (strcmp(el_ent->cf_ent.ainfo.local,
9435c51f124SMoriah Waterland 				    "?") == NULL) {
9445c51f124SMoriah Waterland 					(void) strlcpy(
9455c51f124SMoriah Waterland 						el_ent->cf_ent.ainfo.local,
9465c51f124SMoriah Waterland 						cf_ent->ainfo.local,
9475c51f124SMoriah Waterland 						PATH_MAX);
9485c51f124SMoriah Waterland 				} else {
9495c51f124SMoriah Waterland 					el_ent->mstat.contchg = 1;
9505c51f124SMoriah Waterland 				}
9515c51f124SMoriah Waterland 			}
9525c51f124SMoriah Waterland 		}
9535c51f124SMoriah Waterland 		return (changed ? MRG_DIFFERENT : MRG_SAME);
9545c51f124SMoriah Waterland 
9555c51f124SMoriah Waterland 	} else if (el_ent->cf_ent.ftype == 'e') {
9565c51f124SMoriah Waterland 
9575c51f124SMoriah Waterland 		/*
9585c51f124SMoriah Waterland 		 * The contents of edittable files are assumed to be changing
9595c51f124SMoriah Waterland 		 * since some class action script will be doing the work and
9605c51f124SMoriah Waterland 		 * we have no way of evaluating what it will actually do.
9615c51f124SMoriah Waterland 		 */
9625c51f124SMoriah Waterland 		el_ent->mstat.contchg = 1;
9635c51f124SMoriah Waterland 		changed++;
9645c51f124SMoriah Waterland 	} else if (((el_ent->cf_ent.ftype == 'f') ||
9655c51f124SMoriah Waterland 					(el_ent->cf_ent.ftype == 'v'))) {
9665c51f124SMoriah Waterland 		/*
9675c51f124SMoriah Waterland 		 * For regular files, Look at content information; a BADCONT
9685c51f124SMoriah Waterland 		 * in any el_ent field indicates the contents are unknown --
9695c51f124SMoriah Waterland 		 * since cf_ent is guaranteed to have a valid entry here (bad
9705c51f124SMoriah Waterland 		 * assumption?) this function will recognize this as a
9715c51f124SMoriah Waterland 		 * change. The ambiguous el_ent values will be evaluated and
9725c51f124SMoriah Waterland 		 * set later.
9735c51f124SMoriah Waterland 		 */
9745c51f124SMoriah Waterland 
9755c51f124SMoriah Waterland 		/*
9765c51f124SMoriah Waterland 		 * for type f/v files, if the file is in an area that is
9775c51f124SMoriah Waterland 		 * inherited from the global zone, that area is read only
9785c51f124SMoriah Waterland 		 * and the object cannot be changed - ignore any settings
9795c51f124SMoriah Waterland 		 * in the current package database that may be present for
9805c51f124SMoriah Waterland 		 * any existing object because they are irrelevant - since
9815c51f124SMoriah Waterland 		 * the object is in a read-only area shared from the global
9825c51f124SMoriah Waterland 		 * zone, accept that file's actual attributes as being correct.
9835c51f124SMoriah Waterland 		 */
9845c51f124SMoriah Waterland 
9855c51f124SMoriah Waterland 		if (z_path_is_inherited(el_ent->cf_ent.path,
9865c51f124SMoriah Waterland 			el_ent->cf_ent.ftype, get_inst_root()) == B_TRUE) {
9875c51f124SMoriah Waterland 			echoDebug(DBG_PKGDBMRG_INHERITED, el_ent->cf_ent.path);
9885c51f124SMoriah Waterland 		} else if (cf_ent->cinfo.size != el_ent->cf_ent.cinfo.size) {
9895c51f124SMoriah Waterland 			changed++;
9905c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
9915c51f124SMoriah Waterland 		} else if (cf_ent->cinfo.modtime !=
9925c51f124SMoriah Waterland 		    el_ent->cf_ent.cinfo.modtime) {
9935c51f124SMoriah Waterland 			changed++;
9945c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
9955c51f124SMoriah Waterland 		} else if (cf_ent->cinfo.cksum != el_ent->cf_ent.cinfo.cksum) {
9965c51f124SMoriah Waterland 			changed++;
9975c51f124SMoriah Waterland 			el_ent->mstat.contchg = 1;
9985c51f124SMoriah Waterland 		}
9995c51f124SMoriah Waterland 	} else if (((el_ent->cf_ent.ftype == 'c') ||
10005c51f124SMoriah Waterland 					(el_ent->cf_ent.ftype == 'b'))) {
10015c51f124SMoriah Waterland 		/*
10025c51f124SMoriah Waterland 		 * For devices, if major or minor numbers are identical the
10035c51f124SMoriah Waterland 		 * merge is trivial. If the el_ent value is ambiguous (BAD),
10045c51f124SMoriah Waterland 		 * the cf_ent value is inherited. Otherwise, the el_ent value
10055c51f124SMoriah Waterland 		 * is preserved.
10065c51f124SMoriah Waterland 		 */
10075c51f124SMoriah Waterland 		if (cf_ent->ainfo.major != el_ent->cf_ent.ainfo.major) {
10085c51f124SMoriah Waterland 			changed++;
10095c51f124SMoriah Waterland 			if (el_ent->cf_ent.ainfo.major == BADMAJOR) {
10105c51f124SMoriah Waterland 				el_ent->cf_ent.ainfo.major =
10115c51f124SMoriah Waterland 				    cf_ent->ainfo.major;
10125c51f124SMoriah Waterland 			} else {
10135c51f124SMoriah Waterland 				el_ent->mstat.contchg = 1;
10145c51f124SMoriah Waterland 			}
10155c51f124SMoriah Waterland 		}
10165c51f124SMoriah Waterland 		if (cf_ent->ainfo.minor != el_ent->cf_ent.ainfo.minor) {
10175c51f124SMoriah Waterland 			changed++;
10185c51f124SMoriah Waterland 			if (el_ent->cf_ent.ainfo.minor == BADMINOR)
10195c51f124SMoriah Waterland 				el_ent->cf_ent.ainfo.minor =
10205c51f124SMoriah Waterland 				    cf_ent->ainfo.minor;
10215c51f124SMoriah Waterland 			else
10225c51f124SMoriah Waterland 				el_ent->mstat.contchg = 1;
10235c51f124SMoriah Waterland 		}
10245c51f124SMoriah Waterland 	}
10255c51f124SMoriah Waterland 
10265c51f124SMoriah Waterland 	/*
10275c51f124SMoriah Waterland 	 * For mode, owner and group follow the same rules as above - if
10285c51f124SMoriah Waterland 	 * ambiguous, inherit, otherwise keep the new one.
10295c51f124SMoriah Waterland 	 */
10305c51f124SMoriah Waterland 	if (cf_ent->ainfo.mode != el_ent->cf_ent.ainfo.mode) {
10315c51f124SMoriah Waterland 		changed++;  /* attribute info is changing */
10325c51f124SMoriah Waterland 		if (el_ent->cf_ent.ainfo.mode == BADMODE) {
10335c51f124SMoriah Waterland 			el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode;
10345c51f124SMoriah Waterland 		} else if (el_ent->cf_ent.ainfo.mode == WILDCARD) {
10355c51f124SMoriah Waterland 			/*
10365c51f124SMoriah Waterland 			 * If pkgmap has a '?' set for mode, use the mode from
10375c51f124SMoriah Waterland 			 * the pkg DB (contents file).
10385c51f124SMoriah Waterland 			 */
10395c51f124SMoriah Waterland 			el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode;
10405c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 0;
10415c51f124SMoriah Waterland 		} else {
10425c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 1;
10435c51f124SMoriah Waterland 		}
10445c51f124SMoriah Waterland 	}
10455c51f124SMoriah Waterland 	if (strcmp(cf_ent->ainfo.owner, el_ent->cf_ent.ainfo.owner) != 0) {
10465c51f124SMoriah Waterland 		changed++;  /* attribute info is changing */
10475c51f124SMoriah Waterland 		if (strcmp(el_ent->cf_ent.ainfo.owner, BADOWNER) == 0)
10485c51f124SMoriah Waterland 			(void) strcpy(el_ent->cf_ent.ainfo.owner,
10495c51f124SMoriah Waterland 			    cf_ent->ainfo.owner);
10505c51f124SMoriah Waterland 		else
10515c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 1;
10525c51f124SMoriah Waterland 	}
10535c51f124SMoriah Waterland 	if (strcmp(cf_ent->ainfo.group, el_ent->cf_ent.ainfo.group) != 0) {
10545c51f124SMoriah Waterland 		changed++;  /* attribute info is changing */
10555c51f124SMoriah Waterland 		if (strcmp(el_ent->cf_ent.ainfo.group, BADGROUP) == 0)
10565c51f124SMoriah Waterland 			(void) strcpy(el_ent->cf_ent.ainfo.group,
10575c51f124SMoriah Waterland 			    cf_ent->ainfo.group);
10585c51f124SMoriah Waterland 		else
10595c51f124SMoriah Waterland 			el_ent->mstat.attrchg = 1;
10605c51f124SMoriah Waterland 	}
10615c51f124SMoriah Waterland 	return (changed ? MRG_DIFFERENT : MRG_SAME);
10625c51f124SMoriah Waterland }
10635c51f124SMoriah Waterland 
10645c51f124SMoriah Waterland /*
10655c51f124SMoriah Waterland  * This puts the current entry into the package database in the appropriate
10665c51f124SMoriah Waterland  * intermediate format for this stage of the installation. This also assures
10675c51f124SMoriah Waterland  * the correct format for the various package object ftypes, stripping the
10685c51f124SMoriah Waterland  * link name before storing a regular file and stuff like that.
10695c51f124SMoriah Waterland  */
10705c51f124SMoriah Waterland 
10715c51f124SMoriah Waterland static void
10725c51f124SMoriah Waterland output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo)
10735c51f124SMoriah Waterland {
10745c51f124SMoriah Waterland 	short	svvolno;
10755c51f124SMoriah Waterland 	char	*svpt;
10765c51f124SMoriah Waterland 
10775c51f124SMoriah Waterland 	/* output without volume information */
10785c51f124SMoriah Waterland 	svvolno = ent->volno;
10795c51f124SMoriah Waterland 	ent->volno = 0;
10805c51f124SMoriah Waterland 
10815c51f124SMoriah Waterland 	pinfo->editflag = 0;
10825c51f124SMoriah Waterland 	if (((ent->ftype == 's') || (ent->ftype == 'l'))) {
10835c51f124SMoriah Waterland 		if (putcvfpfile(ent, vfpo)) {
10845c51f124SMoriah Waterland 			progerr(gettext(ERR_OUTPUT));
10855c51f124SMoriah Waterland 			quit(99);
10865c51f124SMoriah Waterland 		}
10875c51f124SMoriah Waterland 	} else {
10885c51f124SMoriah Waterland 
10895c51f124SMoriah Waterland 		/* output without local pathname */
10905c51f124SMoriah Waterland 		svpt = ent->ainfo.local;
10915c51f124SMoriah Waterland 		ent->ainfo.local = NULL;
10925c51f124SMoriah Waterland 		if (putcvfpfile(ent, vfpo)) {
10935c51f124SMoriah Waterland 			progerr(gettext(ERR_OUTPUT));
10945c51f124SMoriah Waterland 			quit(99);
10955c51f124SMoriah Waterland 		}
10965c51f124SMoriah Waterland 
10975c51f124SMoriah Waterland 		ent->ainfo.local = svpt;
10985c51f124SMoriah Waterland 		/*
10995c51f124SMoriah Waterland 		 * If this entry represents a file which is being edited, we
11005c51f124SMoriah Waterland 		 * need to store in memory the fact that it is an edittable
11015c51f124SMoriah Waterland 		 * file so that when we audit it after installation we do not
11025c51f124SMoriah Waterland 		 * worry about its contents; we do this by resetting the ftype
11035c51f124SMoriah Waterland 		 * to 'e' in the memory array which is later used to control
11045c51f124SMoriah Waterland 		 * the audit
11055c51f124SMoriah Waterland 		 */
11065c51f124SMoriah Waterland 		if (pinfo->editflag)
11075c51f124SMoriah Waterland 			ent->ftype = 'e';
11085c51f124SMoriah Waterland 	}
11095c51f124SMoriah Waterland 	/* restore volume information */
11105c51f124SMoriah Waterland 	ent->volno = svvolno;
11115c51f124SMoriah Waterland }
11125c51f124SMoriah Waterland 
11135c51f124SMoriah Waterland static void
11145c51f124SMoriah Waterland chgclass(struct cfent *cf_ent, struct pinfo *pinfo)
11155c51f124SMoriah Waterland {
11165c51f124SMoriah Waterland 	struct pinfo *pp;
11175c51f124SMoriah Waterland 	char	*oldclass, newclass[CLSSIZ+1];
11185c51f124SMoriah Waterland 	int	newcnt, oldcnt;
11195c51f124SMoriah Waterland 
11205c51f124SMoriah Waterland 	/*
11215c51f124SMoriah Waterland 	 * we use this routine to minimize the use of the aclass element by
11225c51f124SMoriah Waterland 	 * optimizing the use of the cf_ent->pkg_class element
11235c51f124SMoriah Waterland 	 */
11245c51f124SMoriah Waterland 
11255c51f124SMoriah Waterland 	(void) strlcpy(newclass, pinfo->aclass, sizeof (newclass));
11265c51f124SMoriah Waterland 	newcnt = 1;
11275c51f124SMoriah Waterland 
11285c51f124SMoriah Waterland 	oldclass = cf_ent->pkg_class;
11295c51f124SMoriah Waterland 	oldcnt = 0;
11305c51f124SMoriah Waterland 
11315c51f124SMoriah Waterland 	/*
11325c51f124SMoriah Waterland 	 * count the number of times the newclass will be used and see if it
11335c51f124SMoriah Waterland 	 * exceeds the number of times the oldclass is referenced
11345c51f124SMoriah Waterland 	 */
11355c51f124SMoriah Waterland 	pp = cf_ent->pinfo;
11365c51f124SMoriah Waterland 	while (pp) {
11375c51f124SMoriah Waterland 		if (pp->aclass[0] != '\0') {
11385c51f124SMoriah Waterland 			if (strcmp(pp->aclass, newclass) == 0)
11395c51f124SMoriah Waterland 				newcnt++;
11405c51f124SMoriah Waterland 			else if (strcmp(pp->aclass, oldclass) == 0)
11415c51f124SMoriah Waterland 				oldcnt++;
11425c51f124SMoriah Waterland 		}
11435c51f124SMoriah Waterland 		pp = pp->next;
11445c51f124SMoriah Waterland 	}
11455c51f124SMoriah Waterland 	if (newcnt > oldcnt) {
11465c51f124SMoriah Waterland 		pp = cf_ent->pinfo;
11475c51f124SMoriah Waterland 		while (pp) {
11485c51f124SMoriah Waterland 			if (pp->aclass[0] == '\0') {
11495c51f124SMoriah Waterland 				(void) strcpy(pp->aclass, oldclass);
11505c51f124SMoriah Waterland 			} else if (strcmp(pp->aclass, newclass) == 0) {
11515c51f124SMoriah Waterland 				pp->aclass[0] = '\0';
11525c51f124SMoriah Waterland 			}
11535c51f124SMoriah Waterland 			pp = pp->next;
11545c51f124SMoriah Waterland 		}
11555c51f124SMoriah Waterland 		(void) strcpy(cf_ent->pkg_class, newclass);
11565c51f124SMoriah Waterland 	}
11575c51f124SMoriah Waterland }
1158