xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgremove/main.c (revision 12734:76969fc28795)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
23*12734Sgary.pennington@oracle.com  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
249781SMoriah.Waterland@Sun.COM  */
259781SMoriah.Waterland@Sun.COM 
269781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
279781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
289781SMoriah.Waterland@Sun.COM 
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM #include <stdio.h>
319781SMoriah.Waterland@Sun.COM #include <limits.h>
329781SMoriah.Waterland@Sun.COM #include <stdlib.h>
339781SMoriah.Waterland@Sun.COM #include <unistd.h>
349781SMoriah.Waterland@Sun.COM #include <string.h>
359781SMoriah.Waterland@Sun.COM #include <signal.h>
369781SMoriah.Waterland@Sun.COM #include <errno.h>
379781SMoriah.Waterland@Sun.COM #include <fcntl.h>
389781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
399781SMoriah.Waterland@Sun.COM #include <sys/types.h>
409781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
419781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
429781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
439781SMoriah.Waterland@Sun.COM #include <locale.h>
449781SMoriah.Waterland@Sun.COM #include <libintl.h>
459781SMoriah.Waterland@Sun.COM #include <assert.h>
469781SMoriah.Waterland@Sun.COM #include <cfext.h>
479781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
489781SMoriah.Waterland@Sun.COM #include <pkglib.h>
499781SMoriah.Waterland@Sun.COM #include <install.h>
509781SMoriah.Waterland@Sun.COM #include <libinst.h>
519781SMoriah.Waterland@Sun.COM #include <libadm.h>
529781SMoriah.Waterland@Sun.COM #include <messages.h>
539781SMoriah.Waterland@Sun.COM 
549781SMoriah.Waterland@Sun.COM struct cfent **eptlist;
559781SMoriah.Waterland@Sun.COM extern int	eptnum;
569781SMoriah.Waterland@Sun.COM 
579781SMoriah.Waterland@Sun.COM extern char	*pkgdir;
589781SMoriah.Waterland@Sun.COM extern char	**environ;
599781SMoriah.Waterland@Sun.COM 
609781SMoriah.Waterland@Sun.COM /* quit.c */
619781SMoriah.Waterland@Sun.COM extern sighdlrFunc_t	*quitGetTrapHandler(void);
629781SMoriah.Waterland@Sun.COM extern void		quitSetSilentExit(boolean_t a_silentExit);
639781SMoriah.Waterland@Sun.COM extern void		quitSetZoneName(char *a_zoneName);
649781SMoriah.Waterland@Sun.COM 
659781SMoriah.Waterland@Sun.COM 
669781SMoriah.Waterland@Sun.COM 
679781SMoriah.Waterland@Sun.COM /* check.c */
689781SMoriah.Waterland@Sun.COM extern void	rcksetPreremoveCheck(boolean_t);
699781SMoriah.Waterland@Sun.COM extern void	rcksetZoneName(char *);
709781SMoriah.Waterland@Sun.COM extern int	rckpriv(void);
719781SMoriah.Waterland@Sun.COM extern int	rckdepend(void);
729781SMoriah.Waterland@Sun.COM extern int	rckrunlevel(void);
739781SMoriah.Waterland@Sun.COM 
749781SMoriah.Waterland@Sun.COM /* predepend.c */
759781SMoriah.Waterland@Sun.COM extern void	predepend(char *oldpkg);
769781SMoriah.Waterland@Sun.COM 
779781SMoriah.Waterland@Sun.COM /* delmap.c */
789869SCasper.Dik@Sun.COM extern int delmap(int flag, char *pkginst, PKGserver *server, VFP_T **tfp);
799781SMoriah.Waterland@Sun.COM 
809781SMoriah.Waterland@Sun.COM #define	DEFPATH		"/sbin:/usr/sbin:/usr/bin"
819781SMoriah.Waterland@Sun.COM 
829781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
839781SMoriah.Waterland@Sun.COM #define	SCRIPT	0	/* Tells exception_pkg() which pkg list to use */
849781SMoriah.Waterland@Sun.COM #define	LINK	1
859781SMoriah.Waterland@Sun.COM #endif
869781SMoriah.Waterland@Sun.COM 
879781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
889781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
899781SMoriah.Waterland@Sun.COM #endif
909781SMoriah.Waterland@Sun.COM 
919781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-name=" option */
929781SMoriah.Waterland@Sun.COM 
939781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME	"parent-zone-name="
949781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME_LEN	((sizeof (PARENTZONENAME))-1)
959781SMoriah.Waterland@Sun.COM 
969781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-type=" option */
979781SMoriah.Waterland@Sun.COM 
989781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE	"parent-zone-type="
999781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE_LEN	((sizeof (PARENTZONETYPE))-1)
1009781SMoriah.Waterland@Sun.COM 
1019781SMoriah.Waterland@Sun.COM struct	admin adm; 	/* holds info about installation admin */
1029781SMoriah.Waterland@Sun.COM int	dreboot; 	/* non-zero if reboot required after installation */
1039781SMoriah.Waterland@Sun.COM int	ireboot;	/* non-zero if immediate reboot required */
1049781SMoriah.Waterland@Sun.COM int	failflag;	/* non-zero if fatal error has occurred */
1059781SMoriah.Waterland@Sun.COM int	warnflag;	/* non-zero if non-fatal error has occurred */
1069781SMoriah.Waterland@Sun.COM int	pkgverbose;	/* non-zero if verbose mode is selected */
1079781SMoriah.Waterland@Sun.COM int	started;
1089781SMoriah.Waterland@Sun.COM int	nocnflct = 0; 	/* pkgdbmerg needs this defined */
1099781SMoriah.Waterland@Sun.COM int	nosetuid = 0; 	/* pkgdbmerg needs this defined */
1109781SMoriah.Waterland@Sun.COM 
1119781SMoriah.Waterland@Sun.COM char	*pkginst; 	/* current package (source) instance to process */
1129781SMoriah.Waterland@Sun.COM 
1139781SMoriah.Waterland@Sun.COM int	dbchg;
1149781SMoriah.Waterland@Sun.COM char	*msgtext;
1159781SMoriah.Waterland@Sun.COM char	pkgloc[PATH_MAX];
1169781SMoriah.Waterland@Sun.COM 
1179781SMoriah.Waterland@Sun.COM /*
1189781SMoriah.Waterland@Sun.COM  * The following variable is the name of the device to which stdin
1199781SMoriah.Waterland@Sun.COM  * is connected during execution of a procedure script. /dev/null is
1209781SMoriah.Waterland@Sun.COM  * correct for all ABI compliant packages. For non-ABI-compliant
1219781SMoriah.Waterland@Sun.COM  * packages, the '-o' command line switch changes this to /dev/tty
1229781SMoriah.Waterland@Sun.COM  * to allow user interaction during these scripts. -- JST
1239781SMoriah.Waterland@Sun.COM  */
1249781SMoriah.Waterland@Sun.COM static char 	*script_in = PROC_STDIN;	/* assume ABI compliance */
1259781SMoriah.Waterland@Sun.COM 
1269781SMoriah.Waterland@Sun.COM static char	*client_mntdir; 	/* mount point for client's basedir */
1279781SMoriah.Waterland@Sun.COM static char	pkgbin[PATH_MAX],
1289781SMoriah.Waterland@Sun.COM 		rlockfile[PATH_MAX],
1299781SMoriah.Waterland@Sun.COM 		*admnfile, 		/* file to use for installation admin */
1309781SMoriah.Waterland@Sun.COM 		*tmpdir; 		/* location to place temporary files */
1319781SMoriah.Waterland@Sun.COM 
1329781SMoriah.Waterland@Sun.COM static boolean_t	path_valid(char *path);
1339781SMoriah.Waterland@Sun.COM static void		ckreturn(int retcode, char *msg);
1349781SMoriah.Waterland@Sun.COM static void		rmclass(char *aclass, int rm_remote, char *a_zoneName);
1359781SMoriah.Waterland@Sun.COM static void		usage(void);
1369781SMoriah.Waterland@Sun.COM 
1379781SMoriah.Waterland@Sun.COM /*
1389781SMoriah.Waterland@Sun.COM  * Set by -O debug: debug output is enabled?
1399781SMoriah.Waterland@Sun.COM  */
1409781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
1419781SMoriah.Waterland@Sun.COM 
1429781SMoriah.Waterland@Sun.COM /*
1439781SMoriah.Waterland@Sun.COM  * Set by -O preremovecheck: do remove dependency checking only
1449781SMoriah.Waterland@Sun.COM  */
1459781SMoriah.Waterland@Sun.COM static boolean_t	preremoveCheck = B_FALSE;
1469781SMoriah.Waterland@Sun.COM 
1479781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-name= */
1489781SMoriah.Waterland@Sun.COM 
1499781SMoriah.Waterland@Sun.COM static char		*parentZoneName = (char *)NULL;
1509781SMoriah.Waterland@Sun.COM 
1519781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-type= */
1529781SMoriah.Waterland@Sun.COM 
1539781SMoriah.Waterland@Sun.COM static char		*parentZoneType = (char *)NULL;
1549781SMoriah.Waterland@Sun.COM 
1559781SMoriah.Waterland@Sun.COM static int	nointeract;	/* != 0 no interaction with user should occur */
1569781SMoriah.Waterland@Sun.COM 
1579781SMoriah.Waterland@Sun.COM 
1589781SMoriah.Waterland@Sun.COM 
1599781SMoriah.Waterland@Sun.COM int
main(int argc,char * argv[])1609781SMoriah.Waterland@Sun.COM main(int argc, char *argv[])
1619781SMoriah.Waterland@Sun.COM {
1629781SMoriah.Waterland@Sun.COM 	FILE		*fp;
1639781SMoriah.Waterland@Sun.COM 	char		*abi_comp_ptr;
1649781SMoriah.Waterland@Sun.COM 	char		*abi_sym_ptr;
1659781SMoriah.Waterland@Sun.COM 	char		*p;
1669781SMoriah.Waterland@Sun.COM 	char		*prog_full_name = NULL;
1679781SMoriah.Waterland@Sun.COM 	char		*pt;
1689781SMoriah.Waterland@Sun.COM 	char		*value;
1699781SMoriah.Waterland@Sun.COM 	char		*vfstab_file = NULL;
1709781SMoriah.Waterland@Sun.COM 	char		*zoneName = (char *)NULL;
1719781SMoriah.Waterland@Sun.COM 	char		cmdbin[PATH_MAX];
1729781SMoriah.Waterland@Sun.COM 	char		param[MAX_PKG_PARAM_LENGTH];
1739781SMoriah.Waterland@Sun.COM 	char		path[PATH_MAX];
1749781SMoriah.Waterland@Sun.COM 	char		script[PATH_MAX];
1759781SMoriah.Waterland@Sun.COM 	int		c;
1769781SMoriah.Waterland@Sun.COM 	int		err;
1779781SMoriah.Waterland@Sun.COM 	int		fd;
1789781SMoriah.Waterland@Sun.COM 	int		i;
1799781SMoriah.Waterland@Sun.COM 	int		map_client = 1;
1809781SMoriah.Waterland@Sun.COM 	int		n;
1819781SMoriah.Waterland@Sun.COM 	int		nodelete = 0; 	/* do not delete file or run scripts */
1829781SMoriah.Waterland@Sun.COM 	int		pkgrmremote = 0;	/* dont remove remote objects */
1839781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
1849781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
1859869SCasper.Dik@Sun.COM 	PKGserver	pkgserver = NULL;
1869869SCasper.Dik@Sun.COM 	VFP_T		*tmpfp;
1879781SMoriah.Waterland@Sun.COM 
1889781SMoriah.Waterland@Sun.COM 	/* reset contents of all default paths */
1899781SMoriah.Waterland@Sun.COM 
1909781SMoriah.Waterland@Sun.COM 	(void) memset(cmdbin, '\0', sizeof (cmdbin));
1919781SMoriah.Waterland@Sun.COM 
1929781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
1939781SMoriah.Waterland@Sun.COM 
1949781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
1959781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
1969781SMoriah.Waterland@Sun.COM 
1979781SMoriah.Waterland@Sun.COM 	/* initialize program name */
1989781SMoriah.Waterland@Sun.COM 
1999781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
2009781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
2019781SMoriah.Waterland@Sun.COM 
2029781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
2039781SMoriah.Waterland@Sun.COM 
2049781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
2059781SMoriah.Waterland@Sun.COM 
2069781SMoriah.Waterland@Sun.COM 	/* exit if not root */
2079781SMoriah.Waterland@Sun.COM 
2089781SMoriah.Waterland@Sun.COM 	if (getuid()) {
2099781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, get_prog_name());
2109781SMoriah.Waterland@Sun.COM 		exit(1);
2119781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
2129781SMoriah.Waterland@Sun.COM 	}
2139781SMoriah.Waterland@Sun.COM 
2149781SMoriah.Waterland@Sun.COM 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
2159781SMoriah.Waterland@Sun.COM 
2169781SMoriah.Waterland@Sun.COM 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
2179781SMoriah.Waterland@Sun.COM 		progerr(ERR_ROOT_SET);
2189781SMoriah.Waterland@Sun.COM 		exit(1);
2199781SMoriah.Waterland@Sun.COM 	}
2209781SMoriah.Waterland@Sun.COM 
2219869SCasper.Dik@Sun.COM 	pkgserversetmode(DEFAULTMODE);
2229869SCasper.Dik@Sun.COM 
2239781SMoriah.Waterland@Sun.COM 	/* parse command line options */
2249781SMoriah.Waterland@Sun.COM 
2259781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) {
2269781SMoriah.Waterland@Sun.COM 		switch (c) {
2279781SMoriah.Waterland@Sun.COM 		/*
2289781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: Allow admin to remove package objects from
2299781SMoriah.Waterland@Sun.COM 		 * a shared area from a reference client.
2309781SMoriah.Waterland@Sun.COM 		 */
2319781SMoriah.Waterland@Sun.COM 		case 'A':
2329781SMoriah.Waterland@Sun.COM 		    pkgrmremote++;
2339781SMoriah.Waterland@Sun.COM 		    break;
2349781SMoriah.Waterland@Sun.COM 
2359781SMoriah.Waterland@Sun.COM 		/*
2369781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: Use the installation
2379781SMoriah.Waterland@Sun.COM 		 * administration file, admin, in place of the
2389781SMoriah.Waterland@Sun.COM 		 * default admin file. pkgrm first looks in the
2399781SMoriah.Waterland@Sun.COM 		 * current working directory for the administration
2409781SMoriah.Waterland@Sun.COM 		 * file.  If the specified administration file is not
2419781SMoriah.Waterland@Sun.COM 		 * in the current working directory, pkgrm looks in
2429781SMoriah.Waterland@Sun.COM 		 * the /var/sadm/install/admin directory for the
2439781SMoriah.Waterland@Sun.COM 		 * administration file.
2449781SMoriah.Waterland@Sun.COM 		 */
2459781SMoriah.Waterland@Sun.COM 		case 'a':
2469781SMoriah.Waterland@Sun.COM 		    admnfile = flex_device(optarg, 0);
2479781SMoriah.Waterland@Sun.COM 		    break;
2489781SMoriah.Waterland@Sun.COM 
2499781SMoriah.Waterland@Sun.COM 		/*
2509781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: location where package executables
2519781SMoriah.Waterland@Sun.COM 		 * can be found - default is /usr/sadm/install/bin.
2529781SMoriah.Waterland@Sun.COM 		 */
2539781SMoriah.Waterland@Sun.COM 		case 'b':
2549781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
2559781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
2569781SMoriah.Waterland@Sun.COM 				exit(1);
2579781SMoriah.Waterland@Sun.COM 			}
2589781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
2599781SMoriah.Waterland@Sun.COM 				char *p = strerror(errno);
2609781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
2619781SMoriah.Waterland@Sun.COM 				exit(1);
2629781SMoriah.Waterland@Sun.COM 			}
2639781SMoriah.Waterland@Sun.COM 			(void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
2649781SMoriah.Waterland@Sun.COM 			break;
2659781SMoriah.Waterland@Sun.COM 
2669781SMoriah.Waterland@Sun.COM 		/*
2679781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: suppresses the removal of any
2689781SMoriah.Waterland@Sun.COM 		 * files and any class action scripts, and suppresses
2699781SMoriah.Waterland@Sun.COM 		 * the running of any class action scripts.  The
2709781SMoriah.Waterland@Sun.COM 		 * package files remain but the package looks like it
2719781SMoriah.Waterland@Sun.COM 		 * is not installed. This is mainly for use by the
2729781SMoriah.Waterland@Sun.COM 		 * upgrade process.
2739781SMoriah.Waterland@Sun.COM 		 */
2749781SMoriah.Waterland@Sun.COM 		case 'F':
2759781SMoriah.Waterland@Sun.COM 		    nodelete++;
2769781SMoriah.Waterland@Sun.COM 		    break;
2779781SMoriah.Waterland@Sun.COM 
2789781SMoriah.Waterland@Sun.COM 		/*
2799781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: Instruct pkgrm not to use the
2809781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the
2819781SMoriah.Waterland@Sun.COM 		 * client's mount points. This option assumes the
2829781SMoriah.Waterland@Sun.COM 		 * mount points are correct on the server and it
2839781SMoriah.Waterland@Sun.COM 		 * behaves consistently with Solaris 2.5 and earlier
2849781SMoriah.Waterland@Sun.COM 		 * releases.
2859781SMoriah.Waterland@Sun.COM 		 */
2869781SMoriah.Waterland@Sun.COM 		case 'M':
2879781SMoriah.Waterland@Sun.COM 		    map_client = 0;
2889781SMoriah.Waterland@Sun.COM 		    break;
2899781SMoriah.Waterland@Sun.COM 
2909781SMoriah.Waterland@Sun.COM 		/*
2919781SMoriah.Waterland@Sun.COM 		 * Different from pkgrm: specify program name to use
2929781SMoriah.Waterland@Sun.COM 		 * for messages.
2939781SMoriah.Waterland@Sun.COM 		 */
2949781SMoriah.Waterland@Sun.COM 		case 'N':
2959781SMoriah.Waterland@Sun.COM 		    (void) set_prog_name(optarg);
2969781SMoriah.Waterland@Sun.COM 		    break;
2979781SMoriah.Waterland@Sun.COM 
2989781SMoriah.Waterland@Sun.COM 		/*
2999781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: package removal occurs in
3009781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
3019781SMoriah.Waterland@Sun.COM 		 * removed files. The default mode is interactive.
3029781SMoriah.Waterland@Sun.COM 		 */
3039781SMoriah.Waterland@Sun.COM 		case 'n':
3049781SMoriah.Waterland@Sun.COM 		    nointeract++;
3059781SMoriah.Waterland@Sun.COM 		    (void) echoSetFlag(B_FALSE);
3069781SMoriah.Waterland@Sun.COM 		    break;
3079781SMoriah.Waterland@Sun.COM 
3089781SMoriah.Waterland@Sun.COM 		/*
3099781SMoriah.Waterland@Sun.COM 		 * Almost same as pkgrm: the -O option allows the behavior
3109781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
3119781SMoriah.Waterland@Sun.COM 		 * -> debug
3129781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
3139781SMoriah.Waterland@Sun.COM 		 * -> preremovecheck
3149781SMoriah.Waterland@Sun.COM 		 * ---> perform a "pre removal" check of the specified
3159781SMoriah.Waterland@Sun.COM 		 * ---> package - suppress all regular output and cause a
3169781SMoriah.Waterland@Sun.COM 		 * ---> series of one or more "name=value" pair format lines
3179781SMoriah.Waterland@Sun.COM 		 * ---> to be output that describes the "removability" of
3189781SMoriah.Waterland@Sun.COM 		 * ---> the specified package
3199781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
3209781SMoriah.Waterland@Sun.COM 		 * --> Enable hollow package support. When specified, for any
3219781SMoriah.Waterland@Sun.COM 		 * --> package that has SUNW_PKG_HOLLOW=true:
3229781SMoriah.Waterland@Sun.COM 		 * --> Do not calculate and verify package size against target
3239781SMoriah.Waterland@Sun.COM 		 * --> Do not run any package procedure or class action scripts
3249781SMoriah.Waterland@Sun.COM 		 * --> Do not create or remove any target directories
3259781SMoriah.Waterland@Sun.COM 		 * --> Do not perform any script locking
3269781SMoriah.Waterland@Sun.COM 		 * --> Do not install or uninstall any components of any package
3279781SMoriah.Waterland@Sun.COM 		 * --> Do not output any status or database update messages
3289781SMoriah.Waterland@Sun.COM 		 */
3299781SMoriah.Waterland@Sun.COM 		case 'O':
3309781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
3319781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
3329781SMoriah.Waterland@Sun.COM 
3339781SMoriah.Waterland@Sun.COM 				/* process debug option */
3349781SMoriah.Waterland@Sun.COM 
3359781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
3369781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
3379781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
3389781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
3399781SMoriah.Waterland@Sun.COM 
3409781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
3419781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
3429781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
3439781SMoriah.Waterland@Sun.COM 					}
3449781SMoriah.Waterland@Sun.COM 
3459781SMoriah.Waterland@Sun.COM 					continue;
3469781SMoriah.Waterland@Sun.COM 				}
3479781SMoriah.Waterland@Sun.COM 
3489781SMoriah.Waterland@Sun.COM 				/* process enable-hollow-package-support opt */
3499781SMoriah.Waterland@Sun.COM 
3509781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
3519781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
3529781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
3539781SMoriah.Waterland@Sun.COM 					continue;
3549781SMoriah.Waterland@Sun.COM 				}
3559781SMoriah.Waterland@Sun.COM 
3569781SMoriah.Waterland@Sun.COM 				/* process preremovecheck option */
3579781SMoriah.Waterland@Sun.COM 
3589781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "preremovecheck") == 0) {
3599781SMoriah.Waterland@Sun.COM 					preremoveCheck = B_TRUE;
3609781SMoriah.Waterland@Sun.COM 					nointeract++;	/* -n */
3619781SMoriah.Waterland@Sun.COM 					nodelete++;	/* -F */
3629781SMoriah.Waterland@Sun.COM 					quitSetSilentExit(B_TRUE);
3639781SMoriah.Waterland@Sun.COM 					continue;
3649781SMoriah.Waterland@Sun.COM 				}
3659781SMoriah.Waterland@Sun.COM 
3669781SMoriah.Waterland@Sun.COM 				/* process addzonename option */
3679781SMoriah.Waterland@Sun.COM 
3689781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "addzonename") == 0) {
3699781SMoriah.Waterland@Sun.COM 					zoneName = z_get_zonename();
3709781SMoriah.Waterland@Sun.COM 					quitSetZoneName(zoneName);
3719781SMoriah.Waterland@Sun.COM 					continue;
3729781SMoriah.Waterland@Sun.COM 				}
3739781SMoriah.Waterland@Sun.COM 
3749781SMoriah.Waterland@Sun.COM 				/* process parent-zone-name option */
3759781SMoriah.Waterland@Sun.COM 
3769781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONENAME,
3779781SMoriah.Waterland@Sun.COM 						PARENTZONENAME_LEN) == 0) {
3789781SMoriah.Waterland@Sun.COM 					parentZoneName = p+PARENTZONENAME_LEN;
3799781SMoriah.Waterland@Sun.COM 					continue;
3809781SMoriah.Waterland@Sun.COM 				}
3819781SMoriah.Waterland@Sun.COM 
3829781SMoriah.Waterland@Sun.COM 				/* process parent-zone-type option */
3839781SMoriah.Waterland@Sun.COM 
3849781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONETYPE,
3859781SMoriah.Waterland@Sun.COM 						PARENTZONETYPE_LEN) == 0) {
3869781SMoriah.Waterland@Sun.COM 					parentZoneType = p+PARENTZONETYPE_LEN;
3879781SMoriah.Waterland@Sun.COM 					continue;
3889781SMoriah.Waterland@Sun.COM 				}
3899781SMoriah.Waterland@Sun.COM 
3909869SCasper.Dik@Sun.COM 				if (strncmp(p, PKGSERV_MODE,
3919869SCasper.Dik@Sun.COM 				    PKGSERV_MODE_LEN) == 0) {
3929869SCasper.Dik@Sun.COM 					pkgserversetmode(pkgparsemode(p +
3939869SCasper.Dik@Sun.COM 					    PKGSERV_MODE_LEN));
3949869SCasper.Dik@Sun.COM 					continue;
3959869SCasper.Dik@Sun.COM 				}
3969781SMoriah.Waterland@Sun.COM 				/* option not recognized - issue warning */
3979781SMoriah.Waterland@Sun.COM 
3989781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
3999781SMoriah.Waterland@Sun.COM 				continue;
4009781SMoriah.Waterland@Sun.COM 			}
4019781SMoriah.Waterland@Sun.COM 			break;
4029781SMoriah.Waterland@Sun.COM 
4039781SMoriah.Waterland@Sun.COM 		/*
4049781SMoriah.Waterland@Sun.COM 		 * Different from pkgrm: This is an old non-ABI package
4059781SMoriah.Waterland@Sun.COM 		 */
4069781SMoriah.Waterland@Sun.COM 
4079781SMoriah.Waterland@Sun.COM 		case 'o':
4089781SMoriah.Waterland@Sun.COM 		    script_in = PROC_XSTDIN;
4099781SMoriah.Waterland@Sun.COM 		    break;
4109781SMoriah.Waterland@Sun.COM 
4119781SMoriah.Waterland@Sun.COM 		/*
4129781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: defines the full path name of a
4139781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
4149781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
4159781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the
4169781SMoriah.Waterland@Sun.COM 		 * specified root_path.
4179781SMoriah.Waterland@Sun.COM 		 */
4189781SMoriah.Waterland@Sun.COM 		case 'R':
4199781SMoriah.Waterland@Sun.COM 		    if (!set_inst_root(optarg)) {
4209781SMoriah.Waterland@Sun.COM 			    progerr(ERR_ROOT_CMD);
4219781SMoriah.Waterland@Sun.COM 			    exit(1);
4229781SMoriah.Waterland@Sun.COM 		    }
4239781SMoriah.Waterland@Sun.COM 		    break;
4249781SMoriah.Waterland@Sun.COM 
4259781SMoriah.Waterland@Sun.COM 		/*
4269781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: allow admin to establish the client
4279781SMoriah.Waterland@Sun.COM 		 * filesystem using a vfstab-like file of stable format.
4289781SMoriah.Waterland@Sun.COM 		 */
4299781SMoriah.Waterland@Sun.COM 		case 'V':
4309781SMoriah.Waterland@Sun.COM 		    vfstab_file = flex_device(optarg, 2);
4319781SMoriah.Waterland@Sun.COM 		    map_client = 1;
4329781SMoriah.Waterland@Sun.COM 		    break;
4339781SMoriah.Waterland@Sun.COM 
4349781SMoriah.Waterland@Sun.COM 		/*
4359781SMoriah.Waterland@Sun.COM 		 * Same as pkgrm: trace all of the scripts that
4369781SMoriah.Waterland@Sun.COM 		 * get executed by pkgrm, located in the
4379781SMoriah.Waterland@Sun.COM 		 * pkginst/install directory. This option is used for
4389781SMoriah.Waterland@Sun.COM 		 * debugging the procedural and non-procedural
4399781SMoriah.Waterland@Sun.COM 		 * scripts.
4409781SMoriah.Waterland@Sun.COM 		 */
4419781SMoriah.Waterland@Sun.COM 		case 'v':
4429781SMoriah.Waterland@Sun.COM 		    pkgverbose++;
4439781SMoriah.Waterland@Sun.COM 		    break;
4449781SMoriah.Waterland@Sun.COM 
4459781SMoriah.Waterland@Sun.COM 		/*
4469781SMoriah.Waterland@Sun.COM 		 * Different from pkgrm: process this package using
4479781SMoriah.Waterland@Sun.COM 		 * old non-ABI symlinks
4489781SMoriah.Waterland@Sun.COM 		 */
4499781SMoriah.Waterland@Sun.COM 		case 'y':
4509781SMoriah.Waterland@Sun.COM 		    set_nonABI_symlinks();
4519781SMoriah.Waterland@Sun.COM 		    break;
4529781SMoriah.Waterland@Sun.COM 
4539781SMoriah.Waterland@Sun.COM 		default:
4549781SMoriah.Waterland@Sun.COM 		    usage();
4559781SMoriah.Waterland@Sun.COM 		    /*NOTREACHED*/
4569781SMoriah.Waterland@Sun.COM 		    /*
4579781SMoriah.Waterland@Sun.COM 		     * Although usage() calls a noreturn function,
4589781SMoriah.Waterland@Sun.COM 		     * needed to add return (1);  so that main() would
4599781SMoriah.Waterland@Sun.COM 		     * pass compilation checks. The statement below
4609781SMoriah.Waterland@Sun.COM    		     * should never be executed.
4619781SMoriah.Waterland@Sun.COM 		     */
4629781SMoriah.Waterland@Sun.COM 		    return (1);
4639781SMoriah.Waterland@Sun.COM 		}
4649781SMoriah.Waterland@Sun.COM 	}
4659781SMoriah.Waterland@Sun.COM 
4669781SMoriah.Waterland@Sun.COM 	/*
4679781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
4689781SMoriah.Waterland@Sun.COM 	 * validate command line options
4699781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
4709781SMoriah.Waterland@Sun.COM 	 */
4719781SMoriah.Waterland@Sun.COM 
4729781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
4739781SMoriah.Waterland@Sun.COM 	(void) log_set_verbose(debugFlag);
4749781SMoriah.Waterland@Sun.COM 
4759781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
4769781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
4779781SMoriah.Waterland@Sun.COM 	} else {
4789781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
4799781SMoriah.Waterland@Sun.COM 			z_get_zonename());
4809781SMoriah.Waterland@Sun.COM 	}
4819781SMoriah.Waterland@Sun.COM 
4829781SMoriah.Waterland@Sun.COM 	/* establish cmdbin path */
4839781SMoriah.Waterland@Sun.COM 
4849781SMoriah.Waterland@Sun.COM 	if (cmdbin[0] == '\0') {
4859781SMoriah.Waterland@Sun.COM 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
4869781SMoriah.Waterland@Sun.COM 	}
4879781SMoriah.Waterland@Sun.COM 
4889781SMoriah.Waterland@Sun.COM 	/* Read the mount table */
4899781SMoriah.Waterland@Sun.COM 
4909781SMoriah.Waterland@Sun.COM 	if (get_mntinfo(map_client, vfstab_file)) {
4919781SMoriah.Waterland@Sun.COM 		quit(99);
4929781SMoriah.Waterland@Sun.COM 	}
4939781SMoriah.Waterland@Sun.COM 
4949781SMoriah.Waterland@Sun.COM 	/*
4959781SMoriah.Waterland@Sun.COM 	 * This function defines the standard /var/... directories used later
4969781SMoriah.Waterland@Sun.COM 	 * to construct the paths to the various databases.
4979781SMoriah.Waterland@Sun.COM 	 */
4989781SMoriah.Waterland@Sun.COM 
4999781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
5009781SMoriah.Waterland@Sun.COM 
5019781SMoriah.Waterland@Sun.COM 	/*
5029781SMoriah.Waterland@Sun.COM 	 * If this is being removed from a client whose /var filesystem is
5039781SMoriah.Waterland@Sun.COM 	 * mounted in some odd way, remap the administrative paths to the
5049781SMoriah.Waterland@Sun.COM 	 * real filesystem. This could be avoided by simply mounting up the
5059781SMoriah.Waterland@Sun.COM 	 * client now; but we aren't yet to the point in the process where
5069781SMoriah.Waterland@Sun.COM 	 * modification of the filesystem is permitted.
5079781SMoriah.Waterland@Sun.COM 	 */
5089781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
5099781SMoriah.Waterland@Sun.COM 		int fsys_value;
5109781SMoriah.Waterland@Sun.COM 
5119781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGLOC());
5129781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
5139781SMoriah.Waterland@Sun.COM 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
5149781SMoriah.Waterland@Sun.COM 
5159781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGADM());
5169781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
5179781SMoriah.Waterland@Sun.COM 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
5189781SMoriah.Waterland@Sun.COM 	} else {
5199781SMoriah.Waterland@Sun.COM 		pkgrmremote = 0;	/* Makes no sense on local host. */
5209781SMoriah.Waterland@Sun.COM 	}
5219781SMoriah.Waterland@Sun.COM 
5229781SMoriah.Waterland@Sun.COM 	/*
5239781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
5249781SMoriah.Waterland@Sun.COM 	 */
5259781SMoriah.Waterland@Sun.COM 
5269781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
5279781SMoriah.Waterland@Sun.COM 
5289781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
5299781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
5309781SMoriah.Waterland@Sun.COM 
5319781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
5329781SMoriah.Waterland@Sun.COM 
5339781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
5349781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
5359781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
5369781SMoriah.Waterland@Sun.COM 
5379781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
5389781SMoriah.Waterland@Sun.COM 
5399781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
5409781SMoriah.Waterland@Sun.COM 
5419781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
5429781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
5439781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
5449781SMoriah.Waterland@Sun.COM 
5459781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
5469781SMoriah.Waterland@Sun.COM 
5479781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
5489781SMoriah.Waterland@Sun.COM 
5499781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
5509781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
5519781SMoriah.Waterland@Sun.COM 
5529781SMoriah.Waterland@Sun.COM 	pkginst = argv[optind++];
5539781SMoriah.Waterland@Sun.COM 	if (optind != argc) {
5549781SMoriah.Waterland@Sun.COM 		usage();
5559781SMoriah.Waterland@Sun.COM 	}
5569781SMoriah.Waterland@Sun.COM 
5579781SMoriah.Waterland@Sun.COM 	/* validate package software database (contents) file */
5589781SMoriah.Waterland@Sun.COM 
5599781SMoriah.Waterland@Sun.COM 	if (vcfile() == 0) {
5609781SMoriah.Waterland@Sun.COM 		quit(99);
5619781SMoriah.Waterland@Sun.COM 	}
5629781SMoriah.Waterland@Sun.COM 
5639781SMoriah.Waterland@Sun.COM 	/*
5649781SMoriah.Waterland@Sun.COM 	 * Acquire the package lock - currently at "remove initialization"
5659781SMoriah.Waterland@Sun.COM 	 */
5669781SMoriah.Waterland@Sun.COM 
5679781SMoriah.Waterland@Sun.COM 	if (!lockinst(get_prog_name(), pkginst, "remove-initial")) {
5689781SMoriah.Waterland@Sun.COM 		quit(99);
5699781SMoriah.Waterland@Sun.COM 	}
5709781SMoriah.Waterland@Sun.COM 
5719781SMoriah.Waterland@Sun.COM 	/* establish temporary directory to use */
5729781SMoriah.Waterland@Sun.COM 
5739781SMoriah.Waterland@Sun.COM 	tmpdir = getenv("TMPDIR");
5749781SMoriah.Waterland@Sun.COM 	if (tmpdir == NULL) {
5759781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
5769781SMoriah.Waterland@Sun.COM 	}
5779781SMoriah.Waterland@Sun.COM 
5789781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir);
5799781SMoriah.Waterland@Sun.COM 
5809781SMoriah.Waterland@Sun.COM 	/*
5819781SMoriah.Waterland@Sun.COM 	 * Initialize installation admin parameters by reading
5829781SMoriah.Waterland@Sun.COM 	 * the adminfile.
5839781SMoriah.Waterland@Sun.COM 	 */
5849781SMoriah.Waterland@Sun.COM 
5859781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : "");
5869781SMoriah.Waterland@Sun.COM 	setadminFile(admnfile);
5879781SMoriah.Waterland@Sun.COM 
5889781SMoriah.Waterland@Sun.COM 	/*
5899781SMoriah.Waterland@Sun.COM 	 * about to perform first operation that could be modified by the
5909781SMoriah.Waterland@Sun.COM 	 * preremove check option - if preremove check is selected (that is,
5919781SMoriah.Waterland@Sun.COM 	 * only gathering dependencies), then output a debug message to
5929781SMoriah.Waterland@Sun.COM 	 * indicate that the check is beginning. Also turn echo() output
5939781SMoriah.Waterland@Sun.COM 	 * off and set various other flags.
5949781SMoriah.Waterland@Sun.COM 	 */
5959781SMoriah.Waterland@Sun.COM 
5969781SMoriah.Waterland@Sun.COM 	if (preremoveCheck == B_TRUE) {
5979781SMoriah.Waterland@Sun.COM 		(void) echoSetFlag(B_FALSE);
5989781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "",
5999781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
6009781SMoriah.Waterland@Sun.COM 		rcksetPreremoveCheck(B_TRUE);
6019781SMoriah.Waterland@Sun.COM 		rcksetZoneName(zoneName);
6029781SMoriah.Waterland@Sun.COM 	}
6039781SMoriah.Waterland@Sun.COM 
6049781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(),
6059781SMoriah.Waterland@Sun.COM 			pkginst);
6069781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc);
6079781SMoriah.Waterland@Sun.COM 	(void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc);
6089781SMoriah.Waterland@Sun.COM 
6099781SMoriah.Waterland@Sun.COM 	if (chdir(pkgbin)) {
6109781SMoriah.Waterland@Sun.COM 		progerr(ERR_CHDIR, pkgbin);
6119781SMoriah.Waterland@Sun.COM 		quit(99);
6129781SMoriah.Waterland@Sun.COM 	}
6139781SMoriah.Waterland@Sun.COM 
6149781SMoriah.Waterland@Sun.COM 	echo(MSG_PREREMOVE_REMINST, pkginst);
6159781SMoriah.Waterland@Sun.COM 
6169781SMoriah.Waterland@Sun.COM 	/*
6179781SMoriah.Waterland@Sun.COM 	 * if a lock file is present, then a previous attempt to remove this
6189781SMoriah.Waterland@Sun.COM 	 * package may have been unsuccessful.
6199781SMoriah.Waterland@Sun.COM 	 */
6209781SMoriah.Waterland@Sun.COM 
6219781SMoriah.Waterland@Sun.COM 	if (access(rlockfile, F_OK) == 0) {
6229781SMoriah.Waterland@Sun.COM 		echo(ERR_UNSUCC);
6239781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile,
6249781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
6259781SMoriah.Waterland@Sun.COM 	}
6269781SMoriah.Waterland@Sun.COM 
6279781SMoriah.Waterland@Sun.COM 	/*
6289781SMoriah.Waterland@Sun.COM 	 * Process all parameters from the pkginfo file
6299781SMoriah.Waterland@Sun.COM 	 * and place them in the execution environment
6309781SMoriah.Waterland@Sun.COM 	 */
6319781SMoriah.Waterland@Sun.COM 
6329781SMoriah.Waterland@Sun.COM 	/* Add DB retreival of the pkginfo parameters here */
6339781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc);
6349781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(path, "r")) == NULL) {
6359781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO, path);
6369781SMoriah.Waterland@Sun.COM 		quit(99);
6379781SMoriah.Waterland@Sun.COM 	}
6389781SMoriah.Waterland@Sun.COM 
6399781SMoriah.Waterland@Sun.COM 	/* Mount up the client if necessary. */
6409781SMoriah.Waterland@Sun.COM 	if (map_client && !mount_client()) {
6419781SMoriah.Waterland@Sun.COM 		logerr(MSG_MANMOUNT);
6429781SMoriah.Waterland@Sun.COM 	}
6439781SMoriah.Waterland@Sun.COM 
6449781SMoriah.Waterland@Sun.COM 	/* Get mount point of client */
6459781SMoriah.Waterland@Sun.COM 	client_mntdir = getenv("CLIENT_MNTDIR");
6469781SMoriah.Waterland@Sun.COM 
6479781SMoriah.Waterland@Sun.COM 	getuserlocale();
6489781SMoriah.Waterland@Sun.COM 
6499781SMoriah.Waterland@Sun.COM 	/*
6509781SMoriah.Waterland@Sun.COM 	 * current environment has been read; clear environment out
6519781SMoriah.Waterland@Sun.COM 	 * so putparam() can be used to populate the new environment
6529781SMoriah.Waterland@Sun.COM 	 * to be passed to any executables/scripts.
6539781SMoriah.Waterland@Sun.COM 	 */
6549781SMoriah.Waterland@Sun.COM 
6559781SMoriah.Waterland@Sun.COM 	environ = NULL;
6569781SMoriah.Waterland@Sun.COM 
6579781SMoriah.Waterland@Sun.COM 	if (nonABI_symlinks()) {
6589781SMoriah.Waterland@Sun.COM 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
6599781SMoriah.Waterland@Sun.COM 	}
6609781SMoriah.Waterland@Sun.COM 
6619781SMoriah.Waterland@Sun.COM 	/*
6629781SMoriah.Waterland@Sun.COM 	 * read the pkginfo file and fix any PKGSAV path - the correct
6639781SMoriah.Waterland@Sun.COM 	 * install_root will be prepended to the existing path.
6649781SMoriah.Waterland@Sun.COM 	 */
6659781SMoriah.Waterland@Sun.COM 
6669781SMoriah.Waterland@Sun.COM 	param[0] = '\0';
6679781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
6689781SMoriah.Waterland@Sun.COM 		int validx = 0;
6699781SMoriah.Waterland@Sun.COM 		char *newvalue;
6709781SMoriah.Waterland@Sun.COM 
6719781SMoriah.Waterland@Sun.COM 		/* strip out any setting of PATH */
6729781SMoriah.Waterland@Sun.COM 
6739781SMoriah.Waterland@Sun.COM 		if (strcmp(param, "PATH") == 0) {
6749781SMoriah.Waterland@Sun.COM 			free(value);
6759781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
6769781SMoriah.Waterland@Sun.COM 			continue;
6779781SMoriah.Waterland@Sun.COM 		}
6789781SMoriah.Waterland@Sun.COM 
6799781SMoriah.Waterland@Sun.COM 		/* if not PKGSAV then write out unchanged */
6809781SMoriah.Waterland@Sun.COM 
6819781SMoriah.Waterland@Sun.COM 		if (strcmp(param, "PKGSAV") != 0) {
6829781SMoriah.Waterland@Sun.COM 			putparam(param, value);
6839781SMoriah.Waterland@Sun.COM 			free(value);
6849781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
6859781SMoriah.Waterland@Sun.COM 			continue;
6869781SMoriah.Waterland@Sun.COM 		}
6879781SMoriah.Waterland@Sun.COM 
6889781SMoriah.Waterland@Sun.COM 		/*
6899781SMoriah.Waterland@Sun.COM 		 * PKGSAV parameter found - interpret the directory:
6909781SMoriah.Waterland@Sun.COM 		 * If in host:path format or marked with the leading "//",
6919781SMoriah.Waterland@Sun.COM 		 * then there is no client-relative translation - take it
6929781SMoriah.Waterland@Sun.COM 		 * literally later rather than use fixpath().
6939781SMoriah.Waterland@Sun.COM 		 */
6949781SMoriah.Waterland@Sun.COM 
6959781SMoriah.Waterland@Sun.COM 		if (strstr(value, ":/")) {
6969781SMoriah.Waterland@Sun.COM 			/* no modification needed */
6979781SMoriah.Waterland@Sun.COM 			validx = 0;
6989781SMoriah.Waterland@Sun.COM 		} else if (strstr(value, "//") == value) {
6999781SMoriah.Waterland@Sun.COM 			validx = 1;
7009781SMoriah.Waterland@Sun.COM 		} else if (is_an_inst_root()) {
7019781SMoriah.Waterland@Sun.COM 			/* This PKGSAV needs to be made client-relative. */
7029781SMoriah.Waterland@Sun.COM 			newvalue = fixpath(value);
7039781SMoriah.Waterland@Sun.COM 			free(value);
7049781SMoriah.Waterland@Sun.COM 			value = newvalue;
7059781SMoriah.Waterland@Sun.COM 		}
7069781SMoriah.Waterland@Sun.COM 		putparam(param, value+validx);
7079781SMoriah.Waterland@Sun.COM 		free(value);
7089781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
7099781SMoriah.Waterland@Sun.COM 	}
7109781SMoriah.Waterland@Sun.COM 
7119781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
7129781SMoriah.Waterland@Sun.COM 
7139781SMoriah.Waterland@Sun.COM 	/* write parent condition information to environment */
7149781SMoriah.Waterland@Sun.COM 
7159781SMoriah.Waterland@Sun.COM 	putConditionInfo(parentZoneName, parentZoneType);
7169781SMoriah.Waterland@Sun.COM 
7179781SMoriah.Waterland@Sun.COM 	putuserlocale();
7189781SMoriah.Waterland@Sun.COM 
7199781SMoriah.Waterland@Sun.COM 	/*
7209781SMoriah.Waterland@Sun.COM 	 * Now do all the various setups based on ABI compliance
7219781SMoriah.Waterland@Sun.COM 	 */
7229781SMoriah.Waterland@Sun.COM 
7239781SMoriah.Waterland@Sun.COM 	/* Read the environment provided by the pkginfo file */
7249781SMoriah.Waterland@Sun.COM 	abi_comp_ptr = getenv("NONABI_SCRIPTS");
7259781SMoriah.Waterland@Sun.COM 
7269781SMoriah.Waterland@Sun.COM 	/* if not ABI compliant set global flag */
7279781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
7289781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
7299781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
7309781SMoriah.Waterland@Sun.COM 	}
7319781SMoriah.Waterland@Sun.COM 
7329781SMoriah.Waterland@Sun.COM 	/*
7339781SMoriah.Waterland@Sun.COM 	 * If pkginfo says it's not compliant then set non_abi_scripts.
7349781SMoriah.Waterland@Sun.COM 	 * Oh, for two releases, set it from exception package names as
7359781SMoriah.Waterland@Sun.COM 	 * well.
7369781SMoriah.Waterland@Sun.COM 	 */
7379781SMoriah.Waterland@Sun.COM 	/*
7389781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
7399781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
7409781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
7419781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
7429781SMoriah.Waterland@Sun.COM 	 */
7439781SMoriah.Waterland@Sun.COM 
7449781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
7459781SMoriah.Waterland@Sun.COM 	if (exception_pkg(pkginst, SCRIPT) ||
7469781SMoriah.Waterland@Sun.COM 	    (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0))
7479781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
7489781SMoriah.Waterland@Sun.COM #else
7499781SMoriah.Waterland@Sun.COM 	if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) {
7509781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
7519781SMoriah.Waterland@Sun.COM 	}
7529781SMoriah.Waterland@Sun.COM #endif
7539781SMoriah.Waterland@Sun.COM 	/*
7549781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
7559781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
7569781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
7579781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
7589781SMoriah.Waterland@Sun.COM 	 */
7599781SMoriah.Waterland@Sun.COM 
7609781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
7619781SMoriah.Waterland@Sun.COM 	/* Until 2.9, set it from the execption list */
7629781SMoriah.Waterland@Sun.COM 	if (exception_pkg(pkginst, LINK)) {
7639781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
7649781SMoriah.Waterland@Sun.COM 	}
7659781SMoriah.Waterland@Sun.COM #endif
7669781SMoriah.Waterland@Sun.COM 
7679781SMoriah.Waterland@Sun.COM 	/*
7689781SMoriah.Waterland@Sun.COM 	 * Since this is a removal, we can tell whether it's absolute or
7699781SMoriah.Waterland@Sun.COM 	 * not from the resident pkginfo file read above.
7709781SMoriah.Waterland@Sun.COM 	 */
7719781SMoriah.Waterland@Sun.COM 	if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir,
7729781SMoriah.Waterland@Sun.COM 	    pkginst, nointeract)) != 0) {
7739781SMoriah.Waterland@Sun.COM 		quit(err);
7749781SMoriah.Waterland@Sun.COM 	}
7759781SMoriah.Waterland@Sun.COM 
7769781SMoriah.Waterland@Sun.COM 	/*
7779781SMoriah.Waterland@Sun.COM 	 * See if were are removing a package that only wants to update
7789781SMoriah.Waterland@Sun.COM 	 * the database or only remove files associated with CAS's. We
7799781SMoriah.Waterland@Sun.COM 	 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
7809781SMoriah.Waterland@Sun.COM 	 * the caller.
7819781SMoriah.Waterland@Sun.COM 	 */
7829781SMoriah.Waterland@Sun.COM 
7839781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
7849781SMoriah.Waterland@Sun.COM 		pt = getenv(PKG_HOLLOW_VARIABLE);
7859781SMoriah.Waterland@Sun.COM 
7869781SMoriah.Waterland@Sun.COM 		if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
7879781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
7889781SMoriah.Waterland@Sun.COM 
7899781SMoriah.Waterland@Sun.COM 			/*
7909781SMoriah.Waterland@Sun.COM 			 * this is a hollow package and hollow package support
7919781SMoriah.Waterland@Sun.COM 			 * is enabled -- override admin settings to suppress
7929781SMoriah.Waterland@Sun.COM 			 * checks that do not make sense since no scripts will
7939781SMoriah.Waterland@Sun.COM 			 * be executed and no files will be removed.
7949781SMoriah.Waterland@Sun.COM 			 */
7959781SMoriah.Waterland@Sun.COM 
7969781SMoriah.Waterland@Sun.COM 			setadminSetting("conflict", "nocheck");
7979781SMoriah.Waterland@Sun.COM 			setadminSetting("setuid", "nocheck");
7989781SMoriah.Waterland@Sun.COM 			setadminSetting("action", "nocheck");
7999781SMoriah.Waterland@Sun.COM 			setadminSetting("partial", "nocheck");
8009781SMoriah.Waterland@Sun.COM 			setadminSetting("space", "nocheck");
8019781SMoriah.Waterland@Sun.COM 			setadminSetting("authentication", "nocheck");
8029781SMoriah.Waterland@Sun.COM 		} else {
8039781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
8049781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_FALSE);
8059781SMoriah.Waterland@Sun.COM 		}
8069781SMoriah.Waterland@Sun.COM 	}
8079781SMoriah.Waterland@Sun.COM 
8089781SMoriah.Waterland@Sun.COM 	put_path_params();
8099781SMoriah.Waterland@Sun.COM 
8109781SMoriah.Waterland@Sun.COM 	/* If client mount point, add it to pkgremove environment */
8119781SMoriah.Waterland@Sun.COM 
8129781SMoriah.Waterland@Sun.COM 	if (client_mntdir != NULL) {
8139781SMoriah.Waterland@Sun.COM 		putparam("CLIENT_MNTDIR", client_mntdir);
8149781SMoriah.Waterland@Sun.COM 	}
8159781SMoriah.Waterland@Sun.COM 
8169781SMoriah.Waterland@Sun.COM 	/* Establish the class list and the class attributes. */
8179781SMoriah.Waterland@Sun.COM 
8189781SMoriah.Waterland@Sun.COM 	if ((value = getenv("CLASSES")) != NULL) {
8199781SMoriah.Waterland@Sun.COM 		cl_sets(qstrdup(value));
8209781SMoriah.Waterland@Sun.COM 	} else {
8219781SMoriah.Waterland@Sun.COM 		progerr(ERR_CLASSES, path);
8229781SMoriah.Waterland@Sun.COM 		quit(99);
8239781SMoriah.Waterland@Sun.COM 	}
8249781SMoriah.Waterland@Sun.COM 
8259781SMoriah.Waterland@Sun.COM 	/* establish path and tmpdir */
8269781SMoriah.Waterland@Sun.COM 
8279781SMoriah.Waterland@Sun.COM 	if (cmdbin[0] == '\0') {
8289781SMoriah.Waterland@Sun.COM 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
8299781SMoriah.Waterland@Sun.COM 	}
8309781SMoriah.Waterland@Sun.COM 
8319781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
8329781SMoriah.Waterland@Sun.COM 	putparam("PATH", path);
8339781SMoriah.Waterland@Sun.COM 
8349781SMoriah.Waterland@Sun.COM 	putparam("TMPDIR", tmpdir);
8359781SMoriah.Waterland@Sun.COM 
8369781SMoriah.Waterland@Sun.COM 	/*
8379781SMoriah.Waterland@Sun.COM 	 * Check ulimit requirement (provided in pkginfo). The purpose of
8389781SMoriah.Waterland@Sun.COM 	 * this limit is to terminate pathological file growth resulting from
8399781SMoriah.Waterland@Sun.COM 	 * file edits in scripts. It does not apply to files in the pkgmap
8409781SMoriah.Waterland@Sun.COM 	 * and it does not apply to any database files manipulated by the
8419781SMoriah.Waterland@Sun.COM 	 * installation service.
8429781SMoriah.Waterland@Sun.COM 	 */
8439781SMoriah.Waterland@Sun.COM 	if (value = getenv("ULIMIT")) {
8449781SMoriah.Waterland@Sun.COM 		if (assign_ulimit(value) == -1) {
8459781SMoriah.Waterland@Sun.COM 			progerr(ERR_BADULIMIT, value);
8469781SMoriah.Waterland@Sun.COM 			warnflag++;
8479781SMoriah.Waterland@Sun.COM 		}
8489781SMoriah.Waterland@Sun.COM 		putparam("PKG_ULIMIT", "TRUE");
8499781SMoriah.Waterland@Sun.COM 	}
8509781SMoriah.Waterland@Sun.COM 
8519781SMoriah.Waterland@Sun.COM 	/*
8529781SMoriah.Waterland@Sun.COM 	 * If only gathering dependencies, check and output status of all
8539781SMoriah.Waterland@Sun.COM 	 * remaining dependencies and exit.
8549781SMoriah.Waterland@Sun.COM 	 */
8559781SMoriah.Waterland@Sun.COM 
8569781SMoriah.Waterland@Sun.COM 	if (preremoveCheck == B_TRUE) {
8579781SMoriah.Waterland@Sun.COM 		/*
8589781SMoriah.Waterland@Sun.COM 		 * make sure current runlevel is appropriate
8599781SMoriah.Waterland@Sun.COM 		 */
8609781SMoriah.Waterland@Sun.COM 
8619781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel());
8629781SMoriah.Waterland@Sun.COM 
8639781SMoriah.Waterland@Sun.COM 		/*
8649781SMoriah.Waterland@Sun.COM 		 * determine if any packaging scripts provided with
8659781SMoriah.Waterland@Sun.COM 		 * this package will execute as a priviledged user
8669781SMoriah.Waterland@Sun.COM 		 */
8679781SMoriah.Waterland@Sun.COM 
8689781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "rckpriv=%d\n", rckpriv());
8699781SMoriah.Waterland@Sun.COM 
8709781SMoriah.Waterland@Sun.COM 		/*
8719781SMoriah.Waterland@Sun.COM 		 * verify package dependencies
8729781SMoriah.Waterland@Sun.COM 		 */
8739781SMoriah.Waterland@Sun.COM 
8749781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "rckdepend=%d\n", rckdepend());
8759781SMoriah.Waterland@Sun.COM 
8769781SMoriah.Waterland@Sun.COM 		/*
8779781SMoriah.Waterland@Sun.COM 		 * ****** preremove check done - exit ******
8789781SMoriah.Waterland@Sun.COM 		 */
8799781SMoriah.Waterland@Sun.COM 
8809781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PRERMCHK_OK);
8819781SMoriah.Waterland@Sun.COM 		quit(0);
8829781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
8839781SMoriah.Waterland@Sun.COM 	}
8849781SMoriah.Waterland@Sun.COM 
8859781SMoriah.Waterland@Sun.COM 	/*
8869781SMoriah.Waterland@Sun.COM 	 * Not gathering dependencies only, proceed to check dependencies
8879781SMoriah.Waterland@Sun.COM 	 * and continue with the package removal operation.
8889781SMoriah.Waterland@Sun.COM 	 */
8899781SMoriah.Waterland@Sun.COM 
8909781SMoriah.Waterland@Sun.COM 	/*
8919781SMoriah.Waterland@Sun.COM 	 * make sure current runlevel is appropriate
8929781SMoriah.Waterland@Sun.COM 	 */
8939781SMoriah.Waterland@Sun.COM 
8949781SMoriah.Waterland@Sun.COM 	n = rckrunlevel();
8959781SMoriah.Waterland@Sun.COM 
8969781SMoriah.Waterland@Sun.COM 	if (n != 0) {
8979781SMoriah.Waterland@Sun.COM 		quit(n);
8989781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
8999781SMoriah.Waterland@Sun.COM 	}
9009781SMoriah.Waterland@Sun.COM 
9019781SMoriah.Waterland@Sun.COM 	/*
9029781SMoriah.Waterland@Sun.COM 	 * determine if any packaging scripts provided with
9039781SMoriah.Waterland@Sun.COM 	 * this package will execute as a priviledged user
9049781SMoriah.Waterland@Sun.COM 	 */
9059781SMoriah.Waterland@Sun.COM 
9069781SMoriah.Waterland@Sun.COM 	n = rckpriv();
9079781SMoriah.Waterland@Sun.COM 
9089781SMoriah.Waterland@Sun.COM 	if (n != 0) {
9099781SMoriah.Waterland@Sun.COM 		quit(n);
9109781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
9119781SMoriah.Waterland@Sun.COM 	}
9129781SMoriah.Waterland@Sun.COM 
9139781SMoriah.Waterland@Sun.COM 	/*
9149781SMoriah.Waterland@Sun.COM 	 * verify package dependencies
9159781SMoriah.Waterland@Sun.COM 	 */
9169781SMoriah.Waterland@Sun.COM 	n = rckdepend();
9179781SMoriah.Waterland@Sun.COM 
9189781SMoriah.Waterland@Sun.COM 	if (n != 0) {
9199781SMoriah.Waterland@Sun.COM 		quit(n);
9209781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
9219781SMoriah.Waterland@Sun.COM 	}
9229781SMoriah.Waterland@Sun.COM 
9239781SMoriah.Waterland@Sun.COM 	/*
9249781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
9259781SMoriah.Waterland@Sun.COM 	 * the actual removal of the package begins here
9269781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
9279781SMoriah.Waterland@Sun.COM 	 */
9289781SMoriah.Waterland@Sun.COM 
9299781SMoriah.Waterland@Sun.COM 	/*
9309781SMoriah.Waterland@Sun.COM 	 * create lockfile to indicate start of removal
9319781SMoriah.Waterland@Sun.COM 	 */
9329781SMoriah.Waterland@Sun.COM 	started++;
9339781SMoriah.Waterland@Sun.COM 	if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
9349781SMoriah.Waterland@Sun.COM 		progerr(ERR_LOCKFILE, rlockfile);
9359781SMoriah.Waterland@Sun.COM 		quit(99);
9369781SMoriah.Waterland@Sun.COM 	} else {
9379781SMoriah.Waterland@Sun.COM 		(void) close(fd);
9389781SMoriah.Waterland@Sun.COM 	}
9399781SMoriah.Waterland@Sun.COM 
9409781SMoriah.Waterland@Sun.COM 	if (zoneName == (char *)NULL) {
9419781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_PROCPKG_GZ);
9429781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile);
9439781SMoriah.Waterland@Sun.COM 	} else {
9449781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName);
9459781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile,
9469781SMoriah.Waterland@Sun.COM 			zoneName);
9479781SMoriah.Waterland@Sun.COM 	}
9489869SCasper.Dik@Sun.COM 	if (delmap(0, pkginst, &pkgserver, &tmpfp) != 0) {
9499781SMoriah.Waterland@Sun.COM 		progerr(ERR_DB_QUERY, pkginst);
9509781SMoriah.Waterland@Sun.COM 		quit(99);
9519781SMoriah.Waterland@Sun.COM 	}
9529781SMoriah.Waterland@Sun.COM 
9539781SMoriah.Waterland@Sun.COM 	/*
9549781SMoriah.Waterland@Sun.COM 	 * Run a preremove script if one is provided by the package.
9559781SMoriah.Waterland@Sun.COM 	 * Don't execute preremove script if only updating the DB.
9569781SMoriah.Waterland@Sun.COM 	 * Don't execute preremove script if files are not being deleted.
9579781SMoriah.Waterland@Sun.COM 	 */
9589781SMoriah.Waterland@Sun.COM 
9599781SMoriah.Waterland@Sun.COM 	/* update the lock - at the preremove script */
9609781SMoriah.Waterland@Sun.COM 	lockupd("preremove");
9619781SMoriah.Waterland@Sun.COM 
9629781SMoriah.Waterland@Sun.COM 	/* execute preremove script if one is provided */
9639781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/preremove", pkgbin);
9649781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) != 0) {
9659781SMoriah.Waterland@Sun.COM 		/* no script present */
9669781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst,
9679781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
9689781SMoriah.Waterland@Sun.COM 	} else if (nodelete) {
9699781SMoriah.Waterland@Sun.COM 		/* not deleting files: skip preremove script */
9709781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script,
9719781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
9729781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
9739781SMoriah.Waterland@Sun.COM 		/* updating db only: skip preremove script */
9749781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script,
9759781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
9769781SMoriah.Waterland@Sun.COM 	} else {
9779781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
9789781SMoriah.Waterland@Sun.COM 		set_ulimit("preremove", ERR_PREREMOVE);
9799781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
9809781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGREMOVE_EXEPOC_GZ);
9819781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script);
9829781SMoriah.Waterland@Sun.COM 		} else {
9839781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName);
9849781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script,
9859781SMoriah.Waterland@Sun.COM 				zoneName);
9869781SMoriah.Waterland@Sun.COM 		}
9879781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_SCRIPT", "preremove");
9889781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
9899781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
9909781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, "-x",
9919781SMoriah.Waterland@Sun.COM 				script, NULL), ERR_PREREMOVE);
9929781SMoriah.Waterland@Sun.COM 		} else {
9939781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
9949781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, script,
9959781SMoriah.Waterland@Sun.COM 				NULL), ERR_PREREMOVE);
9969781SMoriah.Waterland@Sun.COM 		}
9979781SMoriah.Waterland@Sun.COM 		clr_ulimit();
9989781SMoriah.Waterland@Sun.COM 	}
9999781SMoriah.Waterland@Sun.COM 
10009781SMoriah.Waterland@Sun.COM 	/* update the lock - doing removal */
10019781SMoriah.Waterland@Sun.COM 
10029781SMoriah.Waterland@Sun.COM 	lockupd("remove");
10039781SMoriah.Waterland@Sun.COM 
10049781SMoriah.Waterland@Sun.COM 	/*
10059781SMoriah.Waterland@Sun.COM 	 * Ensure that the contents file is updated even if the db has
10069781SMoriah.Waterland@Sun.COM 	 * been upgraded, in the case that there are relevant entries
10079781SMoriah.Waterland@Sun.COM 	 * in a special_contents file.  The return value is ignored
10089781SMoriah.Waterland@Sun.COM 	 * since we do not want special_contents operation to prevent
10099781SMoriah.Waterland@Sun.COM 	 * pkgremove from succeeding.  We do report errors to stderr.
10109781SMoriah.Waterland@Sun.COM 	 */
10119781SMoriah.Waterland@Sun.COM 
10129781SMoriah.Waterland@Sun.COM 	/*
10139781SMoriah.Waterland@Sun.COM 	 * Remove all components belonging to this package.
10149781SMoriah.Waterland@Sun.COM 	 * Don't remove components if only updating the DB.
10159781SMoriah.Waterland@Sun.COM 	 * Don't remove components if files are not being deleted.
10169781SMoriah.Waterland@Sun.COM 	 */
10179781SMoriah.Waterland@Sun.COM 
10189781SMoriah.Waterland@Sun.COM 	if (nodelete) {
10199781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst,
10209781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10219781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
10229781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst,
10239781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10249781SMoriah.Waterland@Sun.COM 	} else {
10259781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_REM, pkginst,
10269781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10279781SMoriah.Waterland@Sun.COM 		/*
10289781SMoriah.Waterland@Sun.COM 		 * remove package one class at a time
10299781SMoriah.Waterland@Sun.COM 		 */
10309781SMoriah.Waterland@Sun.COM 
10319781SMoriah.Waterland@Sun.COM 		/* reverse order of classes */
10329781SMoriah.Waterland@Sun.COM 		for (i = cl_getn() - 1; i >= 0; i--) {
10339781SMoriah.Waterland@Sun.COM 			rmclass(cl_nam(i), pkgrmremote, zoneName);
10349781SMoriah.Waterland@Sun.COM 		}
10359781SMoriah.Waterland@Sun.COM 
10369781SMoriah.Waterland@Sun.COM 		rmclass(NULL, pkgrmremote, zoneName);
10379781SMoriah.Waterland@Sun.COM 	}
10389781SMoriah.Waterland@Sun.COM 
10399781SMoriah.Waterland@Sun.COM 	z_destroyMountTable();
10409781SMoriah.Waterland@Sun.COM 
10419781SMoriah.Waterland@Sun.COM 	/*
10429781SMoriah.Waterland@Sun.COM 	 * Execute postremove script, if any
10439781SMoriah.Waterland@Sun.COM 	 * Don't execute postremove script if only updating the DB.
10449781SMoriah.Waterland@Sun.COM 	 * Don't execute postremove script if files are not being deleted.
10459781SMoriah.Waterland@Sun.COM 	 */
10469781SMoriah.Waterland@Sun.COM 
10479781SMoriah.Waterland@Sun.COM 	/* update the lock - at the postremove script */
10489781SMoriah.Waterland@Sun.COM 	lockupd("postremove");
10499781SMoriah.Waterland@Sun.COM 
10509781SMoriah.Waterland@Sun.COM 	/* execute postremove script if one is provided */
10519781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/postremove", pkgbin);
10529781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) != 0) {
10539781SMoriah.Waterland@Sun.COM 		/* no script present */
10549781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst,
10559781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10569781SMoriah.Waterland@Sun.COM 	} else if (nodelete) {
10579781SMoriah.Waterland@Sun.COM 		/* not deleting files: skip postremove script */
10589781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script,
10599781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10609781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
10619781SMoriah.Waterland@Sun.COM 		/* updating db only: skip postremove script */
10629781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script,
10639781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
10649781SMoriah.Waterland@Sun.COM 	} else {
10659781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
10669781SMoriah.Waterland@Sun.COM 		set_ulimit("postremove", ERR_POSTREMOVE);
10679781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
10689781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGREMOVE_EXEPIC_GZ);
10699781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script);
10709781SMoriah.Waterland@Sun.COM 		} else {
10719781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName);
10729781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script,
10739781SMoriah.Waterland@Sun.COM 				zoneName);
10749781SMoriah.Waterland@Sun.COM 		}
10759781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_SCRIPT", "postremove");
10769781SMoriah.Waterland@Sun.COM 		putparam("TMPDIR", tmpdir);
10779781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
10789781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
10799781SMoriah.Waterland@Sun.COM 			    PROC_GRP, SHELL, "-x", script, NULL),
10809781SMoriah.Waterland@Sun.COM 			    ERR_POSTREMOVE);
10819781SMoriah.Waterland@Sun.COM 		} else {
10829781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
10839781SMoriah.Waterland@Sun.COM 			    PROC_GRP, SHELL, script, NULL),
10849781SMoriah.Waterland@Sun.COM 			    ERR_POSTREMOVE);
10859781SMoriah.Waterland@Sun.COM 		}
10869781SMoriah.Waterland@Sun.COM 		clr_ulimit();
10879781SMoriah.Waterland@Sun.COM 	}
10889781SMoriah.Waterland@Sun.COM 
10899781SMoriah.Waterland@Sun.COM 	if (zoneName == (char *)NULL) {
10909781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_UPDINF_GZ);
10919781SMoriah.Waterland@Sun.COM 	} else {
10929781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName);
10939781SMoriah.Waterland@Sun.COM 	}
10949781SMoriah.Waterland@Sun.COM 
10959869SCasper.Dik@Sun.COM 	if (delmap(1, pkginst, &pkgserver, &tmpfp) != 0) {
10969781SMoriah.Waterland@Sun.COM 		progerr(ERR_DB_QUERY, pkginst);
10979781SMoriah.Waterland@Sun.COM 		quit(99);
10989781SMoriah.Waterland@Sun.COM 	}
10999781SMoriah.Waterland@Sun.COM 
11009781SMoriah.Waterland@Sun.COM 	if (!warnflag && !failflag) {
11019781SMoriah.Waterland@Sun.COM 		if (pt = getenv("PREDEPEND"))
11029781SMoriah.Waterland@Sun.COM 			predepend(pt);
11039781SMoriah.Waterland@Sun.COM 		(void) chdir("/");
11049781SMoriah.Waterland@Sun.COM 		if (rrmdir(pkgloc))
11059781SMoriah.Waterland@Sun.COM 			warnflag++;
11069781SMoriah.Waterland@Sun.COM 	}
11079781SMoriah.Waterland@Sun.COM 
11089781SMoriah.Waterland@Sun.COM 	if ((z_running_in_global_zone() == B_TRUE) &&
11099781SMoriah.Waterland@Sun.COM 		(pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) {
11109781SMoriah.Waterland@Sun.COM 		boolean_t	b;
11119781SMoriah.Waterland@Sun.COM 
11129781SMoriah.Waterland@Sun.COM 		b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst);
11139781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
11149781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst);
11159781SMoriah.Waterland@Sun.COM 			ckreturn(1, NULL);
11169781SMoriah.Waterland@Sun.COM 		}
11179781SMoriah.Waterland@Sun.COM 	}
11189781SMoriah.Waterland@Sun.COM 
11199781SMoriah.Waterland@Sun.COM 	/* release the generic package lock */
11209781SMoriah.Waterland@Sun.COM 
11219781SMoriah.Waterland@Sun.COM 	(void) unlockinst();
11229781SMoriah.Waterland@Sun.COM 
11239869SCasper.Dik@Sun.COM 	pkgcloseserver(pkgserver);
11249869SCasper.Dik@Sun.COM 
11259781SMoriah.Waterland@Sun.COM 	quit(0);
11269781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
11279781SMoriah.Waterland@Sun.COM }
11289781SMoriah.Waterland@Sun.COM 
11299781SMoriah.Waterland@Sun.COM int
issymlink(char * path)11309781SMoriah.Waterland@Sun.COM issymlink(char *path)
11319781SMoriah.Waterland@Sun.COM {
11329781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
11339781SMoriah.Waterland@Sun.COM 
11349781SMoriah.Waterland@Sun.COM 	/*
11359781SMoriah.Waterland@Sun.COM 	 * Obtain status of path; if symbolic link get link's status
11369781SMoriah.Waterland@Sun.COM 	 */
11379781SMoriah.Waterland@Sun.COM 
11389781SMoriah.Waterland@Sun.COM 	if (lstat(path, &statbuf) != 0) {
11399781SMoriah.Waterland@Sun.COM 		return (1);	/* not symlink */
11409781SMoriah.Waterland@Sun.COM 	}
11419781SMoriah.Waterland@Sun.COM 
11429781SMoriah.Waterland@Sun.COM 	/*
11439781SMoriah.Waterland@Sun.COM 	 * Status obtained - if symbolic link, return 0
11449781SMoriah.Waterland@Sun.COM 	 */
11459781SMoriah.Waterland@Sun.COM 
11469781SMoriah.Waterland@Sun.COM 	if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
11479781SMoriah.Waterland@Sun.COM 		return (0);	/* is a symlink */
11489781SMoriah.Waterland@Sun.COM 	}
11499781SMoriah.Waterland@Sun.COM 
11509781SMoriah.Waterland@Sun.COM 	/*
11519781SMoriah.Waterland@Sun.COM 	 * Not a symbolic link - return 1
11529781SMoriah.Waterland@Sun.COM 	 */
11539781SMoriah.Waterland@Sun.COM 
11549781SMoriah.Waterland@Sun.COM 	return (1);		/* not symlink */
11559781SMoriah.Waterland@Sun.COM }
11569781SMoriah.Waterland@Sun.COM 
11579781SMoriah.Waterland@Sun.COM static void
rmclass(char * aclass,int rm_remote,char * a_zoneName)11589781SMoriah.Waterland@Sun.COM rmclass(char *aclass, int rm_remote, char *a_zoneName)
11599781SMoriah.Waterland@Sun.COM {
11609781SMoriah.Waterland@Sun.COM 	struct cfent	*ept;
11619781SMoriah.Waterland@Sun.COM 	FILE	*fp;
11629781SMoriah.Waterland@Sun.COM 	char	tmpfile[PATH_MAX];
11639781SMoriah.Waterland@Sun.COM 	char	script[PATH_MAX];
11649781SMoriah.Waterland@Sun.COM 	int	i;
11659781SMoriah.Waterland@Sun.COM 	char	*tmp_path;
11669781SMoriah.Waterland@Sun.COM 	char	*save_path = NULL;
11679781SMoriah.Waterland@Sun.COM 	struct stat st;
11689781SMoriah.Waterland@Sun.COM 
11699781SMoriah.Waterland@Sun.COM 	if (aclass == NULL) {
11709781SMoriah.Waterland@Sun.COM 		for (i = 0; i < eptnum; i++) {
11719781SMoriah.Waterland@Sun.COM 			if (eptlist[i] != NULL) {
11729781SMoriah.Waterland@Sun.COM 				rmclass(eptlist[i]->pkg_class,
11739781SMoriah.Waterland@Sun.COM 					rm_remote, a_zoneName);
11749781SMoriah.Waterland@Sun.COM 			}
11759781SMoriah.Waterland@Sun.COM 		}
11769781SMoriah.Waterland@Sun.COM 		return;
11779781SMoriah.Waterland@Sun.COM 	}
11789781SMoriah.Waterland@Sun.COM 
11799781SMoriah.Waterland@Sun.COM 	/* locate class action script to execute */
11809781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/r.%s", pkgbin, aclass);
11819781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) != 0) {
11829781SMoriah.Waterland@Sun.COM 		(void) snprintf(script, sizeof (script), "%s/r.%s",
11839781SMoriah.Waterland@Sun.COM 		    PKGSCR, aclass);
11849781SMoriah.Waterland@Sun.COM 		if (access(script, F_OK) != 0)
11859781SMoriah.Waterland@Sun.COM 			script[0] = '\0';
11869781SMoriah.Waterland@Sun.COM 	}
11879781SMoriah.Waterland@Sun.COM 	if (script[0] != '\0') {
11889781SMoriah.Waterland@Sun.COM 		int td;
11899781SMoriah.Waterland@Sun.COM 
11909781SMoriah.Waterland@Sun.COM 		(void) snprintf(tmpfile, sizeof (tmpfile), "%s/RMLISTXXXXXX",
11919781SMoriah.Waterland@Sun.COM 		    tmpdir);
11929781SMoriah.Waterland@Sun.COM 		td = mkstemp(tmpfile);
11939781SMoriah.Waterland@Sun.COM 		if (td == -1) {
11949781SMoriah.Waterland@Sun.COM 			progerr(ERR_TMPFILE);
11959781SMoriah.Waterland@Sun.COM 			quit(99);
11969781SMoriah.Waterland@Sun.COM 		}
11979781SMoriah.Waterland@Sun.COM 		if ((fp = fdopen(td, "w")) == NULL) {
11989781SMoriah.Waterland@Sun.COM 			progerr(ERR_WTMPFILE, tmpfile);
11999781SMoriah.Waterland@Sun.COM 			quit(99);
12009781SMoriah.Waterland@Sun.COM 		}
12019781SMoriah.Waterland@Sun.COM 	}
12029781SMoriah.Waterland@Sun.COM 
12039781SMoriah.Waterland@Sun.COM 	if (a_zoneName == (char *)NULL) {
12049781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_REMPATHCLASS_GZ, aclass);
12059781SMoriah.Waterland@Sun.COM 	} else {
12069781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGREMOVE_REMPATHCLASS_LZ, aclass, a_zoneName);
12079781SMoriah.Waterland@Sun.COM 	}
12089781SMoriah.Waterland@Sun.COM 
12099781SMoriah.Waterland@Sun.COM 	/* process paths in reverse order */
12109781SMoriah.Waterland@Sun.COM 	i = eptnum;
12119781SMoriah.Waterland@Sun.COM 	while (--i >= 0) {
12129781SMoriah.Waterland@Sun.COM 		ept = eptlist[i];
12139781SMoriah.Waterland@Sun.COM 
12149781SMoriah.Waterland@Sun.COM 		if ((ept == NULL) || strcmp(aclass, ept->pkg_class)) {
12159781SMoriah.Waterland@Sun.COM 			continue;
12169781SMoriah.Waterland@Sun.COM 		}
12179781SMoriah.Waterland@Sun.COM 
12189781SMoriah.Waterland@Sun.COM 		/* save the path, and prepend the ir */
12199781SMoriah.Waterland@Sun.COM 		if (is_an_inst_root()) {
12209781SMoriah.Waterland@Sun.COM 			save_path = ept->path;
12219781SMoriah.Waterland@Sun.COM 			tmp_path = fixpath(ept->path);
12229781SMoriah.Waterland@Sun.COM 			ept->path = tmp_path;
12239781SMoriah.Waterland@Sun.COM 		}
12249781SMoriah.Waterland@Sun.COM 
12259781SMoriah.Waterland@Sun.COM 		if (!ept->ftype || (ept->ftype == '^' && !script[0])) {
12269781SMoriah.Waterland@Sun.COM 			/*
12279781SMoriah.Waterland@Sun.COM 			 * A path owned by more than one package is marked with
12289781SMoriah.Waterland@Sun.COM 			 * a NULL ftype (seems odd, but that's how it's
12299781SMoriah.Waterland@Sun.COM 			 * done). Such files are sacro sanct. Shared editable
12309781SMoriah.Waterland@Sun.COM 			 * files are a special case, and are marked with an
12319781SMoriah.Waterland@Sun.COM 			 * ftype of '^'. These files should only be ignored if
12329781SMoriah.Waterland@Sun.COM 			 * no class action script is present. It is the CAS's
12339781SMoriah.Waterland@Sun.COM 			 * responsibility to not remove the editable object.
12349781SMoriah.Waterland@Sun.COM 			 */
12359781SMoriah.Waterland@Sun.COM 			echo(MSG_SHARED, ept->path);
12369781SMoriah.Waterland@Sun.COM 		} else if (ept->pinfo->status == SERVED_FILE && !rm_remote) {
12379781SMoriah.Waterland@Sun.COM 			/*
12389781SMoriah.Waterland@Sun.COM 			 * If the path is provided to the client from a
12399781SMoriah.Waterland@Sun.COM 			 * server, don't remove anything unless explicitly
12409781SMoriah.Waterland@Sun.COM 			 * requested through the "-f" option.
12419781SMoriah.Waterland@Sun.COM 			 */
12429781SMoriah.Waterland@Sun.COM 			echo(MSG_SERVER, ept->path);
12439781SMoriah.Waterland@Sun.COM 		} else if (script[0]) {
12449781SMoriah.Waterland@Sun.COM 			/*
12459781SMoriah.Waterland@Sun.COM 			 * If there's a class action script, just put the
12469781SMoriah.Waterland@Sun.COM 			 * path name into the list.
12479781SMoriah.Waterland@Sun.COM 			 */
12489781SMoriah.Waterland@Sun.COM 			(void) fprintf(fp, "%s\n", ept->path);
12499781SMoriah.Waterland@Sun.COM 		} else if (strchr("dx", ept->ftype) != NULL ||
12509781SMoriah.Waterland@Sun.COM 		    (lstat(ept->path, &st) == 0 && S_ISDIR(st.st_mode))) {
12519781SMoriah.Waterland@Sun.COM 			/* Directories are rmdir()'d. */
12529781SMoriah.Waterland@Sun.COM 
12539781SMoriah.Waterland@Sun.COM 			if (rmdir(ept->path)) {
12549781SMoriah.Waterland@Sun.COM 				if (errno == EBUSY) {
12559781SMoriah.Waterland@Sun.COM 					echo(MSG_DIRBUSY, ept->path);
12569781SMoriah.Waterland@Sun.COM 				} else if (errno == EEXIST) {
12579781SMoriah.Waterland@Sun.COM 					echo(MSG_NOTEMPTY, ept->path);
12589781SMoriah.Waterland@Sun.COM 				} else if (errno != ENOENT) {
12599781SMoriah.Waterland@Sun.COM 					progerr(ERR_RMDIR, ept->path);
12609781SMoriah.Waterland@Sun.COM 					warnflag++;
12619781SMoriah.Waterland@Sun.COM 				}
12629781SMoriah.Waterland@Sun.COM 			} else {
12639781SMoriah.Waterland@Sun.COM 				if (ept->pinfo->status == SERVED_FILE) {
12649781SMoriah.Waterland@Sun.COM 					echo(MSG_RMSRVR, ept->path);
12659781SMoriah.Waterland@Sun.COM 				} else {
12669781SMoriah.Waterland@Sun.COM 					echo("%s", ept->path);
12679781SMoriah.Waterland@Sun.COM 				}
12689781SMoriah.Waterland@Sun.COM 			}
12699781SMoriah.Waterland@Sun.COM 
12709781SMoriah.Waterland@Sun.COM 		} else {
12719781SMoriah.Waterland@Sun.COM 			/*
12729781SMoriah.Waterland@Sun.COM 			 * Before removing this object one more
12739781SMoriah.Waterland@Sun.COM 			 * check should be done to assure that a
12749781SMoriah.Waterland@Sun.COM 			 * shared object is not removed.
12759781SMoriah.Waterland@Sun.COM 			 * This can happen if the original object
12769781SMoriah.Waterland@Sun.COM 			 * was incorrectly updated with the
12779781SMoriah.Waterland@Sun.COM 			 * incorrect class identifier.
12789781SMoriah.Waterland@Sun.COM 			 * This handles pathologcal cases that
12799781SMoriah.Waterland@Sun.COM 			 * weren't handled above.
12809781SMoriah.Waterland@Sun.COM 			 */
12819781SMoriah.Waterland@Sun.COM 			if (ept->npkgs > 1) {
12829781SMoriah.Waterland@Sun.COM 				echo(MSG_SHARED, ept->path);
12839781SMoriah.Waterland@Sun.COM 				continue;
12849781SMoriah.Waterland@Sun.COM 			}
12859781SMoriah.Waterland@Sun.COM 
12869781SMoriah.Waterland@Sun.COM 			/* Regular files are unlink()'d. */
12879781SMoriah.Waterland@Sun.COM 
12889781SMoriah.Waterland@Sun.COM 			if (unlink(ept->path)) {
12899781SMoriah.Waterland@Sun.COM 				if (errno != ENOENT) {
12909781SMoriah.Waterland@Sun.COM 					progerr(ERR_RMPATH, ept->path);
12919781SMoriah.Waterland@Sun.COM 					warnflag++;
12929781SMoriah.Waterland@Sun.COM 				}
12939781SMoriah.Waterland@Sun.COM 			} else {
12949781SMoriah.Waterland@Sun.COM 				if (ept->pinfo->status == SERVED_FILE) {
12959781SMoriah.Waterland@Sun.COM 					echo(MSG_RMSRVR, ept->path);
12969781SMoriah.Waterland@Sun.COM 				} else {
12979781SMoriah.Waterland@Sun.COM 					echo("%s", ept->path);
12989781SMoriah.Waterland@Sun.COM 				}
12999781SMoriah.Waterland@Sun.COM 			}
13009781SMoriah.Waterland@Sun.COM 		}
13019781SMoriah.Waterland@Sun.COM 
13029781SMoriah.Waterland@Sun.COM 		/* restore the original path */
13039781SMoriah.Waterland@Sun.COM 
13049781SMoriah.Waterland@Sun.COM 		if (is_an_inst_root()) {
13059781SMoriah.Waterland@Sun.COM 			ept->path = save_path;
13069781SMoriah.Waterland@Sun.COM 		}
13079781SMoriah.Waterland@Sun.COM 
13089781SMoriah.Waterland@Sun.COM 		/*
13099781SMoriah.Waterland@Sun.COM 		 * free memory allocated for this entry memory used for
13109781SMoriah.Waterland@Sun.COM 		 * pathnames will be freed later by a call to pathdup()
13119781SMoriah.Waterland@Sun.COM 		 */
13129781SMoriah.Waterland@Sun.COM 
13139781SMoriah.Waterland@Sun.COM 		if (eptlist[i]) {
13149781SMoriah.Waterland@Sun.COM 			free(eptlist[i]);
13159781SMoriah.Waterland@Sun.COM 		}
13169781SMoriah.Waterland@Sun.COM 		eptlist[i] = NULL;
13179781SMoriah.Waterland@Sun.COM 	}
13189781SMoriah.Waterland@Sun.COM 	if (script[0]) {
13199781SMoriah.Waterland@Sun.COM 		(void) fclose(fp);
13209781SMoriah.Waterland@Sun.COM 		set_ulimit(script, ERR_CASFAIL);
13219781SMoriah.Waterland@Sun.COM 		if (pkgverbose)
13229781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER,
13239781SMoriah.Waterland@Sun.COM 			    CAS_GRP, SHELL, "-x", script, NULL),
13249781SMoriah.Waterland@Sun.COM 			    ERR_CASFAIL);
13259781SMoriah.Waterland@Sun.COM 		else
13269781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER,
13279781SMoriah.Waterland@Sun.COM 			    CAS_GRP, SHELL, script, NULL),
13289781SMoriah.Waterland@Sun.COM 			    ERR_CASFAIL);
13299781SMoriah.Waterland@Sun.COM 		clr_ulimit();
13309781SMoriah.Waterland@Sun.COM 		if (isfile(NULL, tmpfile) == 0) {
13319781SMoriah.Waterland@Sun.COM 			if (unlink(tmpfile) == -1)
13329781SMoriah.Waterland@Sun.COM 				progerr(ERR_RMPATH, tmpfile);
13339781SMoriah.Waterland@Sun.COM 		}
13349781SMoriah.Waterland@Sun.COM 	}
13359781SMoriah.Waterland@Sun.COM }
13369781SMoriah.Waterland@Sun.COM 
13379781SMoriah.Waterland@Sun.COM static void
ckreturn(int retcode,char * msg)13389781SMoriah.Waterland@Sun.COM ckreturn(int retcode, char *msg)
13399781SMoriah.Waterland@Sun.COM {
13409781SMoriah.Waterland@Sun.COM 	switch (retcode) {
13419781SMoriah.Waterland@Sun.COM 	    case 2:
13429781SMoriah.Waterland@Sun.COM 	    case 12:
13439781SMoriah.Waterland@Sun.COM 	    case 22:
13449781SMoriah.Waterland@Sun.COM 		warnflag++;
13459781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
13469781SMoriah.Waterland@Sun.COM 		if (msg)
13479781SMoriah.Waterland@Sun.COM 			progerr(msg);
13489781SMoriah.Waterland@Sun.COM 	    case 10:
13499781SMoriah.Waterland@Sun.COM 	    case 20:
13509781SMoriah.Waterland@Sun.COM 		if (retcode >= 10)
13519781SMoriah.Waterland@Sun.COM 			dreboot++;
13529781SMoriah.Waterland@Sun.COM 		if (retcode >= 20)
13539781SMoriah.Waterland@Sun.COM 			ireboot++;
13549781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
13559781SMoriah.Waterland@Sun.COM 	    case 0:
13569781SMoriah.Waterland@Sun.COM 		break; /* okay */
13579781SMoriah.Waterland@Sun.COM 
13589781SMoriah.Waterland@Sun.COM 	    case -1:
13599781SMoriah.Waterland@Sun.COM 		retcode = 99;
13609781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
13619781SMoriah.Waterland@Sun.COM 	    case 99:
13629781SMoriah.Waterland@Sun.COM 	    case 1:
13639781SMoriah.Waterland@Sun.COM 	    case 11:
13649781SMoriah.Waterland@Sun.COM 	    case 21:
13659781SMoriah.Waterland@Sun.COM 	    case 4:
13669781SMoriah.Waterland@Sun.COM 	    case 14:
13679781SMoriah.Waterland@Sun.COM 	    case 24:
13689781SMoriah.Waterland@Sun.COM 	    case 5:
13699781SMoriah.Waterland@Sun.COM 	    case 15:
13709781SMoriah.Waterland@Sun.COM 	    case 25:
13719781SMoriah.Waterland@Sun.COM 		if (msg)
13729781SMoriah.Waterland@Sun.COM 			progerr(msg);
13739781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
13749781SMoriah.Waterland@Sun.COM 	    case 3:
13759781SMoriah.Waterland@Sun.COM 	    case 13:
13769781SMoriah.Waterland@Sun.COM 	    case 23:
13779781SMoriah.Waterland@Sun.COM 		quit(retcode);
13789781SMoriah.Waterland@Sun.COM 		/* NOT REACHED */
13799781SMoriah.Waterland@Sun.COM 	    default:
13809781SMoriah.Waterland@Sun.COM 		if (msg)
13819781SMoriah.Waterland@Sun.COM 			progerr(msg);
13829781SMoriah.Waterland@Sun.COM 		quit(1);
13839781SMoriah.Waterland@Sun.COM 	}
13849781SMoriah.Waterland@Sun.COM }
13859781SMoriah.Waterland@Sun.COM 
13869781SMoriah.Waterland@Sun.COM static void
usage(void)13879781SMoriah.Waterland@Sun.COM usage(void)
13889781SMoriah.Waterland@Sun.COM {
13899781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, ERR_USAGE_PKGREMOVE);
13909781SMoriah.Waterland@Sun.COM 
13919781SMoriah.Waterland@Sun.COM 	exit(1);
13929781SMoriah.Waterland@Sun.COM }
13939781SMoriah.Waterland@Sun.COM 
13949781SMoriah.Waterland@Sun.COM /*
13959781SMoriah.Waterland@Sun.COM  * Name:		path_valid
13969781SMoriah.Waterland@Sun.COM  * Description:	Checks a string for being a valid path
13979781SMoriah.Waterland@Sun.COM  *
13989781SMoriah.Waterland@Sun.COM  * Arguments:	path - path to validate
13999781SMoriah.Waterland@Sun.COM  *
14009781SMoriah.Waterland@Sun.COM  * Returns :	B_TRUE - success, B_FALSE otherwise.
14019781SMoriah.Waterland@Sun.COM  *		B_FALSE means path was null, too long (>PATH_MAX),
14029781SMoriah.Waterland@Sun.COM  *		or too short (<1)
14039781SMoriah.Waterland@Sun.COM  */
14049781SMoriah.Waterland@Sun.COM static boolean_t
path_valid(char * path)14059781SMoriah.Waterland@Sun.COM path_valid(char *path)
14069781SMoriah.Waterland@Sun.COM {
14079781SMoriah.Waterland@Sun.COM 	if (path == NULL) {
14089781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
14099781SMoriah.Waterland@Sun.COM 	} else if (strlen(path) > PATH_MAX) {
14109781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
14119781SMoriah.Waterland@Sun.COM 	} else if (strlen(path) >= 1) {
14129781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
14139781SMoriah.Waterland@Sun.COM 	} else {
14149781SMoriah.Waterland@Sun.COM 		/* path < 1 */
14159781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
14169781SMoriah.Waterland@Sun.COM 	}
14179781SMoriah.Waterland@Sun.COM }
1418