xref: /onnv-gate/usr/src/cmd/svr4pkg/installf/main.c (revision 10032:087ec449fca8)
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 /*
239781SMoriah.Waterland@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
249781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
259781SMoriah.Waterland@Sun.COM  */
269781SMoriah.Waterland@Sun.COM 
279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM 
319781SMoriah.Waterland@Sun.COM #include <stdio.h>
329781SMoriah.Waterland@Sun.COM #include <fcntl.h>
339781SMoriah.Waterland@Sun.COM #include <ctype.h>
349781SMoriah.Waterland@Sun.COM #include <errno.h>
359781SMoriah.Waterland@Sun.COM #include <string.h>
369781SMoriah.Waterland@Sun.COM #include <signal.h>
379781SMoriah.Waterland@Sun.COM #include <stdlib.h>
389781SMoriah.Waterland@Sun.COM #include <unistd.h>
399781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
409781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
419781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
429781SMoriah.Waterland@Sun.COM #include <locale.h>
439781SMoriah.Waterland@Sun.COM #include <libintl.h>
449781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
459781SMoriah.Waterland@Sun.COM #include <pkglib.h>
469781SMoriah.Waterland@Sun.COM #include <install.h>
479781SMoriah.Waterland@Sun.COM #include <libadm.h>
489781SMoriah.Waterland@Sun.COM #include <libinst.h>
499781SMoriah.Waterland@Sun.COM #include "installf.h"
509781SMoriah.Waterland@Sun.COM 
519781SMoriah.Waterland@Sun.COM #define	BASEDIR	"/BASEDIR/"
529781SMoriah.Waterland@Sun.COM 
539781SMoriah.Waterland@Sun.COM #define	INSTALF	(*prog == 'i')
549781SMoriah.Waterland@Sun.COM #define	REMOVEF	(*prog == 'r')
559781SMoriah.Waterland@Sun.COM 
569781SMoriah.Waterland@Sun.COM #define	MSG_MANMOUNT	"Assuming mounts were provided."
579781SMoriah.Waterland@Sun.COM 
589781SMoriah.Waterland@Sun.COM #define	ERR_PKGNAME_TOO_LONG	\
599781SMoriah.Waterland@Sun.COM "The package name specified on the command line\n" \
609781SMoriah.Waterland@Sun.COM "exceeds the maximum package name length: a package name may contain a\n" \
619781SMoriah.Waterland@Sun.COM "maximum of <%d> characters; however, the package name specified on\n" \
629781SMoriah.Waterland@Sun.COM "the command line contains <%d> characters, which exceeds the maximum\n" \
639781SMoriah.Waterland@Sun.COM "package name length by <%d> characters. Please specify a package name\n" \
649781SMoriah.Waterland@Sun.COM "that contains no more than <%d> characters."
659781SMoriah.Waterland@Sun.COM 
669781SMoriah.Waterland@Sun.COM #define	ERR_DB_GET "unable to retrieve entries from the database."
679781SMoriah.Waterland@Sun.COM #define	ERR_DB_PUT "unable to update the package database."
689781SMoriah.Waterland@Sun.COM #define	ERR_ROOT_SET	"Could not set install root from the environment."
699781SMoriah.Waterland@Sun.COM #define	ERR_ROOT_CMD	"Command line install root contends with environment."
709781SMoriah.Waterland@Sun.COM #define	ERR_CLASSLONG	"classname argument too long"
719781SMoriah.Waterland@Sun.COM #define	ERR_CLASSCHAR	"bad character in classname"
729781SMoriah.Waterland@Sun.COM #define	ERR_INVAL	"package instance <%s> is invalid"
739781SMoriah.Waterland@Sun.COM #define	ERR_NOTINST	"package instance <%s> is not installed"
749781SMoriah.Waterland@Sun.COM #define	ERR_MERG	"unable to merge contents file"
759781SMoriah.Waterland@Sun.COM #define	ERR_SORT	"unable to sort contents file"
769781SMoriah.Waterland@Sun.COM #define	ERR_I_FAIL	"installf did not complete successfully"
779781SMoriah.Waterland@Sun.COM #define	ERR_R_FAIL	"removef did not complete successfully"
789781SMoriah.Waterland@Sun.COM #define	ERR_NOTROOT	"You must be \"root\" for %s to execute properly."
799781SMoriah.Waterland@Sun.COM #define	ERR_USAGE0	"usage:\n" \
809781SMoriah.Waterland@Sun.COM 	"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path " \
819781SMoriah.Waterland@Sun.COM 	"[path ...]\n" \
829781SMoriah.Waterland@Sun.COM 	"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path\n"
839781SMoriah.Waterland@Sun.COM 
849781SMoriah.Waterland@Sun.COM #define	ERR_USAGE1	"usage:\n" \
859781SMoriah.Waterland@Sun.COM 	"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
869781SMoriah.Waterland@Sun.COM 	"<path>\n" \
879781SMoriah.Waterland@Sun.COM 	"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
889781SMoriah.Waterland@Sun.COM 	"<path> <specs>\n" \
899781SMoriah.Waterland@Sun.COM 	"\t   where <specs> may be defined as:\n" \
909781SMoriah.Waterland@Sun.COM 	"\t\tf <mode> <owner> <group>\n" \
919781SMoriah.Waterland@Sun.COM 	"\t\tv <mode> <owner> <group>\n" \
929781SMoriah.Waterland@Sun.COM 	"\t\te <mode> <owner> <group>\n" \
939781SMoriah.Waterland@Sun.COM 	"\t\td <mode> <owner> <group>\n" \
949781SMoriah.Waterland@Sun.COM 	"\t\tx <mode> <owner> <group>\n" \
959781SMoriah.Waterland@Sun.COM 	"\t\tp <mode> <owner> <group>\n" \
969781SMoriah.Waterland@Sun.COM 	"\t\tc <major> <minor> <mode> <owner> <group>\n" \
979781SMoriah.Waterland@Sun.COM 	"\t\tb <major> <minor> <mode> <owner> <group>\n" \
989781SMoriah.Waterland@Sun.COM 	"\t\ts <path>=<srcpath>\n" \
999781SMoriah.Waterland@Sun.COM 	"\t\tl <path>=<srcpath>\n" \
1009781SMoriah.Waterland@Sun.COM 	"\t%s [[-M] -R host_path] [-V ...] [-c class] -f pkginst\n"
1019781SMoriah.Waterland@Sun.COM 
1029781SMoriah.Waterland@Sun.COM #define	CMD_SORT	"sort +0 -1"
1039781SMoriah.Waterland@Sun.COM 
1049781SMoriah.Waterland@Sun.COM #define	LINK	1
1059781SMoriah.Waterland@Sun.COM 
1069781SMoriah.Waterland@Sun.COM extern char	dbst; 			/* libinst/pkgdbmerg.c */
1079781SMoriah.Waterland@Sun.COM 
1089781SMoriah.Waterland@Sun.COM struct cfextra **extlist;
1099781SMoriah.Waterland@Sun.COM struct pinfo **eptlist;
1109781SMoriah.Waterland@Sun.COM 
1119781SMoriah.Waterland@Sun.COM char	*classname = NULL;
1129781SMoriah.Waterland@Sun.COM char	*pkginst;
1139781SMoriah.Waterland@Sun.COM char	*uniTmp;
1149781SMoriah.Waterland@Sun.COM char 	*abi_sym_ptr;
1159781SMoriah.Waterland@Sun.COM char 	*ulim;
1169781SMoriah.Waterland@Sun.COM char 	*script;
1179781SMoriah.Waterland@Sun.COM 
1189781SMoriah.Waterland@Sun.COM int	eptnum;
1199781SMoriah.Waterland@Sun.COM int	nosetuid;
1209781SMoriah.Waterland@Sun.COM int	nocnflct;
1219781SMoriah.Waterland@Sun.COM int	warnflag = 0;
1229781SMoriah.Waterland@Sun.COM 
1239781SMoriah.Waterland@Sun.COM /* libadm/pkgparam.c */
1249781SMoriah.Waterland@Sun.COM extern void	set_PKGADM(char *newpath);
1259781SMoriah.Waterland@Sun.COM extern void	set_PKGLOC(char *newpath);
1269781SMoriah.Waterland@Sun.COM 
1279781SMoriah.Waterland@Sun.COM extern void set_limit(void);
1289781SMoriah.Waterland@Sun.COM 
1299781SMoriah.Waterland@Sun.COM int
main(int argc,char ** argv)1309781SMoriah.Waterland@Sun.COM main(int argc, char **argv)
1319781SMoriah.Waterland@Sun.COM {
1329781SMoriah.Waterland@Sun.COM 	VFP_T		*cfTmpVfp;
1339869SCasper.Dik@Sun.COM 	PKGserver	pkgserver = NULL;
1349781SMoriah.Waterland@Sun.COM 	char		*tp;
1359781SMoriah.Waterland@Sun.COM 	char		*prog;
1369781SMoriah.Waterland@Sun.COM 	char		*pt;
1379781SMoriah.Waterland@Sun.COM 	char		*vfstab_file = NULL;
138*10032SPhaniram.Krishnamurthy@Sun.COM 	char		*temp_cl_basedir;
1399781SMoriah.Waterland@Sun.COM 	char		outbuf[PATH_MAX];
1409781SMoriah.Waterland@Sun.COM 	int		c;
1419781SMoriah.Waterland@Sun.COM 	int		dbchg;
1429781SMoriah.Waterland@Sun.COM 	int		err;
1439781SMoriah.Waterland@Sun.COM 	int		fflag = 0;
1449781SMoriah.Waterland@Sun.COM 	int		map_client = 1;
1459781SMoriah.Waterland@Sun.COM 	int		n;
1469781SMoriah.Waterland@Sun.COM 	int		pkgrmremote = 0;	/* don't remove remote files */
1479781SMoriah.Waterland@Sun.COM 	struct cfent	*ept;
1489781SMoriah.Waterland@Sun.COM 
1499781SMoriah.Waterland@Sun.COM 	/* hookup signals */
1509781SMoriah.Waterland@Sun.COM 
1519781SMoriah.Waterland@Sun.COM 	(void) signal(SIGHUP, exit);
1529781SMoriah.Waterland@Sun.COM 	(void) signal(SIGINT, exit);
1539781SMoriah.Waterland@Sun.COM 	(void) signal(SIGQUIT, exit);
1549781SMoriah.Waterland@Sun.COM 
1559781SMoriah.Waterland@Sun.COM 	/* initialize locale mechanism */
1569781SMoriah.Waterland@Sun.COM 
1579781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
1589781SMoriah.Waterland@Sun.COM 
1599781SMoriah.Waterland@Sun.COM #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1609781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
1619781SMoriah.Waterland@Sun.COM #endif	/* !defined(TEXT_DOMAIN) */
1629781SMoriah.Waterland@Sun.COM 
1639781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
1649781SMoriah.Waterland@Sun.COM 
1659781SMoriah.Waterland@Sun.COM 	/* determine program name */
1669781SMoriah.Waterland@Sun.COM 
1679781SMoriah.Waterland@Sun.COM 	prog = set_prog_name(argv[0]);
1689781SMoriah.Waterland@Sun.COM 
1699781SMoriah.Waterland@Sun.COM 	/* tell instzones interface how to access package output functions */
1709781SMoriah.Waterland@Sun.COM 
1719781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
1729781SMoriah.Waterland@Sun.COM 
1739781SMoriah.Waterland@Sun.COM 	/* only allow root to run this program */
1749781SMoriah.Waterland@Sun.COM 
1759781SMoriah.Waterland@Sun.COM 	if (getuid() != 0) {
1769781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOTROOT), prog);
1779781SMoriah.Waterland@Sun.COM 		exit(1);
1789781SMoriah.Waterland@Sun.COM 	}
1799781SMoriah.Waterland@Sun.COM 
1809781SMoriah.Waterland@Sun.COM 	ulim = getenv("PKG_ULIMIT");
1819781SMoriah.Waterland@Sun.COM 	script = getenv("PKG_PROC_SCRIPT");
1829781SMoriah.Waterland@Sun.COM 
1839781SMoriah.Waterland@Sun.COM 	if (ulim && script) {
1849781SMoriah.Waterland@Sun.COM 		set_limit();
1859781SMoriah.Waterland@Sun.COM 		clr_ulimit();
1869781SMoriah.Waterland@Sun.COM 	}
1879781SMoriah.Waterland@Sun.COM 
1889781SMoriah.Waterland@Sun.COM 	/* bug id 4244631, not ABI compliant */
1899781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
1909781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)
1919781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
1929781SMoriah.Waterland@Sun.COM 
1939781SMoriah.Waterland@Sun.COM 	/* bugId 4012147 */
1949781SMoriah.Waterland@Sun.COM 	if ((uniTmp = getenv("PKG_NO_UNIFIED")) != NULL)
1959781SMoriah.Waterland@Sun.COM 		map_client = 0;
1969781SMoriah.Waterland@Sun.COM 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
1979781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_ROOT_SET));
1989781SMoriah.Waterland@Sun.COM 		exit(1);
1999781SMoriah.Waterland@Sun.COM 	}
2009781SMoriah.Waterland@Sun.COM 
2019781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, "c:V:fAMR:?")) != EOF) {
2029781SMoriah.Waterland@Sun.COM 		switch (c) {
2039781SMoriah.Waterland@Sun.COM 			case 'f':
2049781SMoriah.Waterland@Sun.COM 			fflag++;
2059781SMoriah.Waterland@Sun.COM 			break;
2069781SMoriah.Waterland@Sun.COM 
2079781SMoriah.Waterland@Sun.COM 			case 'c':
2089781SMoriah.Waterland@Sun.COM 			classname = optarg;
2099781SMoriah.Waterland@Sun.COM 			/* validate that classname is acceptable */
2109781SMoriah.Waterland@Sun.COM 			if (strlen(classname) > (size_t)CLSSIZ) {
2119781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_CLASSLONG));
2129781SMoriah.Waterland@Sun.COM 				exit(1);
2139781SMoriah.Waterland@Sun.COM 			}
2149781SMoriah.Waterland@Sun.COM 			for (pt = classname; *pt; pt++) {
2159781SMoriah.Waterland@Sun.COM 				if (!isalpha(*pt) && !isdigit(*pt)) {
2169781SMoriah.Waterland@Sun.COM 					progerr(gettext(ERR_CLASSCHAR));
2179781SMoriah.Waterland@Sun.COM 					exit(1);
2189781SMoriah.Waterland@Sun.COM 				}
2199781SMoriah.Waterland@Sun.COM 			}
2209781SMoriah.Waterland@Sun.COM 			break;
2219781SMoriah.Waterland@Sun.COM 
2229781SMoriah.Waterland@Sun.COM 		/*
2239781SMoriah.Waterland@Sun.COM 		 * Don't map the client filesystem onto the server's. Assume
2249781SMoriah.Waterland@Sun.COM 		 * the mounts have been made for us.
2259781SMoriah.Waterland@Sun.COM 		 */
2269781SMoriah.Waterland@Sun.COM 			case 'M':
2279781SMoriah.Waterland@Sun.COM 			map_client = 0;
2289781SMoriah.Waterland@Sun.COM 			break;
2299781SMoriah.Waterland@Sun.COM 
2309781SMoriah.Waterland@Sun.COM 		/*
2319781SMoriah.Waterland@Sun.COM 		 * Allow admin to establish the client filesystem using a
2329781SMoriah.Waterland@Sun.COM 		 * vfstab-like file of stable format.
2339781SMoriah.Waterland@Sun.COM 		 */
2349781SMoriah.Waterland@Sun.COM 			case 'V':
2359781SMoriah.Waterland@Sun.COM 			vfstab_file = flex_device(optarg, 2);
2369781SMoriah.Waterland@Sun.COM 			map_client = 1;
2379781SMoriah.Waterland@Sun.COM 			break;
2389781SMoriah.Waterland@Sun.COM 
2399781SMoriah.Waterland@Sun.COM 			case 'A':
2409781SMoriah.Waterland@Sun.COM 			pkgrmremote++;
2419781SMoriah.Waterland@Sun.COM 			break;
2429781SMoriah.Waterland@Sun.COM 
2439781SMoriah.Waterland@Sun.COM 			case 'R':	/* added for newroot option */
2449781SMoriah.Waterland@Sun.COM 			if (!set_inst_root(optarg)) {
2459781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_ROOT_CMD));
2469781SMoriah.Waterland@Sun.COM 				exit(1);
2479781SMoriah.Waterland@Sun.COM 			}
2489781SMoriah.Waterland@Sun.COM 			break;
2499781SMoriah.Waterland@Sun.COM 
2509781SMoriah.Waterland@Sun.COM 			default:
2519781SMoriah.Waterland@Sun.COM 			usage();
2529781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
2539781SMoriah.Waterland@Sun.COM 			/*
2549781SMoriah.Waterland@Sun.COM 			 * Although usage() calls a noreturn function,
2559781SMoriah.Waterland@Sun.COM 			 * needed to add return (1);  so that main() would
2569781SMoriah.Waterland@Sun.COM 			 * pass compilation checks. The statement below
2579781SMoriah.Waterland@Sun.COM 			 * should never be executed.
2589781SMoriah.Waterland@Sun.COM 			 */
2599781SMoriah.Waterland@Sun.COM 			return (1);
2609781SMoriah.Waterland@Sun.COM 		}
2619781SMoriah.Waterland@Sun.COM 	}
2629781SMoriah.Waterland@Sun.COM 
2639781SMoriah.Waterland@Sun.COM 	if (pkgrmremote && (!is_an_inst_root() || fflag || INSTALF)) {
2649781SMoriah.Waterland@Sun.COM 		usage();
2659781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2669781SMoriah.Waterland@Sun.COM 	}
2679781SMoriah.Waterland@Sun.COM 
2689781SMoriah.Waterland@Sun.COM 	/*
2699781SMoriah.Waterland@Sun.COM 	 * Get the mount table info and store internally.
2709781SMoriah.Waterland@Sun.COM 	 */
2719781SMoriah.Waterland@Sun.COM 	if (get_mntinfo(map_client, vfstab_file))
2729781SMoriah.Waterland@Sun.COM 		exit(1);
2739781SMoriah.Waterland@Sun.COM 
2749781SMoriah.Waterland@Sun.COM 	/*
2759781SMoriah.Waterland@Sun.COM 	 * This function defines the standard /var/... directories used later
2769781SMoriah.Waterland@Sun.COM 	 * to construct the paths to the various databases.
2779781SMoriah.Waterland@Sun.COM 	 */
2789781SMoriah.Waterland@Sun.COM 	(void) set_PKGpaths(get_inst_root());
2799781SMoriah.Waterland@Sun.COM 
2809781SMoriah.Waterland@Sun.COM 	/*
2819781SMoriah.Waterland@Sun.COM 	 * If this is being installed on a client whose /var filesystem is
2829781SMoriah.Waterland@Sun.COM 	 * mounted in some odd way, remap the administrative paths to the
2839781SMoriah.Waterland@Sun.COM 	 * real filesystem. This could be avoided by simply mounting up the
2849781SMoriah.Waterland@Sun.COM 	 * client now; but we aren't yet to the point in the process where
2859781SMoriah.Waterland@Sun.COM 	 * modification of the filesystem is permitted.
2869781SMoriah.Waterland@Sun.COM 	 */
2879781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
2889781SMoriah.Waterland@Sun.COM 		int fsys_value;
2899781SMoriah.Waterland@Sun.COM 
2909781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGLOC());
2919781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
2929781SMoriah.Waterland@Sun.COM 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
2939781SMoriah.Waterland@Sun.COM 
2949781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGADM());
2959781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
2969781SMoriah.Waterland@Sun.COM 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
2979781SMoriah.Waterland@Sun.COM 	}
2989781SMoriah.Waterland@Sun.COM 
2999781SMoriah.Waterland@Sun.COM 	/*
3009781SMoriah.Waterland@Sun.COM 	 * get the package name and verify length is not too long
3019781SMoriah.Waterland@Sun.COM 	 */
3029781SMoriah.Waterland@Sun.COM 
3039781SMoriah.Waterland@Sun.COM 	pkginst = argv[optind++];
3049781SMoriah.Waterland@Sun.COM 	if (pkginst == NULL) {
3059781SMoriah.Waterland@Sun.COM 		usage();
3069781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
3079781SMoriah.Waterland@Sun.COM 
3089781SMoriah.Waterland@Sun.COM 	}
3099781SMoriah.Waterland@Sun.COM 
3109781SMoriah.Waterland@Sun.COM 	n = strlen(pkginst);
3119781SMoriah.Waterland@Sun.COM 	if (n > PKGSIZ) {
3129781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_PKGNAME_TOO_LONG), PKGSIZ, n, n-PKGSIZ,
3139781SMoriah.Waterland@Sun.COM 		    PKGSIZ);
3149781SMoriah.Waterland@Sun.COM 		usage();
3159781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
3169781SMoriah.Waterland@Sun.COM 	}
3179781SMoriah.Waterland@Sun.COM 
3189781SMoriah.Waterland@Sun.COM 	/*
3199781SMoriah.Waterland@Sun.COM 	 * The following is used to setup the environment. Note that the
3209781SMoriah.Waterland@Sun.COM 	 * variable 'BASEDIR' is only meaningful for this utility if there
3219781SMoriah.Waterland@Sun.COM 	 * is an install root, recorded in PKG_INSTALL_ROOT. Otherwise, this
3229781SMoriah.Waterland@Sun.COM 	 * utility can create a file or directory anywhere unfettered by
3239781SMoriah.Waterland@Sun.COM 	 * the basedir associated with the package instance.
3249781SMoriah.Waterland@Sun.COM 	 */
3259781SMoriah.Waterland@Sun.COM 	if ((err = set_basedirs(0, NULL, pkginst, 1)) != 0)
3269781SMoriah.Waterland@Sun.COM 		exit(err);
3279781SMoriah.Waterland@Sun.COM 
3289781SMoriah.Waterland@Sun.COM 	if (INSTALF)
3299781SMoriah.Waterland@Sun.COM 		mkbasedir(0, get_basedir());
3309781SMoriah.Waterland@Sun.COM 
3319781SMoriah.Waterland@Sun.COM 	if (fflag) {
3329781SMoriah.Waterland@Sun.COM 		/* installf and removef must only have pkginst */
3339781SMoriah.Waterland@Sun.COM 		if (optind != argc) {
3349781SMoriah.Waterland@Sun.COM 			usage();
3359781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
3369781SMoriah.Waterland@Sun.COM 		}
3379781SMoriah.Waterland@Sun.COM 	} else {
3389781SMoriah.Waterland@Sun.COM 		/*
3399781SMoriah.Waterland@Sun.COM 		 * installf and removef must have at minimum
3409781SMoriah.Waterland@Sun.COM 		 * pkginst & pathname specified on command line
3419781SMoriah.Waterland@Sun.COM 		 */
3429781SMoriah.Waterland@Sun.COM 		if (optind >= argc) {
3439781SMoriah.Waterland@Sun.COM 			usage();
3449781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
3459781SMoriah.Waterland@Sun.COM 		}
3469781SMoriah.Waterland@Sun.COM 	}
3479781SMoriah.Waterland@Sun.COM 	if (REMOVEF) {
3489781SMoriah.Waterland@Sun.COM 		if (classname) {
3499781SMoriah.Waterland@Sun.COM 			usage();
3509781SMoriah.Waterland@Sun.COM 		}
3519781SMoriah.Waterland@Sun.COM 	}
3529781SMoriah.Waterland@Sun.COM 	if (pkgnmchk(pkginst, "all", 0)) {
3539781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_INVAL), pkginst);
3549781SMoriah.Waterland@Sun.COM 		exit(1);
3559781SMoriah.Waterland@Sun.COM 	}
3569781SMoriah.Waterland@Sun.COM 	if (fpkginst(pkginst, NULL, NULL) == NULL) {
3579781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOTINST), pkginst);
3589781SMoriah.Waterland@Sun.COM 		exit(1);
3599781SMoriah.Waterland@Sun.COM 	}
3609781SMoriah.Waterland@Sun.COM 
3619781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
3629781SMoriah.Waterland@Sun.COM 	/*
3639781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
3649781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
3659781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
3669781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
3679781SMoriah.Waterland@Sun.COM 	 */
3689781SMoriah.Waterland@Sun.COM 	/* Until 2.9, set it from the execption list */
3699781SMoriah.Waterland@Sun.COM 	if (pkginst && exception_pkg(pkginst, LINK))
3709781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
3719781SMoriah.Waterland@Sun.COM #endif
3729781SMoriah.Waterland@Sun.COM 	/*
3739781SMoriah.Waterland@Sun.COM 	 * This maps the client filesystems into the server's space.
3749781SMoriah.Waterland@Sun.COM 	 */
3759781SMoriah.Waterland@Sun.COM 	if (map_client && !mount_client())
3769781SMoriah.Waterland@Sun.COM 		logerr(gettext(MSG_MANMOUNT));
3779781SMoriah.Waterland@Sun.COM 
3789781SMoriah.Waterland@Sun.COM 	/* open the package database (contents) file */
3799781SMoriah.Waterland@Sun.COM 
3809869SCasper.Dik@Sun.COM 	if (!ocfile(&pkgserver, &cfTmpVfp, 0L)) {
3819781SMoriah.Waterland@Sun.COM 		quit(1);
3829781SMoriah.Waterland@Sun.COM 	}
3839781SMoriah.Waterland@Sun.COM 
3849781SMoriah.Waterland@Sun.COM 	if (fflag) {
3859869SCasper.Dik@Sun.COM 		dbchg = dofinal(pkgserver, cfTmpVfp, REMOVEF, classname, prog);
3869781SMoriah.Waterland@Sun.COM 	} else {
3879781SMoriah.Waterland@Sun.COM 		if (INSTALF) {
3889781SMoriah.Waterland@Sun.COM 			dbst = INST_RDY;
3899781SMoriah.Waterland@Sun.COM 			if (installf(argc-optind, &argv[optind]))
3909781SMoriah.Waterland@Sun.COM 				quit(1);
3919781SMoriah.Waterland@Sun.COM 		} else {
3929781SMoriah.Waterland@Sun.COM 			dbst = RM_RDY;
3939781SMoriah.Waterland@Sun.COM 			removef(argc-optind, &argv[optind]);
3949781SMoriah.Waterland@Sun.COM 		}
3959781SMoriah.Waterland@Sun.COM 
3969869SCasper.Dik@Sun.COM 		dbchg = pkgdbmerg(pkgserver, cfTmpVfp, extlist);
3979781SMoriah.Waterland@Sun.COM 		if (dbchg < 0) {
3989781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MERG));
3999781SMoriah.Waterland@Sun.COM 			quit(99);
4009781SMoriah.Waterland@Sun.COM 		}
4019781SMoriah.Waterland@Sun.COM 	}
4029781SMoriah.Waterland@Sun.COM 
4039781SMoriah.Waterland@Sun.COM 	if (dbchg) {
4049869SCasper.Dik@Sun.COM 		if ((n = swapcfile(pkgserver, &cfTmpVfp, pkginst, 1))
4059869SCasper.Dik@Sun.COM 		    == RESULT_WRN) {
4069869SCasper.Dik@Sun.COM 			warnflag++;
4079781SMoriah.Waterland@Sun.COM 		} else if (n == RESULT_ERR) {
4089869SCasper.Dik@Sun.COM 			quit(99);
4099781SMoriah.Waterland@Sun.COM 		}
4109781SMoriah.Waterland@Sun.COM 	}
4119781SMoriah.Waterland@Sun.COM 
4129781SMoriah.Waterland@Sun.COM 	relslock();
4139781SMoriah.Waterland@Sun.COM 
4149781SMoriah.Waterland@Sun.COM 	if (REMOVEF && !fflag) {
4159781SMoriah.Waterland@Sun.COM 		for (n = 0; extlist[n]; n++) {
4169781SMoriah.Waterland@Sun.COM 			ept = &(extlist[n]->cf_ent);
4179781SMoriah.Waterland@Sun.COM 
4189781SMoriah.Waterland@Sun.COM 			/* Skip duplicated paths */
4199781SMoriah.Waterland@Sun.COM 			if ((n > 0) && (strncmp(ept->path,
4209781SMoriah.Waterland@Sun.COM 			    extlist[n-1]->cf_ent.path, PATH_MAX) == 0)) {
4219781SMoriah.Waterland@Sun.COM 				continue;
4229781SMoriah.Waterland@Sun.COM 			}
4239781SMoriah.Waterland@Sun.COM 
4249781SMoriah.Waterland@Sun.COM 			if (!extlist[n]->mstat.shared) {
4259781SMoriah.Waterland@Sun.COM 				/*
4269781SMoriah.Waterland@Sun.COM 				 * Only output paths that can be deleted.
4279781SMoriah.Waterland@Sun.COM 				 * so need to skip if the object is owned
4289781SMoriah.Waterland@Sun.COM 				 * by a remote server and removal is not
4299781SMoriah.Waterland@Sun.COM 				 * being forced.
4309781SMoriah.Waterland@Sun.COM 				 */
4319781SMoriah.Waterland@Sun.COM 				if (ept->pinfo &&
4329781SMoriah.Waterland@Sun.COM 				    (ept->pinfo->status == SERVED_FILE) &&
4339781SMoriah.Waterland@Sun.COM 				    !pkgrmremote)
4349781SMoriah.Waterland@Sun.COM 					continue;
4359781SMoriah.Waterland@Sun.COM 
4369781SMoriah.Waterland@Sun.COM 				c = 0;
4379781SMoriah.Waterland@Sun.COM 				if (is_a_cl_basedir() && !is_an_inst_root()) {
438*10032SPhaniram.Krishnamurthy@Sun.COM 					/*
439*10032SPhaniram.Krishnamurthy@Sun.COM 					 * A path in contents db might have
440*10032SPhaniram.Krishnamurthy@Sun.COM 					 * other prefix than BASEDIR of the
441*10032SPhaniram.Krishnamurthy@Sun.COM 					 * package
442*10032SPhaniram.Krishnamurthy@Sun.COM 					 */
443*10032SPhaniram.Krishnamurthy@Sun.COM 					temp_cl_basedir = get_client_basedir();
444*10032SPhaniram.Krishnamurthy@Sun.COM 					if (strncmp(ept->path, temp_cl_basedir,
445*10032SPhaniram.Krishnamurthy@Sun.COM 					    strlen(temp_cl_basedir)) == 0) {
446*10032SPhaniram.Krishnamurthy@Sun.COM 						c = strlen(temp_cl_basedir);
447*10032SPhaniram.Krishnamurthy@Sun.COM 						(void) snprintf(outbuf,
448*10032SPhaniram.Krishnamurthy@Sun.COM 						    sizeof (outbuf), "%s/%s\n",
449*10032SPhaniram.Krishnamurthy@Sun.COM 						    get_basedir(),
450*10032SPhaniram.Krishnamurthy@Sun.COM 						    &(ept->path[c]));
451*10032SPhaniram.Krishnamurthy@Sun.COM 					} else {
452*10032SPhaniram.Krishnamurthy@Sun.COM 						(void) snprintf(outbuf,
453*10032SPhaniram.Krishnamurthy@Sun.COM 						    sizeof (outbuf),
454*10032SPhaniram.Krishnamurthy@Sun.COM 						    "%s\n", &(ept->path[c]));
455*10032SPhaniram.Krishnamurthy@Sun.COM 					}
4569781SMoriah.Waterland@Sun.COM 				} else if (is_an_inst_root()) {
4579781SMoriah.Waterland@Sun.COM 					(void) snprintf(outbuf, sizeof (outbuf),
4589869SCasper.Dik@Sun.COM 					    "%s/%s\n", get_inst_root(),
4599869SCasper.Dik@Sun.COM 					    &(ept->path[c]));
4609781SMoriah.Waterland@Sun.COM 				} else {
4619781SMoriah.Waterland@Sun.COM 					(void) snprintf(outbuf, sizeof (outbuf),
4629869SCasper.Dik@Sun.COM 					    "%s\n", &(ept->path[c]));
4639781SMoriah.Waterland@Sun.COM 				}
4649781SMoriah.Waterland@Sun.COM 				canonize(outbuf);
4659781SMoriah.Waterland@Sun.COM 				(void) printf("%s", outbuf);
4669781SMoriah.Waterland@Sun.COM 			}
4679781SMoriah.Waterland@Sun.COM 		}
4689781SMoriah.Waterland@Sun.COM 	} else if (INSTALF && !fflag) {
4699781SMoriah.Waterland@Sun.COM 		for (n = 0; extlist[n]; n++) {
4709781SMoriah.Waterland@Sun.COM 			ept = &(extlist[n]->cf_ent);
4719781SMoriah.Waterland@Sun.COM 
4729781SMoriah.Waterland@Sun.COM 			if (strchr("dxcbp", ept->ftype)) {
4739781SMoriah.Waterland@Sun.COM 				tp = fixpath(ept->path);
4749869SCasper.Dik@Sun.COM 				(void) averify(1, &ept->ftype, tp, &ept->ainfo);
4759781SMoriah.Waterland@Sun.COM 			}
4769781SMoriah.Waterland@Sun.COM 		}
4779781SMoriah.Waterland@Sun.COM 	}
4789781SMoriah.Waterland@Sun.COM 
4799869SCasper.Dik@Sun.COM 	pkgcloseserver(pkgserver);
4809781SMoriah.Waterland@Sun.COM 
4819781SMoriah.Waterland@Sun.COM 	z_destroyMountTable();
4829781SMoriah.Waterland@Sun.COM 
4839781SMoriah.Waterland@Sun.COM 	quit(warnflag ? 1 : 0);
4849781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
4859781SMoriah.Waterland@Sun.COM }
4869781SMoriah.Waterland@Sun.COM 
4879781SMoriah.Waterland@Sun.COM void
quit(int n)4889781SMoriah.Waterland@Sun.COM quit(int n)
4899781SMoriah.Waterland@Sun.COM {
4909781SMoriah.Waterland@Sun.COM 	char *prog = get_prog_name();
4919781SMoriah.Waterland@Sun.COM 
4929781SMoriah.Waterland@Sun.COM 	unmount_client();
4939781SMoriah.Waterland@Sun.COM 
4949781SMoriah.Waterland@Sun.COM 	if (ulim && script) {
4959781SMoriah.Waterland@Sun.COM 		if (REMOVEF) {
4969781SMoriah.Waterland@Sun.COM 			set_ulimit(script, gettext(ERR_R_FAIL));
4979781SMoriah.Waterland@Sun.COM 		} else {
4989781SMoriah.Waterland@Sun.COM 			set_ulimit(script, gettext(ERR_I_FAIL));
4999781SMoriah.Waterland@Sun.COM 		}
5009781SMoriah.Waterland@Sun.COM 	}
5019781SMoriah.Waterland@Sun.COM 
5029781SMoriah.Waterland@Sun.COM 	exit(n);
5039781SMoriah.Waterland@Sun.COM }
5049781SMoriah.Waterland@Sun.COM 
5059781SMoriah.Waterland@Sun.COM void
usage(void)5069781SMoriah.Waterland@Sun.COM usage(void)
5079781SMoriah.Waterland@Sun.COM {
5089781SMoriah.Waterland@Sun.COM 	char *prog = get_prog_name();
5099781SMoriah.Waterland@Sun.COM 
5109781SMoriah.Waterland@Sun.COM 	if (REMOVEF) {
5119781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(ERR_USAGE0), prog, prog);
5129781SMoriah.Waterland@Sun.COM 	} else {
5139781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(ERR_USAGE1), prog, prog, prog);
5149781SMoriah.Waterland@Sun.COM 	}
5159781SMoriah.Waterland@Sun.COM 	exit(1);
5169781SMoriah.Waterland@Sun.COM }
517