xref: /titanic_52/usr/src/cmd/svr4pkg/pkgremove/main.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 <limits.h>
335c51f124SMoriah Waterland #include <stdlib.h>
345c51f124SMoriah Waterland #include <unistd.h>
355c51f124SMoriah Waterland #include <string.h>
365c51f124SMoriah Waterland #include <signal.h>
375c51f124SMoriah Waterland #include <errno.h>
385c51f124SMoriah Waterland #include <fcntl.h>
395c51f124SMoriah Waterland #include <sys/stat.h>
405c51f124SMoriah Waterland #include <sys/types.h>
415c51f124SMoriah Waterland #include <pkgstrct.h>
425c51f124SMoriah Waterland #include <pkginfo.h>
435c51f124SMoriah Waterland #include <pkglocs.h>
445c51f124SMoriah Waterland #include <locale.h>
455c51f124SMoriah Waterland #include <libintl.h>
465c51f124SMoriah Waterland #include <assert.h>
475c51f124SMoriah Waterland #include <cfext.h>
485c51f124SMoriah Waterland #include <instzones_api.h>
495c51f124SMoriah Waterland #include <pkglib.h>
505c51f124SMoriah Waterland #include <install.h>
515c51f124SMoriah Waterland #include <libinst.h>
525c51f124SMoriah Waterland #include <libadm.h>
535c51f124SMoriah Waterland #include <messages.h>
545c51f124SMoriah Waterland 
555c51f124SMoriah Waterland struct cfent **eptlist;
565c51f124SMoriah Waterland extern int	eptnum;
575c51f124SMoriah Waterland 
585c51f124SMoriah Waterland extern char	*pkgdir;
595c51f124SMoriah Waterland extern char	**environ;
605c51f124SMoriah Waterland 
615c51f124SMoriah Waterland /* quit.c */
625c51f124SMoriah Waterland extern sighdlrFunc_t	*quitGetTrapHandler(void);
635c51f124SMoriah Waterland extern void		quitSetSilentExit(boolean_t a_silentExit);
645c51f124SMoriah Waterland extern void		quitSetZoneName(char *a_zoneName);
655c51f124SMoriah Waterland 
665c51f124SMoriah Waterland 
675c51f124SMoriah Waterland 
685c51f124SMoriah Waterland /* check.c */
695c51f124SMoriah Waterland extern void	rcksetPreremoveCheck(boolean_t);
705c51f124SMoriah Waterland extern void	rcksetZoneName(char *);
715c51f124SMoriah Waterland extern int	rckpriv(void);
725c51f124SMoriah Waterland extern int	rckdepend(void);
735c51f124SMoriah Waterland extern int	rckrunlevel(void);
745c51f124SMoriah Waterland 
755c51f124SMoriah Waterland /* predepend.c */
765c51f124SMoriah Waterland extern void	predepend(char *oldpkg);
775c51f124SMoriah Waterland 
785c51f124SMoriah Waterland /* delmap.c */
79*62224350SCasper H.S. Dik extern int delmap(int flag, char *pkginst, PKGserver *server, VFP_T **tfp);
805c51f124SMoriah Waterland 
815c51f124SMoriah Waterland #define	DEFPATH		"/sbin:/usr/sbin:/usr/bin"
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland #ifdef	ALLOW_EXCEPTION_PKG_LIST
845c51f124SMoriah Waterland #define	SCRIPT	0	/* Tells exception_pkg() which pkg list to use */
855c51f124SMoriah Waterland #define	LINK	1
865c51f124SMoriah Waterland #endif
875c51f124SMoriah Waterland 
885c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
895c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
905c51f124SMoriah Waterland #endif
915c51f124SMoriah Waterland 
925c51f124SMoriah Waterland /* This is the text for the "-O inherited-filesystem=" option */
935c51f124SMoriah Waterland 
945c51f124SMoriah Waterland #define	INHERITFS	"inherited-filesystem="
955c51f124SMoriah Waterland #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
965c51f124SMoriah Waterland 
975c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-name=" option */
985c51f124SMoriah Waterland 
995c51f124SMoriah Waterland #define	PARENTZONENAME	"parent-zone-name="
1005c51f124SMoriah Waterland #define	PARENTZONENAME_LEN	((sizeof (PARENTZONENAME))-1)
1015c51f124SMoriah Waterland 
1025c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-type=" option */
1035c51f124SMoriah Waterland 
1045c51f124SMoriah Waterland #define	PARENTZONETYPE	"parent-zone-type="
1055c51f124SMoriah Waterland #define	PARENTZONETYPE_LEN	((sizeof (PARENTZONETYPE))-1)
1065c51f124SMoriah Waterland 
1075c51f124SMoriah Waterland struct	admin adm; 	/* holds info about installation admin */
1085c51f124SMoriah Waterland int	dreboot; 	/* non-zero if reboot required after installation */
1095c51f124SMoriah Waterland int	ireboot;	/* non-zero if immediate reboot required */
1105c51f124SMoriah Waterland int	failflag;	/* non-zero if fatal error has occurred */
1115c51f124SMoriah Waterland int	warnflag;	/* non-zero if non-fatal error has occurred */
1125c51f124SMoriah Waterland int	pkgverbose;	/* non-zero if verbose mode is selected */
1135c51f124SMoriah Waterland int	started;
1145c51f124SMoriah Waterland int	nocnflct = 0; 	/* pkgdbmerg needs this defined */
1155c51f124SMoriah Waterland int	nosetuid = 0; 	/* pkgdbmerg needs this defined */
1165c51f124SMoriah Waterland 
1175c51f124SMoriah Waterland char	*pkginst; 	/* current package (source) instance to process */
1185c51f124SMoriah Waterland 
1195c51f124SMoriah Waterland int	dbchg;
1205c51f124SMoriah Waterland char	*msgtext;
1215c51f124SMoriah Waterland char	pkgloc[PATH_MAX];
1225c51f124SMoriah Waterland 
1235c51f124SMoriah Waterland /*
1245c51f124SMoriah Waterland  * The following variable is the name of the device to which stdin
1255c51f124SMoriah Waterland  * is connected during execution of a procedure script. /dev/null is
1265c51f124SMoriah Waterland  * correct for all ABI compliant packages. For non-ABI-compliant
1275c51f124SMoriah Waterland  * packages, the '-o' command line switch changes this to /dev/tty
1285c51f124SMoriah Waterland  * to allow user interaction during these scripts. -- JST
1295c51f124SMoriah Waterland  */
1305c51f124SMoriah Waterland static char 	*script_in = PROC_STDIN;	/* assume ABI compliance */
1315c51f124SMoriah Waterland 
1325c51f124SMoriah Waterland static char	*client_mntdir; 	/* mount point for client's basedir */
1335c51f124SMoriah Waterland static char	pkgbin[PATH_MAX],
1345c51f124SMoriah Waterland 		rlockfile[PATH_MAX],
1355c51f124SMoriah Waterland 		*admnfile, 		/* file to use for installation admin */
1365c51f124SMoriah Waterland 		*tmpdir; 		/* location to place temporary files */
1375c51f124SMoriah Waterland 
1385c51f124SMoriah Waterland static boolean_t	path_valid(char *path);
1395c51f124SMoriah Waterland static void		ckreturn(int retcode, char *msg);
1405c51f124SMoriah Waterland static void		rmclass(char *aclass, int rm_remote, char *a_zoneName);
1415c51f124SMoriah Waterland static void		usage(void);
1425c51f124SMoriah Waterland 
1435c51f124SMoriah Waterland /*
1445c51f124SMoriah Waterland  * Set by -O debug: debug output is enabled?
1455c51f124SMoriah Waterland  */
1465c51f124SMoriah Waterland static boolean_t	debugFlag = B_FALSE;
1475c51f124SMoriah Waterland 
1485c51f124SMoriah Waterland /*
1495c51f124SMoriah Waterland  * Set by -O preremovecheck: do remove dependency checking only
1505c51f124SMoriah Waterland  */
1515c51f124SMoriah Waterland static boolean_t	preremoveCheck = B_FALSE;
1525c51f124SMoriah Waterland 
1535c51f124SMoriah Waterland /* Set by -O parent-zone-name= */
1545c51f124SMoriah Waterland 
1555c51f124SMoriah Waterland static char		*parentZoneName = (char *)NULL;
1565c51f124SMoriah Waterland 
1575c51f124SMoriah Waterland /* Set by -O parent-zone-type= */
1585c51f124SMoriah Waterland 
1595c51f124SMoriah Waterland static char		*parentZoneType = (char *)NULL;
1605c51f124SMoriah Waterland 
1615c51f124SMoriah Waterland static int	nointeract;	/* != 0 no interaction with user should occur */
1625c51f124SMoriah Waterland 
1635c51f124SMoriah Waterland 
1645c51f124SMoriah Waterland 
1655c51f124SMoriah Waterland int
1665c51f124SMoriah Waterland main(int argc, char *argv[])
1675c51f124SMoriah Waterland {
1685c51f124SMoriah Waterland 	FILE		*fp;
1695c51f124SMoriah Waterland 	char		*abi_comp_ptr;
1705c51f124SMoriah Waterland 	char		*abi_sym_ptr;
1715c51f124SMoriah Waterland 	char		*p;
1725c51f124SMoriah Waterland 	char		*prog_full_name = NULL;
1735c51f124SMoriah Waterland 	char		*pt;
1745c51f124SMoriah Waterland 	char		*value;
1755c51f124SMoriah Waterland 	char		*vfstab_file = NULL;
1765c51f124SMoriah Waterland 	char		*zoneName = (char *)NULL;
1775c51f124SMoriah Waterland 	char		cmdbin[PATH_MAX];
1785c51f124SMoriah Waterland 	char		param[MAX_PKG_PARAM_LENGTH];
1795c51f124SMoriah Waterland 	char		path[PATH_MAX];
1805c51f124SMoriah Waterland 	char		script[PATH_MAX];
1815c51f124SMoriah Waterland 	int		c;
1825c51f124SMoriah Waterland 	int		err;
1835c51f124SMoriah Waterland 	int		fd;
1845c51f124SMoriah Waterland 	int		i;
1855c51f124SMoriah Waterland 	int		map_client = 1;
1865c51f124SMoriah Waterland 	int		n;
1875c51f124SMoriah Waterland 	int		nodelete = 0; 	/* do not delete file or run scripts */
1885c51f124SMoriah Waterland 	int		pkgrmremote = 0;	/* dont remove remote objects */
1895c51f124SMoriah Waterland 	struct sigaction	nact;
1905c51f124SMoriah Waterland 	struct sigaction	oact;
191*62224350SCasper H.S. Dik 	PKGserver	pkgserver = NULL;
192*62224350SCasper H.S. Dik 	VFP_T		*tmpfp;
1935c51f124SMoriah Waterland 
1945c51f124SMoriah Waterland 	/* reset contents of all default paths */
1955c51f124SMoriah Waterland 
1965c51f124SMoriah Waterland 	(void) memset(cmdbin, '\0', sizeof (cmdbin));
1975c51f124SMoriah Waterland 
1985c51f124SMoriah Waterland 	/* initialize locale environment */
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
2015c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
2025c51f124SMoriah Waterland 
2035c51f124SMoriah Waterland 	/* initialize program name */
2045c51f124SMoriah Waterland 
2055c51f124SMoriah Waterland 	prog_full_name = argv[0];
2065c51f124SMoriah Waterland 	(void) set_prog_name(argv[0]);
2075c51f124SMoriah Waterland 
2085c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
2095c51f124SMoriah Waterland 
2105c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
2115c51f124SMoriah Waterland 
2125c51f124SMoriah Waterland 	/* exit if not root */
2135c51f124SMoriah Waterland 
2145c51f124SMoriah Waterland 	if (getuid()) {
2155c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, get_prog_name());
2165c51f124SMoriah Waterland 		exit(1);
2175c51f124SMoriah Waterland 		/* NOTREACHED */
2185c51f124SMoriah Waterland 	}
2195c51f124SMoriah Waterland 
2205c51f124SMoriah Waterland 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
2215c51f124SMoriah Waterland 
2225c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
2235c51f124SMoriah Waterland 		progerr(ERR_ROOT_SET);
2245c51f124SMoriah Waterland 		exit(1);
2255c51f124SMoriah Waterland 	}
2265c51f124SMoriah Waterland 
227*62224350SCasper H.S. Dik 	pkgserversetmode(DEFAULTMODE);
228*62224350SCasper H.S. Dik 
2295c51f124SMoriah Waterland 	/* parse command line options */
2305c51f124SMoriah Waterland 
2315c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) {
2325c51f124SMoriah Waterland 		switch (c) {
2335c51f124SMoriah Waterland 		/*
2345c51f124SMoriah Waterland 		 * Same as pkgrm: Allow admin to remove package objects from
2355c51f124SMoriah Waterland 		 * a shared area from a reference client.
2365c51f124SMoriah Waterland 		 */
2375c51f124SMoriah Waterland 		case 'A':
2385c51f124SMoriah Waterland 		    pkgrmremote++;
2395c51f124SMoriah Waterland 		    break;
2405c51f124SMoriah Waterland 
2415c51f124SMoriah Waterland 		/*
2425c51f124SMoriah Waterland 		 * Same as pkgrm: Use the installation
2435c51f124SMoriah Waterland 		 * administration file, admin, in place of the
2445c51f124SMoriah Waterland 		 * default admin file. pkgrm first looks in the
2455c51f124SMoriah Waterland 		 * current working directory for the administration
2465c51f124SMoriah Waterland 		 * file.  If the specified administration file is not
2475c51f124SMoriah Waterland 		 * in the current working directory, pkgrm looks in
2485c51f124SMoriah Waterland 		 * the /var/sadm/install/admin directory for the
2495c51f124SMoriah Waterland 		 * administration file.
2505c51f124SMoriah Waterland 		 */
2515c51f124SMoriah Waterland 		case 'a':
2525c51f124SMoriah Waterland 		    admnfile = flex_device(optarg, 0);
2535c51f124SMoriah Waterland 		    break;
2545c51f124SMoriah Waterland 
2555c51f124SMoriah Waterland 		/*
2565c51f124SMoriah Waterland 		 * Same as pkgrm: location where package executables
2575c51f124SMoriah Waterland 		 * can be found - default is /usr/sadm/install/bin.
2585c51f124SMoriah Waterland 		 */
2595c51f124SMoriah Waterland 		case 'b':
2605c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
2615c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
2625c51f124SMoriah Waterland 				exit(1);
2635c51f124SMoriah Waterland 			}
2645c51f124SMoriah Waterland 			if (isdir(optarg) != 0) {
2655c51f124SMoriah Waterland 				char *p = strerror(errno);
2665c51f124SMoriah Waterland 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
2675c51f124SMoriah Waterland 				exit(1);
2685c51f124SMoriah Waterland 			}
2695c51f124SMoriah Waterland 			(void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
2705c51f124SMoriah Waterland 			break;
2715c51f124SMoriah Waterland 
2725c51f124SMoriah Waterland 		/*
2735c51f124SMoriah Waterland 		 * Same as pkgrm: suppresses the removal of any
2745c51f124SMoriah Waterland 		 * files and any class action scripts, and suppresses
2755c51f124SMoriah Waterland 		 * the running of any class action scripts.  The
2765c51f124SMoriah Waterland 		 * package files remain but the package looks like it
2775c51f124SMoriah Waterland 		 * is not installed. This is mainly for use by the
2785c51f124SMoriah Waterland 		 * upgrade process.
2795c51f124SMoriah Waterland 		 */
2805c51f124SMoriah Waterland 		case 'F':
2815c51f124SMoriah Waterland 		    nodelete++;
2825c51f124SMoriah Waterland 		    break;
2835c51f124SMoriah Waterland 
2845c51f124SMoriah Waterland 		/*
2855c51f124SMoriah Waterland 		 * Same as pkgrm: Instruct pkgrm not to use the
2865c51f124SMoriah Waterland 		 * $root_path/etc/vfstab file for determining the
2875c51f124SMoriah Waterland 		 * client's mount points. This option assumes the
2885c51f124SMoriah Waterland 		 * mount points are correct on the server and it
2895c51f124SMoriah Waterland 		 * behaves consistently with Solaris 2.5 and earlier
2905c51f124SMoriah Waterland 		 * releases.
2915c51f124SMoriah Waterland 		 */
2925c51f124SMoriah Waterland 		case 'M':
2935c51f124SMoriah Waterland 		    map_client = 0;
2945c51f124SMoriah Waterland 		    break;
2955c51f124SMoriah Waterland 
2965c51f124SMoriah Waterland 		/*
2975c51f124SMoriah Waterland 		 * Different from pkgrm: specify program name to use
2985c51f124SMoriah Waterland 		 * for messages.
2995c51f124SMoriah Waterland 		 */
3005c51f124SMoriah Waterland 		case 'N':
3015c51f124SMoriah Waterland 		    (void) set_prog_name(optarg);
3025c51f124SMoriah Waterland 		    break;
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland 		/*
3055c51f124SMoriah Waterland 		 * Same as pkgrm: package removal occurs in
3065c51f124SMoriah Waterland 		 * non-interactive mode.  Suppress output of the list of
3075c51f124SMoriah Waterland 		 * removed files. The default mode is interactive.
3085c51f124SMoriah Waterland 		 */
3095c51f124SMoriah Waterland 		case 'n':
3105c51f124SMoriah Waterland 		    nointeract++;
3115c51f124SMoriah Waterland 		    (void) echoSetFlag(B_FALSE);
3125c51f124SMoriah Waterland 		    break;
3135c51f124SMoriah Waterland 
3145c51f124SMoriah Waterland 		/*
3155c51f124SMoriah Waterland 		 * Almost same as pkgrm: the -O option allows the behavior
3165c51f124SMoriah Waterland 		 * of the package tools to be modified. Recognized options:
3175c51f124SMoriah Waterland 		 * -> debug
3185c51f124SMoriah Waterland 		 * ---> enable debugging output
3195c51f124SMoriah Waterland 		 * -> preremovecheck
3205c51f124SMoriah Waterland 		 * ---> perform a "pre removal" check of the specified
3215c51f124SMoriah Waterland 		 * ---> package - suppress all regular output and cause a
3225c51f124SMoriah Waterland 		 * ---> series of one or more "name=value" pair format lines
3235c51f124SMoriah Waterland 		 * ---> to be output that describes the "removability" of
3245c51f124SMoriah Waterland 		 * ---> the specified package
3255c51f124SMoriah Waterland 		 * -> enable-hollow-package-support
3265c51f124SMoriah Waterland 		 * --> Enable hollow package support. When specified, for any
3275c51f124SMoriah Waterland 		 * --> package that has SUNW_PKG_HOLLOW=true:
3285c51f124SMoriah Waterland 		 * --> Do not calculate and verify package size against target
3295c51f124SMoriah Waterland 		 * --> Do not run any package procedure or class action scripts
3305c51f124SMoriah Waterland 		 * --> Do not create or remove any target directories
3315c51f124SMoriah Waterland 		 * --> Do not perform any script locking
3325c51f124SMoriah Waterland 		 * --> Do not install or uninstall any components of any package
3335c51f124SMoriah Waterland 		 * --> Do not output any status or database update messages
3345c51f124SMoriah Waterland 		 */
3355c51f124SMoriah Waterland 		case 'O':
3365c51f124SMoriah Waterland 			for (p = strtok(optarg, ","); p != (char *)NULL;
3375c51f124SMoriah Waterland 				p = strtok(NULL, ",")) {
3385c51f124SMoriah Waterland 
3395c51f124SMoriah Waterland 				/* process debug option */
3405c51f124SMoriah Waterland 
3415c51f124SMoriah Waterland 				if (strcmp(p, "debug") == 0) {
3425c51f124SMoriah Waterland 					/* set debug flag/enable debug output */
3435c51f124SMoriah Waterland 					debugFlag = B_TRUE;
3445c51f124SMoriah Waterland 					(void) echoDebugSetFlag(debugFlag);
3455c51f124SMoriah Waterland 
3465c51f124SMoriah Waterland 					/* debug info on arguments to pkgadd */
3475c51f124SMoriah Waterland 					for (n = 0; n < argc && argv[n]; n++) {
3485c51f124SMoriah Waterland 						echoDebug(DBG_ARG, n, argv[n]);
3495c51f124SMoriah Waterland 					}
3505c51f124SMoriah Waterland 
3515c51f124SMoriah Waterland 					continue;
3525c51f124SMoriah Waterland 				}
3535c51f124SMoriah Waterland 
3545c51f124SMoriah Waterland 				/* process enable-hollow-package-support opt */
3555c51f124SMoriah Waterland 
3565c51f124SMoriah Waterland 				if (strcmp(p,
3575c51f124SMoriah Waterland 					"enable-hollow-package-support") == 0) {
3585c51f124SMoriah Waterland 					set_depend_pkginfo_DB(B_TRUE);
3595c51f124SMoriah Waterland 					continue;
3605c51f124SMoriah Waterland 				}
3615c51f124SMoriah Waterland 
3625c51f124SMoriah Waterland 				/* process inherited-filesystem= option */
3635c51f124SMoriah Waterland 
3645c51f124SMoriah Waterland 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
3655c51f124SMoriah Waterland 					if (z_add_inherited_file_system(
3665c51f124SMoriah Waterland 						p+INHERITFS_LEN) == B_FALSE) {
3675c51f124SMoriah Waterland 						progerr(ERR_NOSUCH_INHERITED,
3685c51f124SMoriah Waterland 							p+INHERITFS_LEN);
3695c51f124SMoriah Waterland 						quit(1);
3705c51f124SMoriah Waterland 						/* NOTREACHED */
3715c51f124SMoriah Waterland 					}
3725c51f124SMoriah Waterland 					continue;
3735c51f124SMoriah Waterland 				}
3745c51f124SMoriah Waterland 
3755c51f124SMoriah Waterland 				/* process preremovecheck option */
3765c51f124SMoriah Waterland 
3775c51f124SMoriah Waterland 				if (strcmp(p, "preremovecheck") == 0) {
3785c51f124SMoriah Waterland 					preremoveCheck = B_TRUE;
3795c51f124SMoriah Waterland 					nointeract++;	/* -n */
3805c51f124SMoriah Waterland 					nodelete++;	/* -F */
3815c51f124SMoriah Waterland 					quitSetSilentExit(B_TRUE);
3825c51f124SMoriah Waterland 					continue;
3835c51f124SMoriah Waterland 				}
3845c51f124SMoriah Waterland 
3855c51f124SMoriah Waterland 				/* process addzonename option */
3865c51f124SMoriah Waterland 
3875c51f124SMoriah Waterland 				if (strcmp(p, "addzonename") == 0) {
3885c51f124SMoriah Waterland 					zoneName = z_get_zonename();
3895c51f124SMoriah Waterland 					quitSetZoneName(zoneName);
3905c51f124SMoriah Waterland 					continue;
3915c51f124SMoriah Waterland 				}
3925c51f124SMoriah Waterland 
3935c51f124SMoriah Waterland 				/* process parent-zone-name option */
3945c51f124SMoriah Waterland 
3955c51f124SMoriah Waterland 				if (strncmp(p, PARENTZONENAME,
3965c51f124SMoriah Waterland 						PARENTZONENAME_LEN) == 0) {
3975c51f124SMoriah Waterland 					parentZoneName = p+PARENTZONENAME_LEN;
3985c51f124SMoriah Waterland 					continue;
3995c51f124SMoriah Waterland 				}
4005c51f124SMoriah Waterland 
4015c51f124SMoriah Waterland 				/* process parent-zone-type option */
4025c51f124SMoriah Waterland 
4035c51f124SMoriah Waterland 				if (strncmp(p, PARENTZONETYPE,
4045c51f124SMoriah Waterland 						PARENTZONETYPE_LEN) == 0) {
4055c51f124SMoriah Waterland 					parentZoneType = p+PARENTZONETYPE_LEN;
4065c51f124SMoriah Waterland 					continue;
4075c51f124SMoriah Waterland 				}
4085c51f124SMoriah Waterland 
409*62224350SCasper H.S. Dik 				if (strncmp(p, PKGSERV_MODE,
410*62224350SCasper H.S. Dik 				    PKGSERV_MODE_LEN) == 0) {
411*62224350SCasper H.S. Dik 					pkgserversetmode(pkgparsemode(p +
412*62224350SCasper H.S. Dik 					    PKGSERV_MODE_LEN));
413*62224350SCasper H.S. Dik 					continue;
414*62224350SCasper H.S. Dik 				}
4155c51f124SMoriah Waterland 				/* option not recognized - issue warning */
4165c51f124SMoriah Waterland 
4175c51f124SMoriah Waterland 				progerr(ERR_INVALID_O_OPTION, p);
4185c51f124SMoriah Waterland 				continue;
4195c51f124SMoriah Waterland 			}
4205c51f124SMoriah Waterland 			break;
4215c51f124SMoriah Waterland 
4225c51f124SMoriah Waterland 		/*
4235c51f124SMoriah Waterland 		 * Different from pkgrm: This is an old non-ABI package
4245c51f124SMoriah Waterland 		 */
4255c51f124SMoriah Waterland 
4265c51f124SMoriah Waterland 		case 'o':
4275c51f124SMoriah Waterland 		    script_in = PROC_XSTDIN;
4285c51f124SMoriah Waterland 		    break;
4295c51f124SMoriah Waterland 
4305c51f124SMoriah Waterland 		/*
4315c51f124SMoriah Waterland 		 * Same as pkgrm: defines the full path name of a
4325c51f124SMoriah Waterland 		 * directory to use as the root_path.  All files,
4335c51f124SMoriah Waterland 		 * including package system information files, are
4345c51f124SMoriah Waterland 		 * relocated to a directory tree starting in the
4355c51f124SMoriah Waterland 		 * specified root_path.
4365c51f124SMoriah Waterland 		 */
4375c51f124SMoriah Waterland 		case 'R':
4385c51f124SMoriah Waterland 		    if (!set_inst_root(optarg)) {
4395c51f124SMoriah Waterland 			    progerr(ERR_ROOT_CMD);
4405c51f124SMoriah Waterland 			    exit(1);
4415c51f124SMoriah Waterland 		    }
4425c51f124SMoriah Waterland 		    break;
4435c51f124SMoriah Waterland 
4445c51f124SMoriah Waterland 		/*
4455c51f124SMoriah Waterland 		 * Same as pkgrm: allow admin to establish the client
4465c51f124SMoriah Waterland 		 * filesystem using a vfstab-like file of stable format.
4475c51f124SMoriah Waterland 		 */
4485c51f124SMoriah Waterland 		case 'V':
4495c51f124SMoriah Waterland 		    vfstab_file = flex_device(optarg, 2);
4505c51f124SMoriah Waterland 		    map_client = 1;
4515c51f124SMoriah Waterland 		    break;
4525c51f124SMoriah Waterland 
4535c51f124SMoriah Waterland 		/*
4545c51f124SMoriah Waterland 		 * Same as pkgrm: trace all of the scripts that
4555c51f124SMoriah Waterland 		 * get executed by pkgrm, located in the
4565c51f124SMoriah Waterland 		 * pkginst/install directory. This option is used for
4575c51f124SMoriah Waterland 		 * debugging the procedural and non-procedural
4585c51f124SMoriah Waterland 		 * scripts.
4595c51f124SMoriah Waterland 		 */
4605c51f124SMoriah Waterland 		case 'v':
4615c51f124SMoriah Waterland 		    pkgverbose++;
4625c51f124SMoriah Waterland 		    break;
4635c51f124SMoriah Waterland 
4645c51f124SMoriah Waterland 		/*
4655c51f124SMoriah Waterland 		 * Different from pkgrm: process this package using
4665c51f124SMoriah Waterland 		 * old non-ABI symlinks
4675c51f124SMoriah Waterland 		 */
4685c51f124SMoriah Waterland 		case 'y':
4695c51f124SMoriah Waterland 		    set_nonABI_symlinks();
4705c51f124SMoriah Waterland 		    break;
4715c51f124SMoriah Waterland 
4725c51f124SMoriah Waterland 		default:
4735c51f124SMoriah Waterland 		    usage();
4745c51f124SMoriah Waterland 		    /*NOTREACHED*/
4755c51f124SMoriah Waterland 		    /*
4765c51f124SMoriah Waterland 		     * Although usage() calls a noreturn function,
4775c51f124SMoriah Waterland 		     * needed to add return (1);  so that main() would
4785c51f124SMoriah Waterland 		     * pass compilation checks. The statement below
4795c51f124SMoriah Waterland    		     * should never be executed.
4805c51f124SMoriah Waterland 		     */
4815c51f124SMoriah Waterland 		    return (1);
4825c51f124SMoriah Waterland 		}
4835c51f124SMoriah Waterland 	}
4845c51f124SMoriah Waterland 
4855c51f124SMoriah Waterland 	/*
4865c51f124SMoriah Waterland 	 * ********************************************************************
4875c51f124SMoriah Waterland 	 * validate command line options
4885c51f124SMoriah Waterland 	 * ********************************************************************
4895c51f124SMoriah Waterland 	 */
4905c51f124SMoriah Waterland 
4915c51f124SMoriah Waterland 	(void) echoDebugSetFlag(debugFlag);
4925c51f124SMoriah Waterland 	(void) log_set_verbose(debugFlag);
4935c51f124SMoriah Waterland 
4945c51f124SMoriah Waterland 	if (z_running_in_global_zone()) {
4955c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
4965c51f124SMoriah Waterland 	} else {
4975c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
4985c51f124SMoriah Waterland 			z_get_zonename());
4995c51f124SMoriah Waterland 	}
5005c51f124SMoriah Waterland 
5015c51f124SMoriah Waterland 	/* establish cmdbin path */
5025c51f124SMoriah Waterland 
5035c51f124SMoriah Waterland 	if (cmdbin[0] == '\0') {
5045c51f124SMoriah Waterland 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
5055c51f124SMoriah Waterland 	}
5065c51f124SMoriah Waterland 
5075c51f124SMoriah Waterland 	/* Read the mount table */
5085c51f124SMoriah Waterland 
5095c51f124SMoriah Waterland 	if (get_mntinfo(map_client, vfstab_file)) {
5105c51f124SMoriah Waterland 		quit(99);
5115c51f124SMoriah Waterland 	}
5125c51f124SMoriah Waterland 
5135c51f124SMoriah Waterland 	/*
5145c51f124SMoriah Waterland 	 * This function defines the standard /var/... directories used later
5155c51f124SMoriah Waterland 	 * to construct the paths to the various databases.
5165c51f124SMoriah Waterland 	 */
5175c51f124SMoriah Waterland 
5185c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
5195c51f124SMoriah Waterland 
5205c51f124SMoriah Waterland 	/*
5215c51f124SMoriah Waterland 	 * If this is being removed from a client whose /var filesystem is
5225c51f124SMoriah Waterland 	 * mounted in some odd way, remap the administrative paths to the
5235c51f124SMoriah Waterland 	 * real filesystem. This could be avoided by simply mounting up the
5245c51f124SMoriah Waterland 	 * client now; but we aren't yet to the point in the process where
5255c51f124SMoriah Waterland 	 * modification of the filesystem is permitted.
5265c51f124SMoriah Waterland 	 */
5275c51f124SMoriah Waterland 	if (is_an_inst_root()) {
5285c51f124SMoriah Waterland 		int fsys_value;
5295c51f124SMoriah Waterland 
5305c51f124SMoriah Waterland 		fsys_value = fsys(get_PKGLOC());
5315c51f124SMoriah Waterland 		if (use_srvr_map_n(fsys_value))
5325c51f124SMoriah Waterland 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
5335c51f124SMoriah Waterland 
5345c51f124SMoriah Waterland 		fsys_value = fsys(get_PKGADM());
5355c51f124SMoriah Waterland 		if (use_srvr_map_n(fsys_value))
5365c51f124SMoriah Waterland 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
5375c51f124SMoriah Waterland 	} else {
5385c51f124SMoriah Waterland 		pkgrmremote = 0;	/* Makes no sense on local host. */
5395c51f124SMoriah Waterland 	}
5405c51f124SMoriah Waterland 
5415c51f124SMoriah Waterland 	/*
5425c51f124SMoriah Waterland 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
5435c51f124SMoriah Waterland 	 */
5445c51f124SMoriah Waterland 
5455c51f124SMoriah Waterland 	/* hold SIGINT/SIGHUP interrupts */
5465c51f124SMoriah Waterland 
5475c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
5485c51f124SMoriah Waterland 	(void) sighold(SIGINT);
5495c51f124SMoriah Waterland 
5505c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGINT */
5515c51f124SMoriah Waterland 
5525c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
5535c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
5545c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
5555c51f124SMoriah Waterland 
5565c51f124SMoriah Waterland 	(void) sigaction(SIGINT, &nact, &oact);
5575c51f124SMoriah Waterland 
5585c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGHUP */
5595c51f124SMoriah Waterland 
5605c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
5615c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
5625c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
5635c51f124SMoriah Waterland 
5645c51f124SMoriah Waterland 	(void) sigaction(SIGHUP, &nact, &oact);
5655c51f124SMoriah Waterland 
5665c51f124SMoriah Waterland 	/* release hold on signals */
5675c51f124SMoriah Waterland 
5685c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
5695c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
5705c51f124SMoriah Waterland 
5715c51f124SMoriah Waterland 	pkginst = argv[optind++];
5725c51f124SMoriah Waterland 	if (optind != argc) {
5735c51f124SMoriah Waterland 		usage();
5745c51f124SMoriah Waterland 	}
5755c51f124SMoriah Waterland 
5765c51f124SMoriah Waterland 	/* validate package software database (contents) file */
5775c51f124SMoriah Waterland 
5785c51f124SMoriah Waterland 	if (vcfile() == 0) {
5795c51f124SMoriah Waterland 		quit(99);
5805c51f124SMoriah Waterland 	}
5815c51f124SMoriah Waterland 
5825c51f124SMoriah Waterland 	/*
5835c51f124SMoriah Waterland 	 * Acquire the package lock - currently at "remove initialization"
5845c51f124SMoriah Waterland 	 */
5855c51f124SMoriah Waterland 
5865c51f124SMoriah Waterland 	if (!lockinst(get_prog_name(), pkginst, "remove-initial")) {
5875c51f124SMoriah Waterland 		quit(99);
5885c51f124SMoriah Waterland 	}
5895c51f124SMoriah Waterland 
5905c51f124SMoriah Waterland 	/* establish temporary directory to use */
5915c51f124SMoriah Waterland 
5925c51f124SMoriah Waterland 	tmpdir = getenv("TMPDIR");
5935c51f124SMoriah Waterland 	if (tmpdir == NULL) {
5945c51f124SMoriah Waterland 		tmpdir = P_tmpdir;
5955c51f124SMoriah Waterland 	}
5965c51f124SMoriah Waterland 
5975c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir);
5985c51f124SMoriah Waterland 
5995c51f124SMoriah Waterland 	/*
6005c51f124SMoriah Waterland 	 * Initialize installation admin parameters by reading
6015c51f124SMoriah Waterland 	 * the adminfile.
6025c51f124SMoriah Waterland 	 */
6035c51f124SMoriah Waterland 
6045c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : "");
6055c51f124SMoriah Waterland 	setadminFile(admnfile);
6065c51f124SMoriah Waterland 
6075c51f124SMoriah Waterland 	/*
6085c51f124SMoriah Waterland 	 * about to perform first operation that could be modified by the
6095c51f124SMoriah Waterland 	 * preremove check option - if preremove check is selected (that is,
6105c51f124SMoriah Waterland 	 * only gathering dependencies), then output a debug message to
6115c51f124SMoriah Waterland 	 * indicate that the check is beginning. Also turn echo() output
6125c51f124SMoriah Waterland 	 * off and set various other flags.
6135c51f124SMoriah Waterland 	 */
6145c51f124SMoriah Waterland 
6155c51f124SMoriah Waterland 	if (preremoveCheck == B_TRUE) {
6165c51f124SMoriah Waterland 		(void) echoSetFlag(B_FALSE);
6175c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "",
6185c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
6195c51f124SMoriah Waterland 		rcksetPreremoveCheck(B_TRUE);
6205c51f124SMoriah Waterland 		rcksetZoneName(zoneName);
6215c51f124SMoriah Waterland 	}
6225c51f124SMoriah Waterland 
6235c51f124SMoriah Waterland 	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(),
6245c51f124SMoriah Waterland 			pkginst);
6255c51f124SMoriah Waterland 	(void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc);
6265c51f124SMoriah Waterland 	(void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc);
6275c51f124SMoriah Waterland 
6285c51f124SMoriah Waterland 	if (chdir(pkgbin)) {
6295c51f124SMoriah Waterland 		progerr(ERR_CHDIR, pkgbin);
6305c51f124SMoriah Waterland 		quit(99);
6315c51f124SMoriah Waterland 	}
6325c51f124SMoriah Waterland 
6335c51f124SMoriah Waterland 	echo(MSG_PREREMOVE_REMINST, pkginst);
6345c51f124SMoriah Waterland 
6355c51f124SMoriah Waterland 	/*
6365c51f124SMoriah Waterland 	 * if a lock file is present, then a previous attempt to remove this
6375c51f124SMoriah Waterland 	 * package may have been unsuccessful.
6385c51f124SMoriah Waterland 	 */
6395c51f124SMoriah Waterland 
6405c51f124SMoriah Waterland 	if (access(rlockfile, F_OK) == 0) {
6415c51f124SMoriah Waterland 		echo(ERR_UNSUCC);
6425c51f124SMoriah Waterland 		echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile,
6435c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
6445c51f124SMoriah Waterland 	}
6455c51f124SMoriah Waterland 
6465c51f124SMoriah Waterland 	/*
6475c51f124SMoriah Waterland 	 * Process all parameters from the pkginfo file
6485c51f124SMoriah Waterland 	 * and place them in the execution environment
6495c51f124SMoriah Waterland 	 */
6505c51f124SMoriah Waterland 
6515c51f124SMoriah Waterland 	/* Add DB retreival of the pkginfo parameters here */
6525c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc);
6535c51f124SMoriah Waterland 	if ((fp = fopen(path, "r")) == NULL) {
6545c51f124SMoriah Waterland 		progerr(ERR_PKGINFO, path);
6555c51f124SMoriah Waterland 		quit(99);
6565c51f124SMoriah Waterland 	}
6575c51f124SMoriah Waterland 
6585c51f124SMoriah Waterland 	/* Mount up the client if necessary. */
6595c51f124SMoriah Waterland 	if (map_client && !mount_client()) {
6605c51f124SMoriah Waterland 		logerr(MSG_MANMOUNT);
6615c51f124SMoriah Waterland 	}
6625c51f124SMoriah Waterland 
6635c51f124SMoriah Waterland 	/* Get mount point of client */
6645c51f124SMoriah Waterland 	client_mntdir = getenv("CLIENT_MNTDIR");
6655c51f124SMoriah Waterland 
6665c51f124SMoriah Waterland 	getuserlocale();
6675c51f124SMoriah Waterland 
6685c51f124SMoriah Waterland 	/*
6695c51f124SMoriah Waterland 	 * current environment has been read; clear environment out
6705c51f124SMoriah Waterland 	 * so putparam() can be used to populate the new environment
6715c51f124SMoriah Waterland 	 * to be passed to any executables/scripts.
6725c51f124SMoriah Waterland 	 */
6735c51f124SMoriah Waterland 
6745c51f124SMoriah Waterland 	environ = NULL;
6755c51f124SMoriah Waterland 
6765c51f124SMoriah Waterland 	if (nonABI_symlinks()) {
6775c51f124SMoriah Waterland 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
6785c51f124SMoriah Waterland 	}
6795c51f124SMoriah Waterland 
6805c51f124SMoriah Waterland 	/*
6815c51f124SMoriah Waterland 	 * read the pkginfo file and fix any PKGSAV path - the correct
6825c51f124SMoriah Waterland 	 * install_root will be prepended to the existing path.
6835c51f124SMoriah Waterland 	 */
6845c51f124SMoriah Waterland 
6855c51f124SMoriah Waterland 	param[0] = '\0';
6865c51f124SMoriah Waterland 	while (value = fpkgparam(fp, param)) {
6875c51f124SMoriah Waterland 		int validx = 0;
6885c51f124SMoriah Waterland 		char *newvalue;
6895c51f124SMoriah Waterland 
6905c51f124SMoriah Waterland 		/* strip out any setting of PATH */
6915c51f124SMoriah Waterland 
6925c51f124SMoriah Waterland 		if (strcmp(param, "PATH") == 0) {
6935c51f124SMoriah Waterland 			free(value);
6945c51f124SMoriah Waterland 			param[0] = '\0';
6955c51f124SMoriah Waterland 			continue;
6965c51f124SMoriah Waterland 		}
6975c51f124SMoriah Waterland 
6985c51f124SMoriah Waterland 		/* if not PKGSAV then write out unchanged */
6995c51f124SMoriah Waterland 
7005c51f124SMoriah Waterland 		if (strcmp(param, "PKGSAV") != 0) {
7015c51f124SMoriah Waterland 			putparam(param, value);
7025c51f124SMoriah Waterland 			free(value);
7035c51f124SMoriah Waterland 			param[0] = '\0';
7045c51f124SMoriah Waterland 			continue;
7055c51f124SMoriah Waterland 		}
7065c51f124SMoriah Waterland 
7075c51f124SMoriah Waterland 		/*
7085c51f124SMoriah Waterland 		 * PKGSAV parameter found - interpret the directory:
7095c51f124SMoriah Waterland 		 * If in host:path format or marked with the leading "//",
7105c51f124SMoriah Waterland 		 * then there is no client-relative translation - take it
7115c51f124SMoriah Waterland 		 * literally later rather than use fixpath().
7125c51f124SMoriah Waterland 		 */
7135c51f124SMoriah Waterland 
7145c51f124SMoriah Waterland 		if (strstr(value, ":/")) {
7155c51f124SMoriah Waterland 			/* no modification needed */
7165c51f124SMoriah Waterland 			validx = 0;
7175c51f124SMoriah Waterland 		} else if (strstr(value, "//") == value) {
7185c51f124SMoriah Waterland 			validx = 1;
7195c51f124SMoriah Waterland 		} else if (is_an_inst_root()) {
7205c51f124SMoriah Waterland 			/* This PKGSAV needs to be made client-relative. */
7215c51f124SMoriah Waterland 			newvalue = fixpath(value);
7225c51f124SMoriah Waterland 			free(value);
7235c51f124SMoriah Waterland 			value = newvalue;
7245c51f124SMoriah Waterland 		}
7255c51f124SMoriah Waterland 		putparam(param, value+validx);
7265c51f124SMoriah Waterland 		free(value);
7275c51f124SMoriah Waterland 		param[0] = '\0';
7285c51f124SMoriah Waterland 	}
7295c51f124SMoriah Waterland 
7305c51f124SMoriah Waterland 	(void) fclose(fp);
7315c51f124SMoriah Waterland 
7325c51f124SMoriah Waterland 	/* write parent condition information to environment */
7335c51f124SMoriah Waterland 
7345c51f124SMoriah Waterland 	putConditionInfo(parentZoneName, parentZoneType);
7355c51f124SMoriah Waterland 
7365c51f124SMoriah Waterland 	putuserlocale();
7375c51f124SMoriah Waterland 
7385c51f124SMoriah Waterland 	/*
7395c51f124SMoriah Waterland 	 * Now do all the various setups based on ABI compliance
7405c51f124SMoriah Waterland 	 */
7415c51f124SMoriah Waterland 
7425c51f124SMoriah Waterland 	/* Read the environment provided by the pkginfo file */
7435c51f124SMoriah Waterland 	abi_comp_ptr = getenv("NONABI_SCRIPTS");
7445c51f124SMoriah Waterland 
7455c51f124SMoriah Waterland 	/* if not ABI compliant set global flag */
7465c51f124SMoriah Waterland 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
7475c51f124SMoriah Waterland 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
7485c51f124SMoriah Waterland 		set_nonABI_symlinks();
7495c51f124SMoriah Waterland 	}
7505c51f124SMoriah Waterland 
7515c51f124SMoriah Waterland 	/*
7525c51f124SMoriah Waterland 	 * If pkginfo says it's not compliant then set non_abi_scripts.
7535c51f124SMoriah Waterland 	 * Oh, for two releases, set it from exception package names as
7545c51f124SMoriah Waterland 	 * well.
7555c51f124SMoriah Waterland 	 */
7565c51f124SMoriah Waterland 	/*
7575c51f124SMoriah Waterland 	 * *********************************************************************
7585c51f124SMoriah Waterland 	 * this feature is removed starting with Solaris 10 - there is no built
7595c51f124SMoriah Waterland 	 * in list of packages that should be run "the old way"
7605c51f124SMoriah Waterland 	 * *********************************************************************
7615c51f124SMoriah Waterland 	 */
7625c51f124SMoriah Waterland 
7635c51f124SMoriah Waterland #ifdef	ALLOW_EXCEPTION_PKG_LIST
7645c51f124SMoriah Waterland 	if (exception_pkg(pkginst, SCRIPT) ||
7655c51f124SMoriah Waterland 	    (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0))
7665c51f124SMoriah Waterland 		script_in = PROC_XSTDIN;
7675c51f124SMoriah Waterland #else
7685c51f124SMoriah Waterland 	if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) {
7695c51f124SMoriah Waterland 		script_in = PROC_XSTDIN;
7705c51f124SMoriah Waterland 	}
7715c51f124SMoriah Waterland #endif
7725c51f124SMoriah Waterland 	/*
7735c51f124SMoriah Waterland 	 * *********************************************************************
7745c51f124SMoriah Waterland 	 * this feature is removed starting with Solaris 10 - there is no built
7755c51f124SMoriah Waterland 	 * in list of packages that should be run "the old way"
7765c51f124SMoriah Waterland 	 * *********************************************************************
7775c51f124SMoriah Waterland 	 */
7785c51f124SMoriah Waterland 
7795c51f124SMoriah Waterland #ifdef	ALLOW_EXCEPTION_PKG_LIST
7805c51f124SMoriah Waterland 	/* Until 2.9, set it from the execption list */
7815c51f124SMoriah Waterland 	if (exception_pkg(pkginst, LINK)) {
7825c51f124SMoriah Waterland 		set_nonABI_symlinks();
7835c51f124SMoriah Waterland 	}
7845c51f124SMoriah Waterland #endif
7855c51f124SMoriah Waterland 
7865c51f124SMoriah Waterland 	/*
7875c51f124SMoriah Waterland 	 * Since this is a removal, we can tell whether it's absolute or
7885c51f124SMoriah Waterland 	 * not from the resident pkginfo file read above.
7895c51f124SMoriah Waterland 	 */
7905c51f124SMoriah Waterland 	if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir,
7915c51f124SMoriah Waterland 	    pkginst, nointeract)) != 0) {
7925c51f124SMoriah Waterland 		quit(err);
7935c51f124SMoriah Waterland 	}
7945c51f124SMoriah Waterland 
7955c51f124SMoriah Waterland 	/*
7965c51f124SMoriah Waterland 	 * See if were are removing a package that only wants to update
7975c51f124SMoriah Waterland 	 * the database or only remove files associated with CAS's. We
7985c51f124SMoriah Waterland 	 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
7995c51f124SMoriah Waterland 	 * the caller.
8005c51f124SMoriah Waterland 	 */
8015c51f124SMoriah Waterland 
8025c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
8035c51f124SMoriah Waterland 		pt = getenv(PKG_HOLLOW_VARIABLE);
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 		if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
8065c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
8075c51f124SMoriah Waterland 
8085c51f124SMoriah Waterland 			/*
8095c51f124SMoriah Waterland 			 * this is a hollow package and hollow package support
8105c51f124SMoriah Waterland 			 * is enabled -- override admin settings to suppress
8115c51f124SMoriah Waterland 			 * checks that do not make sense since no scripts will
8125c51f124SMoriah Waterland 			 * be executed and no files will be removed.
8135c51f124SMoriah Waterland 			 */
8145c51f124SMoriah Waterland 
8155c51f124SMoriah Waterland 			setadminSetting("conflict", "nocheck");
8165c51f124SMoriah Waterland 			setadminSetting("setuid", "nocheck");
8175c51f124SMoriah Waterland 			setadminSetting("action", "nocheck");
8185c51f124SMoriah Waterland 			setadminSetting("partial", "nocheck");
8195c51f124SMoriah Waterland 			setadminSetting("space", "nocheck");
8205c51f124SMoriah Waterland 			setadminSetting("authentication", "nocheck");
8215c51f124SMoriah Waterland 		} else {
8225c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
8235c51f124SMoriah Waterland 			set_depend_pkginfo_DB(B_FALSE);
8245c51f124SMoriah Waterland 		}
8255c51f124SMoriah Waterland 	}
8265c51f124SMoriah Waterland 
8275c51f124SMoriah Waterland 	put_path_params();
8285c51f124SMoriah Waterland 
8295c51f124SMoriah Waterland 	/* If client mount point, add it to pkgremove environment */
8305c51f124SMoriah Waterland 
8315c51f124SMoriah Waterland 	if (client_mntdir != NULL) {
8325c51f124SMoriah Waterland 		putparam("CLIENT_MNTDIR", client_mntdir);
8335c51f124SMoriah Waterland 	}
8345c51f124SMoriah Waterland 
8355c51f124SMoriah Waterland 	/* Establish the class list and the class attributes. */
8365c51f124SMoriah Waterland 
8375c51f124SMoriah Waterland 	if ((value = getenv("CLASSES")) != NULL) {
8385c51f124SMoriah Waterland 		cl_sets(qstrdup(value));
8395c51f124SMoriah Waterland 	} else {
8405c51f124SMoriah Waterland 		progerr(ERR_CLASSES, path);
8415c51f124SMoriah Waterland 		quit(99);
8425c51f124SMoriah Waterland 	}
8435c51f124SMoriah Waterland 
8445c51f124SMoriah Waterland 	/* establish path and tmpdir */
8455c51f124SMoriah Waterland 
8465c51f124SMoriah Waterland 	if (cmdbin[0] == '\0') {
8475c51f124SMoriah Waterland 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
8485c51f124SMoriah Waterland 	}
8495c51f124SMoriah Waterland 
8505c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
8515c51f124SMoriah Waterland 	putparam("PATH", path);
8525c51f124SMoriah Waterland 
8535c51f124SMoriah Waterland 	putparam("TMPDIR", tmpdir);
8545c51f124SMoriah Waterland 
8555c51f124SMoriah Waterland 	/*
8565c51f124SMoriah Waterland 	 * Check ulimit requirement (provided in pkginfo). The purpose of
8575c51f124SMoriah Waterland 	 * this limit is to terminate pathological file growth resulting from
8585c51f124SMoriah Waterland 	 * file edits in scripts. It does not apply to files in the pkgmap
8595c51f124SMoriah Waterland 	 * and it does not apply to any database files manipulated by the
8605c51f124SMoriah Waterland 	 * installation service.
8615c51f124SMoriah Waterland 	 */
8625c51f124SMoriah Waterland 	if (value = getenv("ULIMIT")) {
8635c51f124SMoriah Waterland 		if (assign_ulimit(value) == -1) {
8645c51f124SMoriah Waterland 			progerr(ERR_BADULIMIT, value);
8655c51f124SMoriah Waterland 			warnflag++;
8665c51f124SMoriah Waterland 		}
8675c51f124SMoriah Waterland 		putparam("PKG_ULIMIT", "TRUE");
8685c51f124SMoriah Waterland 	}
8695c51f124SMoriah Waterland 
8705c51f124SMoriah Waterland 	/*
8715c51f124SMoriah Waterland 	 * If only gathering dependencies, check and output status of all
8725c51f124SMoriah Waterland 	 * remaining dependencies and exit.
8735c51f124SMoriah Waterland 	 */
8745c51f124SMoriah Waterland 
8755c51f124SMoriah Waterland 	if (preremoveCheck == B_TRUE) {
8765c51f124SMoriah Waterland 		/*
8775c51f124SMoriah Waterland 		 * make sure current runlevel is appropriate
8785c51f124SMoriah Waterland 		 */
8795c51f124SMoriah Waterland 
8805c51f124SMoriah Waterland 		(void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel());
8815c51f124SMoriah Waterland 
8825c51f124SMoriah Waterland 		/*
8835c51f124SMoriah Waterland 		 * determine if any packaging scripts provided with
8845c51f124SMoriah Waterland 		 * this package will execute as a priviledged user
8855c51f124SMoriah Waterland 		 */
8865c51f124SMoriah Waterland 
8875c51f124SMoriah Waterland 		(void) fprintf(stdout, "rckpriv=%d\n", rckpriv());
8885c51f124SMoriah Waterland 
8895c51f124SMoriah Waterland 		/*
8905c51f124SMoriah Waterland 		 * verify package dependencies
8915c51f124SMoriah Waterland 		 */
8925c51f124SMoriah Waterland 
8935c51f124SMoriah Waterland 		(void) fprintf(stdout, "rckdepend=%d\n", rckdepend());
8945c51f124SMoriah Waterland 
8955c51f124SMoriah Waterland 		/*
8965c51f124SMoriah Waterland 		 * ****** preremove check done - exit ******
8975c51f124SMoriah Waterland 		 */
8985c51f124SMoriah Waterland 
8995c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PRERMCHK_OK);
9005c51f124SMoriah Waterland 		quit(0);
9015c51f124SMoriah Waterland 		/*NOTREACHED*/
9025c51f124SMoriah Waterland 	}
9035c51f124SMoriah Waterland 
9045c51f124SMoriah Waterland 	/*
9055c51f124SMoriah Waterland 	 * Not gathering dependencies only, proceed to check dependencies
9065c51f124SMoriah Waterland 	 * and continue with the package removal operation.
9075c51f124SMoriah Waterland 	 */
9085c51f124SMoriah Waterland 
9095c51f124SMoriah Waterland 	/*
9105c51f124SMoriah Waterland 	 * make sure current runlevel is appropriate
9115c51f124SMoriah Waterland 	 */
9125c51f124SMoriah Waterland 
9135c51f124SMoriah Waterland 	n = rckrunlevel();
9145c51f124SMoriah Waterland 
9155c51f124SMoriah Waterland 	if (n != 0) {
9165c51f124SMoriah Waterland 		quit(n);
9175c51f124SMoriah Waterland 		/* NOTREACHED */
9185c51f124SMoriah Waterland 	}
9195c51f124SMoriah Waterland 
9205c51f124SMoriah Waterland 	/*
9215c51f124SMoriah Waterland 	 * determine if any packaging scripts provided with
9225c51f124SMoriah Waterland 	 * this package will execute as a priviledged user
9235c51f124SMoriah Waterland 	 */
9245c51f124SMoriah Waterland 
9255c51f124SMoriah Waterland 	n = rckpriv();
9265c51f124SMoriah Waterland 
9275c51f124SMoriah Waterland 	if (n != 0) {
9285c51f124SMoriah Waterland 		quit(n);
9295c51f124SMoriah Waterland 		/* NOTREACHED */
9305c51f124SMoriah Waterland 	}
9315c51f124SMoriah Waterland 
9325c51f124SMoriah Waterland 	/*
9335c51f124SMoriah Waterland 	 * verify package dependencies
9345c51f124SMoriah Waterland 	 */
9355c51f124SMoriah Waterland 	n = rckdepend();
9365c51f124SMoriah Waterland 
9375c51f124SMoriah Waterland 	if (n != 0) {
9385c51f124SMoriah Waterland 		quit(n);
9395c51f124SMoriah Waterland 		/* NOTREACHED */
9405c51f124SMoriah Waterland 	}
9415c51f124SMoriah Waterland 
9425c51f124SMoriah Waterland 	/*
9435c51f124SMoriah Waterland 	 * *********************************************************************
9445c51f124SMoriah Waterland 	 * the actual removal of the package begins here
9455c51f124SMoriah Waterland 	 * *********************************************************************
9465c51f124SMoriah Waterland 	 */
9475c51f124SMoriah Waterland 
9485c51f124SMoriah Waterland 	/*
9495c51f124SMoriah Waterland 	 * create lockfile to indicate start of removal
9505c51f124SMoriah Waterland 	 */
9515c51f124SMoriah Waterland 	started++;
9525c51f124SMoriah Waterland 	if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
9535c51f124SMoriah Waterland 		progerr(ERR_LOCKFILE, rlockfile);
9545c51f124SMoriah Waterland 		quit(99);
9555c51f124SMoriah Waterland 	} else {
9565c51f124SMoriah Waterland 		(void) close(fd);
9575c51f124SMoriah Waterland 	}
9585c51f124SMoriah Waterland 
9595c51f124SMoriah Waterland 	if (zoneName == (char *)NULL) {
9605c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_PROCPKG_GZ);
9615c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile);
9625c51f124SMoriah Waterland 	} else {
9635c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName);
9645c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile,
9655c51f124SMoriah Waterland 			zoneName);
9665c51f124SMoriah Waterland 	}
967*62224350SCasper H.S. Dik 	if (delmap(0, pkginst, &pkgserver, &tmpfp) != 0) {
9685c51f124SMoriah Waterland 		progerr(ERR_DB_QUERY, pkginst);
9695c51f124SMoriah Waterland 		quit(99);
9705c51f124SMoriah Waterland 	}
9715c51f124SMoriah Waterland 
9725c51f124SMoriah Waterland 	/*
9735c51f124SMoriah Waterland 	 * Run a preremove script if one is provided by the package.
9745c51f124SMoriah Waterland 	 * Don't execute preremove script if only updating the DB.
9755c51f124SMoriah Waterland 	 * Don't execute preremove script if files are not being deleted.
9765c51f124SMoriah Waterland 	 * Don't execute preremove script if one or more files reside in
9775c51f124SMoriah Waterland 	 * an inherited FS.
9785c51f124SMoriah Waterland 	 */
9795c51f124SMoriah Waterland 
9805c51f124SMoriah Waterland 	/* update the lock - at the preremove script */
9815c51f124SMoriah Waterland 	lockupd("preremove");
9825c51f124SMoriah Waterland 
9835c51f124SMoriah Waterland 	/* execute preremove script if one is provided */
9845c51f124SMoriah Waterland 	(void) snprintf(script, sizeof (script), "%s/preremove", pkgbin);
9855c51f124SMoriah Waterland 	if (access(script, F_OK) != 0) {
9865c51f124SMoriah Waterland 		/* no script present */
9875c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst,
9885c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
9895c51f124SMoriah Waterland 	} else if (nodelete) {
9905c51f124SMoriah Waterland 		/* not deleting files: skip preremove script */
9915c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script,
9925c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
9935c51f124SMoriah Waterland 	} else if (is_depend_pkginfo_DB()) {
9945c51f124SMoriah Waterland 		/* updating db only: skip preremove script */
9955c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script,
9965c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
9975c51f124SMoriah Waterland 	} else {
9985c51f124SMoriah Waterland 		/* script present and ok to run: run the script */
9995c51f124SMoriah Waterland 		set_ulimit("preremove", ERR_PREREMOVE);
10005c51f124SMoriah Waterland 		if (zoneName == (char *)NULL) {
10015c51f124SMoriah Waterland 			echo(MSG_PKGREMOVE_EXEPOC_GZ);
10025c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script);
10035c51f124SMoriah Waterland 		} else {
10045c51f124SMoriah Waterland 			echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName);
10055c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script,
10065c51f124SMoriah Waterland 				zoneName);
10075c51f124SMoriah Waterland 		}
10085c51f124SMoriah Waterland 		putparam("PKG_PROC_SCRIPT", "preremove");
10095c51f124SMoriah Waterland 		if (pkgverbose) {
10105c51f124SMoriah Waterland 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
10115c51f124SMoriah Waterland 				PROC_USER, PROC_GRP, SHELL, "-x",
10125c51f124SMoriah Waterland 				script, NULL), ERR_PREREMOVE);
10135c51f124SMoriah Waterland 		} else {
10145c51f124SMoriah Waterland 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
10155c51f124SMoriah Waterland 				PROC_USER, PROC_GRP, SHELL, script,
10165c51f124SMoriah Waterland 				NULL), ERR_PREREMOVE);
10175c51f124SMoriah Waterland 		}
10185c51f124SMoriah Waterland 		clr_ulimit();
10195c51f124SMoriah Waterland 	}
10205c51f124SMoriah Waterland 
10215c51f124SMoriah Waterland 	/* update the lock - doing removal */
10225c51f124SMoriah Waterland 
10235c51f124SMoriah Waterland 	lockupd("remove");
10245c51f124SMoriah Waterland 
10255c51f124SMoriah Waterland 	/*
10265c51f124SMoriah Waterland 	 * Ensure that the contents file is updated even if the db has
10275c51f124SMoriah Waterland 	 * been upgraded, in the case that there are relevant entries
10285c51f124SMoriah Waterland 	 * in a special_contents file.  The return value is ignored
10295c51f124SMoriah Waterland 	 * since we do not want special_contents operation to prevent
10305c51f124SMoriah Waterland 	 * pkgremove from succeeding.  We do report errors to stderr.
10315c51f124SMoriah Waterland 	 */
10325c51f124SMoriah Waterland 
10335c51f124SMoriah Waterland 	/*
10345c51f124SMoriah Waterland 	 * Remove all components belonging to this package.
10355c51f124SMoriah Waterland 	 * Don't remove components if only updating the DB.
10365c51f124SMoriah Waterland 	 * Don't remove components if files are not being deleted.
10375c51f124SMoriah Waterland 	 */
10385c51f124SMoriah Waterland 
10395c51f124SMoriah Waterland 	if (nodelete) {
10405c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst,
10415c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10425c51f124SMoriah Waterland 	} else if (is_depend_pkginfo_DB()) {
10435c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst,
10445c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10455c51f124SMoriah Waterland 	} else {
10465c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_REM, pkginst,
10475c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10485c51f124SMoriah Waterland 		/*
10495c51f124SMoriah Waterland 		 * remove package one class at a time
10505c51f124SMoriah Waterland 		 */
10515c51f124SMoriah Waterland 
10525c51f124SMoriah Waterland 		/* reverse order of classes */
10535c51f124SMoriah Waterland 		for (i = cl_getn() - 1; i >= 0; i--) {
10545c51f124SMoriah Waterland 			rmclass(cl_nam(i), pkgrmremote, zoneName);
10555c51f124SMoriah Waterland 		}
10565c51f124SMoriah Waterland 
10575c51f124SMoriah Waterland 		rmclass(NULL, pkgrmremote, zoneName);
10585c51f124SMoriah Waterland 	}
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 	z_destroyMountTable();
10615c51f124SMoriah Waterland 
10625c51f124SMoriah Waterland 	/*
10635c51f124SMoriah Waterland 	 * Execute postremove script, if any
10645c51f124SMoriah Waterland 	 * Don't execute postremove script if only updating the DB.
10655c51f124SMoriah Waterland 	 * Don't execute postremove script if files are not being deleted.
10665c51f124SMoriah Waterland 	 */
10675c51f124SMoriah Waterland 
10685c51f124SMoriah Waterland 	/* update the lock - at the postremove script */
10695c51f124SMoriah Waterland 	lockupd("postremove");
10705c51f124SMoriah Waterland 
10715c51f124SMoriah Waterland 	/* execute postremove script if one is provided */
10725c51f124SMoriah Waterland 	(void) snprintf(script, sizeof (script), "%s/postremove", pkgbin);
10735c51f124SMoriah Waterland 	if (access(script, F_OK) != 0) {
10745c51f124SMoriah Waterland 		/* no script present */
10755c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst,
10765c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10775c51f124SMoriah Waterland 	} else if (nodelete) {
10785c51f124SMoriah Waterland 		/* not deleting files: skip postremove script */
10795c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script,
10805c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10815c51f124SMoriah Waterland 	} else if (is_depend_pkginfo_DB()) {
10825c51f124SMoriah Waterland 		/* updating db only: skip postremove script */
10835c51f124SMoriah Waterland 		echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script,
10845c51f124SMoriah Waterland 			zoneName ? zoneName : "global");
10855c51f124SMoriah Waterland 	} else {
10865c51f124SMoriah Waterland 		/* script present and ok to run: run the script */
10875c51f124SMoriah Waterland 		set_ulimit("postremove", ERR_POSTREMOVE);
10885c51f124SMoriah Waterland 		if (zoneName == (char *)NULL) {
10895c51f124SMoriah Waterland 			echo(MSG_PKGREMOVE_EXEPIC_GZ);
10905c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script);
10915c51f124SMoriah Waterland 		} else {
10925c51f124SMoriah Waterland 			echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName);
10935c51f124SMoriah Waterland 			echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script,
10945c51f124SMoriah Waterland 				zoneName);
10955c51f124SMoriah Waterland 		}
10965c51f124SMoriah Waterland 		putparam("PKG_PROC_SCRIPT", "postremove");
10975c51f124SMoriah Waterland 		putparam("TMPDIR", tmpdir);
10985c51f124SMoriah Waterland 		if (pkgverbose) {
10995c51f124SMoriah Waterland 			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
11005c51f124SMoriah Waterland 			    PROC_GRP, SHELL, "-x", script, NULL),
11015c51f124SMoriah Waterland 			    ERR_POSTREMOVE);
11025c51f124SMoriah Waterland 		} else {
11035c51f124SMoriah Waterland 			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
11045c51f124SMoriah Waterland 			    PROC_GRP, SHELL, script, NULL),
11055c51f124SMoriah Waterland 			    ERR_POSTREMOVE);
11065c51f124SMoriah Waterland 		}
11075c51f124SMoriah Waterland 		clr_ulimit();
11085c51f124SMoriah Waterland 	}
11095c51f124SMoriah Waterland 
11105c51f124SMoriah Waterland 	if (zoneName == (char *)NULL) {
11115c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_UPDINF_GZ);
11125c51f124SMoriah Waterland 	} else {
11135c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName);
11145c51f124SMoriah Waterland 	}
11155c51f124SMoriah Waterland 
1116*62224350SCasper H.S. Dik 	if (delmap(1, pkginst, &pkgserver, &tmpfp) != 0) {
11175c51f124SMoriah Waterland 		progerr(ERR_DB_QUERY, pkginst);
11185c51f124SMoriah Waterland 		quit(99);
11195c51f124SMoriah Waterland 	}
11205c51f124SMoriah Waterland 
11215c51f124SMoriah Waterland 	if (!warnflag && !failflag) {
11225c51f124SMoriah Waterland 		if (pt = getenv("PREDEPEND"))
11235c51f124SMoriah Waterland 			predepend(pt);
11245c51f124SMoriah Waterland 		(void) chdir("/");
11255c51f124SMoriah Waterland 		if (rrmdir(pkgloc))
11265c51f124SMoriah Waterland 			warnflag++;
11275c51f124SMoriah Waterland 	}
11285c51f124SMoriah Waterland 
11295c51f124SMoriah Waterland 	if ((z_running_in_global_zone() == B_TRUE) &&
11305c51f124SMoriah Waterland 		(pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) {
11315c51f124SMoriah Waterland 		boolean_t	b;
11325c51f124SMoriah Waterland 
11335c51f124SMoriah Waterland 		b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst);
11345c51f124SMoriah Waterland 		if (b == B_FALSE) {
11355c51f124SMoriah Waterland 			progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst);
11365c51f124SMoriah Waterland 			ckreturn(1, NULL);
11375c51f124SMoriah Waterland 		}
11385c51f124SMoriah Waterland 	}
11395c51f124SMoriah Waterland 
11405c51f124SMoriah Waterland 	/* release the generic package lock */
11415c51f124SMoriah Waterland 
11425c51f124SMoriah Waterland 	(void) unlockinst();
11435c51f124SMoriah Waterland 
1144*62224350SCasper H.S. Dik 	pkgcloseserver(pkgserver);
1145*62224350SCasper H.S. Dik 
11465c51f124SMoriah Waterland 	quit(0);
11475c51f124SMoriah Waterland 	/* LINTED: no return */
11485c51f124SMoriah Waterland }
11495c51f124SMoriah Waterland 
11505c51f124SMoriah Waterland int
11515c51f124SMoriah Waterland issymlink(char *path)
11525c51f124SMoriah Waterland {
11535c51f124SMoriah Waterland 	struct stat statbuf;
11545c51f124SMoriah Waterland 
11555c51f124SMoriah Waterland 	/*
11565c51f124SMoriah Waterland 	 * Obtain status of path; if symbolic link get link's status
11575c51f124SMoriah Waterland 	 */
11585c51f124SMoriah Waterland 
11595c51f124SMoriah Waterland 	if (lstat(path, &statbuf) != 0) {
11605c51f124SMoriah Waterland 		return (1);	/* not symlink */
11615c51f124SMoriah Waterland 	}
11625c51f124SMoriah Waterland 
11635c51f124SMoriah Waterland 	/*
11645c51f124SMoriah Waterland 	 * Status obtained - if symbolic link, return 0
11655c51f124SMoriah Waterland 	 */
11665c51f124SMoriah Waterland 
11675c51f124SMoriah Waterland 	if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
11685c51f124SMoriah Waterland 		return (0);	/* is a symlink */
11695c51f124SMoriah Waterland 	}
11705c51f124SMoriah Waterland 
11715c51f124SMoriah Waterland 	/*
11725c51f124SMoriah Waterland 	 * Not a symbolic link - return 1
11735c51f124SMoriah Waterland 	 */
11745c51f124SMoriah Waterland 
11755c51f124SMoriah Waterland 	return (1);		/* not symlink */
11765c51f124SMoriah Waterland }
11775c51f124SMoriah Waterland 
11785c51f124SMoriah Waterland static void
11795c51f124SMoriah Waterland rmclass(char *aclass, int rm_remote, char *a_zoneName)
11805c51f124SMoriah Waterland {
11815c51f124SMoriah Waterland 	struct cfent	*ept;
11825c51f124SMoriah Waterland 	FILE	*fp;
11835c51f124SMoriah Waterland 	char	tmpfile[PATH_MAX];
11845c51f124SMoriah Waterland 	char	script[PATH_MAX];
11855c51f124SMoriah Waterland 	int	i;
11865c51f124SMoriah Waterland 	char	*tmp_path;
11875c51f124SMoriah Waterland 	char	*save_path = NULL;
11885c51f124SMoriah Waterland 	struct stat st;
11895c51f124SMoriah Waterland 
11905c51f124SMoriah Waterland 	if (aclass == NULL) {
11915c51f124SMoriah Waterland 		for (i = 0; i < eptnum; i++) {
11925c51f124SMoriah Waterland 			if (eptlist[i] != NULL) {
11935c51f124SMoriah Waterland 				rmclass(eptlist[i]->pkg_class,
11945c51f124SMoriah Waterland 					rm_remote, a_zoneName);
11955c51f124SMoriah Waterland 			}
11965c51f124SMoriah Waterland 		}
11975c51f124SMoriah Waterland 		return;
11985c51f124SMoriah Waterland 	}
11995c51f124SMoriah Waterland 
12005c51f124SMoriah Waterland 	/* locate class action script to execute */
12015c51f124SMoriah Waterland 	(void) snprintf(script, sizeof (script), "%s/r.%s", pkgbin, aclass);
12025c51f124SMoriah Waterland 	if (access(script, F_OK) != 0) {
12035c51f124SMoriah Waterland 		(void) snprintf(script, sizeof (script), "%s/r.%s",
12045c51f124SMoriah Waterland 		    PKGSCR, aclass);
12055c51f124SMoriah Waterland 		if (access(script, F_OK) != 0)
12065c51f124SMoriah Waterland 			script[0] = '\0';
12075c51f124SMoriah Waterland 	}
12085c51f124SMoriah Waterland 	if (script[0] != '\0') {
12095c51f124SMoriah Waterland 		int td;
12105c51f124SMoriah Waterland 
12115c51f124SMoriah Waterland 		(void) snprintf(tmpfile, sizeof (tmpfile), "%s/RMLISTXXXXXX",
12125c51f124SMoriah Waterland 		    tmpdir);
12135c51f124SMoriah Waterland 		td = mkstemp(tmpfile);
12145c51f124SMoriah Waterland 		if (td == -1) {
12155c51f124SMoriah Waterland 			progerr(ERR_TMPFILE);
12165c51f124SMoriah Waterland 			quit(99);
12175c51f124SMoriah Waterland 		}
12185c51f124SMoriah Waterland 		if ((fp = fdopen(td, "w")) == NULL) {
12195c51f124SMoriah Waterland 			progerr(ERR_WTMPFILE, tmpfile);
12205c51f124SMoriah Waterland 			quit(99);
12215c51f124SMoriah Waterland 		}
12225c51f124SMoriah Waterland 	}
12235c51f124SMoriah Waterland 
12245c51f124SMoriah Waterland 	if (a_zoneName == (char *)NULL) {
12255c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_REMPATHCLASS_GZ, aclass);
12265c51f124SMoriah Waterland 	} else {
12275c51f124SMoriah Waterland 		echo(MSG_PKGREMOVE_REMPATHCLASS_LZ, aclass, a_zoneName);
12285c51f124SMoriah Waterland 	}
12295c51f124SMoriah Waterland 
12305c51f124SMoriah Waterland 	/* process paths in reverse order */
12315c51f124SMoriah Waterland 	i = eptnum;
12325c51f124SMoriah Waterland 	while (--i >= 0) {
12335c51f124SMoriah Waterland 		ept = eptlist[i];
12345c51f124SMoriah Waterland 
12355c51f124SMoriah Waterland 		if ((ept == NULL) || strcmp(aclass, ept->pkg_class)) {
12365c51f124SMoriah Waterland 			continue;
12375c51f124SMoriah Waterland 		}
12385c51f124SMoriah Waterland 
12395c51f124SMoriah Waterland 		/* save the path, and prepend the ir */
12405c51f124SMoriah Waterland 		if (is_an_inst_root()) {
12415c51f124SMoriah Waterland 			save_path = ept->path;
12425c51f124SMoriah Waterland 			tmp_path = fixpath(ept->path);
12435c51f124SMoriah Waterland 			ept->path = tmp_path;
12445c51f124SMoriah Waterland 		}
12455c51f124SMoriah Waterland 
12465c51f124SMoriah Waterland 		if (!ept->ftype || (ept->ftype == '^' && !script[0])) {
12475c51f124SMoriah Waterland 			/*
12485c51f124SMoriah Waterland 			 * A path owned by more than one package is marked with
12495c51f124SMoriah Waterland 			 * a NULL ftype (seems odd, but that's how it's
12505c51f124SMoriah Waterland 			 * done). Such files are sacro sanct. Shared editable
12515c51f124SMoriah Waterland 			 * files are a special case, and are marked with an
12525c51f124SMoriah Waterland 			 * ftype of '^'. These files should only be ignored if
12535c51f124SMoriah Waterland 			 * no class action script is present. It is the CAS's
12545c51f124SMoriah Waterland 			 * responsibility to not remove the editable object.
12555c51f124SMoriah Waterland 			 */
12565c51f124SMoriah Waterland 			echo(MSG_SHARED, ept->path);
12575c51f124SMoriah Waterland 		} else if (ept->pinfo->status == SERVED_FILE && !rm_remote) {
12585c51f124SMoriah Waterland 			/*
12595c51f124SMoriah Waterland 			 * If the path is provided to the client from a
12605c51f124SMoriah Waterland 			 * server, don't remove anything unless explicitly
12615c51f124SMoriah Waterland 			 * requested through the "-f" option.
12625c51f124SMoriah Waterland 			 */
12635c51f124SMoriah Waterland 			echo(MSG_SERVER, ept->path);
12645c51f124SMoriah Waterland 		} else if (z_path_is_inherited(ept->path, ept->ftype,
12655c51f124SMoriah Waterland 		    get_inst_root())) {
12665c51f124SMoriah Waterland 			/*
12675c51f124SMoriah Waterland 			 * object is in an area inherited from the global zone,
12685c51f124SMoriah Waterland 			 * and the object cannot be removed - output a message
12695c51f124SMoriah Waterland 			 * indicating the object cannot be removed and continue.
12705c51f124SMoriah Waterland 			 */
12715c51f124SMoriah Waterland 			echo(MSG_NOTREMOVED_INHERITED, ept->path);
12725c51f124SMoriah Waterland 		} else if (script[0]) {
12735c51f124SMoriah Waterland 			/*
12745c51f124SMoriah Waterland 			 * If there's a class action script, just put the
12755c51f124SMoriah Waterland 			 * path name into the list.
12765c51f124SMoriah Waterland 			 */
12775c51f124SMoriah Waterland 			(void) fprintf(fp, "%s\n", ept->path);
12785c51f124SMoriah Waterland 		} else if (strchr("dx", ept->ftype) != NULL ||
12795c51f124SMoriah Waterland 		    (lstat(ept->path, &st) == 0 && S_ISDIR(st.st_mode))) {
12805c51f124SMoriah Waterland 			/* Directories are rmdir()'d. */
12815c51f124SMoriah Waterland 
12825c51f124SMoriah Waterland 			if (rmdir(ept->path)) {
12835c51f124SMoriah Waterland 				if (errno == EBUSY) {
12845c51f124SMoriah Waterland 					echo(MSG_DIRBUSY, ept->path);
12855c51f124SMoriah Waterland 				} else if (errno == EEXIST) {
12865c51f124SMoriah Waterland 					echo(MSG_NOTEMPTY, ept->path);
12875c51f124SMoriah Waterland 				} else if (errno != ENOENT) {
12885c51f124SMoriah Waterland 					progerr(ERR_RMDIR, ept->path);
12895c51f124SMoriah Waterland 					warnflag++;
12905c51f124SMoriah Waterland 				}
12915c51f124SMoriah Waterland 			} else {
12925c51f124SMoriah Waterland 				if (ept->pinfo->status == SERVED_FILE) {
12935c51f124SMoriah Waterland 					echo(MSG_RMSRVR, ept->path);
12945c51f124SMoriah Waterland 				} else {
12955c51f124SMoriah Waterland 					echo("%s", ept->path);
12965c51f124SMoriah Waterland 				}
12975c51f124SMoriah Waterland 			}
12985c51f124SMoriah Waterland 
12995c51f124SMoriah Waterland 		} else {
13005c51f124SMoriah Waterland 			/*
13015c51f124SMoriah Waterland 			 * Before removing this object one more
13025c51f124SMoriah Waterland 			 * check should be done to assure that a
13035c51f124SMoriah Waterland 			 * shared object is not removed.
13045c51f124SMoriah Waterland 			 * This can happen if the original object
13055c51f124SMoriah Waterland 			 * was incorrectly updated with the
13065c51f124SMoriah Waterland 			 * incorrect class identifier.
13075c51f124SMoriah Waterland 			 * This handles pathologcal cases that
13085c51f124SMoriah Waterland 			 * weren't handled above.
13095c51f124SMoriah Waterland 			 */
13105c51f124SMoriah Waterland 			if (ept->npkgs > 1) {
13115c51f124SMoriah Waterland 				echo(MSG_SHARED, ept->path);
13125c51f124SMoriah Waterland 				continue;
13135c51f124SMoriah Waterland 			}
13145c51f124SMoriah Waterland 
13155c51f124SMoriah Waterland 			/* Regular files are unlink()'d. */
13165c51f124SMoriah Waterland 
13175c51f124SMoriah Waterland 			if (unlink(ept->path)) {
13185c51f124SMoriah Waterland 				if (errno != ENOENT) {
13195c51f124SMoriah Waterland 					progerr(ERR_RMPATH, ept->path);
13205c51f124SMoriah Waterland 					warnflag++;
13215c51f124SMoriah Waterland 				}
13225c51f124SMoriah Waterland 			} else {
13235c51f124SMoriah Waterland 				if (ept->pinfo->status == SERVED_FILE) {
13245c51f124SMoriah Waterland 					echo(MSG_RMSRVR, ept->path);
13255c51f124SMoriah Waterland 				} else {
13265c51f124SMoriah Waterland 					echo("%s", ept->path);
13275c51f124SMoriah Waterland 				}
13285c51f124SMoriah Waterland 			}
13295c51f124SMoriah Waterland 		}
13305c51f124SMoriah Waterland 
13315c51f124SMoriah Waterland 		/* restore the original path */
13325c51f124SMoriah Waterland 
13335c51f124SMoriah Waterland 		if (is_an_inst_root()) {
13345c51f124SMoriah Waterland 			ept->path = save_path;
13355c51f124SMoriah Waterland 		}
13365c51f124SMoriah Waterland 
13375c51f124SMoriah Waterland 		/*
13385c51f124SMoriah Waterland 		 * free memory allocated for this entry memory used for
13395c51f124SMoriah Waterland 		 * pathnames will be freed later by a call to pathdup()
13405c51f124SMoriah Waterland 		 */
13415c51f124SMoriah Waterland 
13425c51f124SMoriah Waterland 		if (eptlist[i]) {
13435c51f124SMoriah Waterland 			free(eptlist[i]);
13445c51f124SMoriah Waterland 		}
13455c51f124SMoriah Waterland 		eptlist[i] = NULL;
13465c51f124SMoriah Waterland 	}
13475c51f124SMoriah Waterland 	if (script[0]) {
13485c51f124SMoriah Waterland 		(void) fclose(fp);
13495c51f124SMoriah Waterland 		set_ulimit(script, ERR_CASFAIL);
13505c51f124SMoriah Waterland 		if (pkgverbose)
13515c51f124SMoriah Waterland 			ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER,
13525c51f124SMoriah Waterland 			    CAS_GRP, SHELL, "-x", script, NULL),
13535c51f124SMoriah Waterland 			    ERR_CASFAIL);
13545c51f124SMoriah Waterland 		else
13555c51f124SMoriah Waterland 			ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER,
13565c51f124SMoriah Waterland 			    CAS_GRP, SHELL, script, NULL),
13575c51f124SMoriah Waterland 			    ERR_CASFAIL);
13585c51f124SMoriah Waterland 		clr_ulimit();
13595c51f124SMoriah Waterland 		if (isfile(NULL, tmpfile) == 0) {
13605c51f124SMoriah Waterland 			if (unlink(tmpfile) == -1)
13615c51f124SMoriah Waterland 				progerr(ERR_RMPATH, tmpfile);
13625c51f124SMoriah Waterland 		}
13635c51f124SMoriah Waterland 	}
13645c51f124SMoriah Waterland }
13655c51f124SMoriah Waterland 
13665c51f124SMoriah Waterland static void
13675c51f124SMoriah Waterland ckreturn(int retcode, char *msg)
13685c51f124SMoriah Waterland {
13695c51f124SMoriah Waterland 	switch (retcode) {
13705c51f124SMoriah Waterland 	    case 2:
13715c51f124SMoriah Waterland 	    case 12:
13725c51f124SMoriah Waterland 	    case 22:
13735c51f124SMoriah Waterland 		warnflag++;
13745c51f124SMoriah Waterland 		/*FALLTHRU*/
13755c51f124SMoriah Waterland 		if (msg)
13765c51f124SMoriah Waterland 			progerr(msg);
13775c51f124SMoriah Waterland 	    case 10:
13785c51f124SMoriah Waterland 	    case 20:
13795c51f124SMoriah Waterland 		if (retcode >= 10)
13805c51f124SMoriah Waterland 			dreboot++;
13815c51f124SMoriah Waterland 		if (retcode >= 20)
13825c51f124SMoriah Waterland 			ireboot++;
13835c51f124SMoriah Waterland 		/*FALLTHRU*/
13845c51f124SMoriah Waterland 	    case 0:
13855c51f124SMoriah Waterland 		break; /* okay */
13865c51f124SMoriah Waterland 
13875c51f124SMoriah Waterland 	    case -1:
13885c51f124SMoriah Waterland 		retcode = 99;
13895c51f124SMoriah Waterland 		/*FALLTHRU*/
13905c51f124SMoriah Waterland 	    case 99:
13915c51f124SMoriah Waterland 	    case 1:
13925c51f124SMoriah Waterland 	    case 11:
13935c51f124SMoriah Waterland 	    case 21:
13945c51f124SMoriah Waterland 	    case 4:
13955c51f124SMoriah Waterland 	    case 14:
13965c51f124SMoriah Waterland 	    case 24:
13975c51f124SMoriah Waterland 	    case 5:
13985c51f124SMoriah Waterland 	    case 15:
13995c51f124SMoriah Waterland 	    case 25:
14005c51f124SMoriah Waterland 		if (msg)
14015c51f124SMoriah Waterland 			progerr(msg);
14025c51f124SMoriah Waterland 		/*FALLTHRU*/
14035c51f124SMoriah Waterland 	    case 3:
14045c51f124SMoriah Waterland 	    case 13:
14055c51f124SMoriah Waterland 	    case 23:
14065c51f124SMoriah Waterland 		quit(retcode);
14075c51f124SMoriah Waterland 		/* NOT REACHED */
14085c51f124SMoriah Waterland 	    default:
14095c51f124SMoriah Waterland 		if (msg)
14105c51f124SMoriah Waterland 			progerr(msg);
14115c51f124SMoriah Waterland 		quit(1);
14125c51f124SMoriah Waterland 	}
14135c51f124SMoriah Waterland }
14145c51f124SMoriah Waterland 
14155c51f124SMoriah Waterland static void
14165c51f124SMoriah Waterland usage(void)
14175c51f124SMoriah Waterland {
14185c51f124SMoriah Waterland 	(void) fprintf(stderr, ERR_USAGE_PKGREMOVE);
14195c51f124SMoriah Waterland 
14205c51f124SMoriah Waterland 	exit(1);
14215c51f124SMoriah Waterland }
14225c51f124SMoriah Waterland 
14235c51f124SMoriah Waterland /*
14245c51f124SMoriah Waterland  * Name:		path_valid
14255c51f124SMoriah Waterland  * Description:	Checks a string for being a valid path
14265c51f124SMoriah Waterland  *
14275c51f124SMoriah Waterland  * Arguments:	path - path to validate
14285c51f124SMoriah Waterland  *
14295c51f124SMoriah Waterland  * Returns :	B_TRUE - success, B_FALSE otherwise.
14305c51f124SMoriah Waterland  *		B_FALSE means path was null, too long (>PATH_MAX),
14315c51f124SMoriah Waterland  *		or too short (<1)
14325c51f124SMoriah Waterland  */
14335c51f124SMoriah Waterland static boolean_t
14345c51f124SMoriah Waterland path_valid(char *path)
14355c51f124SMoriah Waterland {
14365c51f124SMoriah Waterland 	if (path == NULL) {
14375c51f124SMoriah Waterland 		return (B_FALSE);
14385c51f124SMoriah Waterland 	} else if (strlen(path) > PATH_MAX) {
14395c51f124SMoriah Waterland 		return (B_FALSE);
14405c51f124SMoriah Waterland 	} else if (strlen(path) >= 1) {
14415c51f124SMoriah Waterland 		return (B_TRUE);
14425c51f124SMoriah Waterland 	} else {
14435c51f124SMoriah Waterland 		/* path < 1 */
14445c51f124SMoriah Waterland 		return (B_FALSE);
14455c51f124SMoriah Waterland 	}
14465c51f124SMoriah Waterland }
1447