xref: /titanic_53/usr/src/cmd/svr4pkg/installf/main.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*5c51f124SMoriah Waterland /* All Rights Reserved */
29*5c51f124SMoriah Waterland 
30*5c51f124SMoriah Waterland 
31*5c51f124SMoriah Waterland #include <stdio.h>
32*5c51f124SMoriah Waterland #include <fcntl.h>
33*5c51f124SMoriah Waterland #include <ctype.h>
34*5c51f124SMoriah Waterland #include <errno.h>
35*5c51f124SMoriah Waterland #include <string.h>
36*5c51f124SMoriah Waterland #include <signal.h>
37*5c51f124SMoriah Waterland #include <stdlib.h>
38*5c51f124SMoriah Waterland #include <unistd.h>
39*5c51f124SMoriah Waterland #include <pkginfo.h>
40*5c51f124SMoriah Waterland #include <pkgstrct.h>
41*5c51f124SMoriah Waterland #include <pkglocs.h>
42*5c51f124SMoriah Waterland #include <locale.h>
43*5c51f124SMoriah Waterland #include <libintl.h>
44*5c51f124SMoriah Waterland #include <instzones_api.h>
45*5c51f124SMoriah Waterland #include <pkglib.h>
46*5c51f124SMoriah Waterland #include <install.h>
47*5c51f124SMoriah Waterland #include <libadm.h>
48*5c51f124SMoriah Waterland #include <libinst.h>
49*5c51f124SMoriah Waterland #include "installf.h"
50*5c51f124SMoriah Waterland 
51*5c51f124SMoriah Waterland #define	BASEDIR	"/BASEDIR/"
52*5c51f124SMoriah Waterland 
53*5c51f124SMoriah Waterland #define	INSTALF	(*prog == 'i')
54*5c51f124SMoriah Waterland #define	REMOVEF	(*prog == 'r')
55*5c51f124SMoriah Waterland 
56*5c51f124SMoriah Waterland #define	MSG_MANMOUNT	"Assuming mounts were provided."
57*5c51f124SMoriah Waterland 
58*5c51f124SMoriah Waterland #define	ERR_PKGNAME_TOO_LONG	\
59*5c51f124SMoriah Waterland "The package name specified on the command line\n" \
60*5c51f124SMoriah Waterland "exceeds the maximum package name length: a package name may contain a\n" \
61*5c51f124SMoriah Waterland "maximum of <%d> characters; however, the package name specified on\n" \
62*5c51f124SMoriah Waterland "the command line contains <%d> characters, which exceeds the maximum\n" \
63*5c51f124SMoriah Waterland "package name length by <%d> characters. Please specify a package name\n" \
64*5c51f124SMoriah Waterland "that contains no more than <%d> characters."
65*5c51f124SMoriah Waterland 
66*5c51f124SMoriah Waterland #define	ERR_DB_GET "unable to retrieve entries from the database."
67*5c51f124SMoriah Waterland #define	ERR_DB_PUT "unable to update the package database."
68*5c51f124SMoriah Waterland #define	ERR_ROOT_SET	"Could not set install root from the environment."
69*5c51f124SMoriah Waterland #define	ERR_ROOT_CMD	"Command line install root contends with environment."
70*5c51f124SMoriah Waterland #define	ERR_CLASSLONG	"classname argument too long"
71*5c51f124SMoriah Waterland #define	ERR_CLASSCHAR	"bad character in classname"
72*5c51f124SMoriah Waterland #define	ERR_INVAL	"package instance <%s> is invalid"
73*5c51f124SMoriah Waterland #define	ERR_NOTINST	"package instance <%s> is not installed"
74*5c51f124SMoriah Waterland #define	ERR_MERG	"unable to merge contents file"
75*5c51f124SMoriah Waterland #define	ERR_SORT	"unable to sort contents file"
76*5c51f124SMoriah Waterland #define	ERR_I_FAIL	"installf did not complete successfully"
77*5c51f124SMoriah Waterland #define	ERR_R_FAIL	"removef did not complete successfully"
78*5c51f124SMoriah Waterland #define	ERR_NOTROOT	"You must be \"root\" for %s to execute properly."
79*5c51f124SMoriah Waterland #define	ERR_USAGE0	"usage:\n" \
80*5c51f124SMoriah Waterland 	"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path " \
81*5c51f124SMoriah Waterland 	"[path ...]\n" \
82*5c51f124SMoriah Waterland 	"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path\n"
83*5c51f124SMoriah Waterland 
84*5c51f124SMoriah Waterland #define	ERR_USAGE1	"usage:\n" \
85*5c51f124SMoriah Waterland 	"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
86*5c51f124SMoriah Waterland 	"<path>\n" \
87*5c51f124SMoriah Waterland 	"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
88*5c51f124SMoriah Waterland 	"<path> <specs>\n" \
89*5c51f124SMoriah Waterland 	"\t   where <specs> may be defined as:\n" \
90*5c51f124SMoriah Waterland 	"\t\tf <mode> <owner> <group>\n" \
91*5c51f124SMoriah Waterland 	"\t\tv <mode> <owner> <group>\n" \
92*5c51f124SMoriah Waterland 	"\t\te <mode> <owner> <group>\n" \
93*5c51f124SMoriah Waterland 	"\t\td <mode> <owner> <group>\n" \
94*5c51f124SMoriah Waterland 	"\t\tx <mode> <owner> <group>\n" \
95*5c51f124SMoriah Waterland 	"\t\tp <mode> <owner> <group>\n" \
96*5c51f124SMoriah Waterland 	"\t\tc <major> <minor> <mode> <owner> <group>\n" \
97*5c51f124SMoriah Waterland 	"\t\tb <major> <minor> <mode> <owner> <group>\n" \
98*5c51f124SMoriah Waterland 	"\t\ts <path>=<srcpath>\n" \
99*5c51f124SMoriah Waterland 	"\t\tl <path>=<srcpath>\n" \
100*5c51f124SMoriah Waterland 	"\t%s [[-M] -R host_path] [-V ...] [-c class] -f pkginst\n"
101*5c51f124SMoriah Waterland 
102*5c51f124SMoriah Waterland #define	CMD_SORT	"sort +0 -1"
103*5c51f124SMoriah Waterland 
104*5c51f124SMoriah Waterland #define	LINK	1
105*5c51f124SMoriah Waterland 
106*5c51f124SMoriah Waterland extern char	dbst; 			/* libinst/pkgdbmerg.c */
107*5c51f124SMoriah Waterland 
108*5c51f124SMoriah Waterland struct cfextra **extlist;
109*5c51f124SMoriah Waterland struct pinfo **eptlist;
110*5c51f124SMoriah Waterland 
111*5c51f124SMoriah Waterland char	*classname = NULL;
112*5c51f124SMoriah Waterland char	*pkginst;
113*5c51f124SMoriah Waterland char	*uniTmp;
114*5c51f124SMoriah Waterland char 	*abi_sym_ptr;
115*5c51f124SMoriah Waterland char 	*ulim;
116*5c51f124SMoriah Waterland char 	*script;
117*5c51f124SMoriah Waterland 
118*5c51f124SMoriah Waterland int	eptnum;
119*5c51f124SMoriah Waterland int	sortflag;
120*5c51f124SMoriah Waterland int	nosetuid;
121*5c51f124SMoriah Waterland int	nocnflct;
122*5c51f124SMoriah Waterland int	warnflag = 0;
123*5c51f124SMoriah Waterland 
124*5c51f124SMoriah Waterland /* libadm/pkgparam.c */
125*5c51f124SMoriah Waterland extern void	set_PKGADM(char *newpath);
126*5c51f124SMoriah Waterland extern void	set_PKGLOC(char *newpath);
127*5c51f124SMoriah Waterland 
128*5c51f124SMoriah Waterland extern void set_limit(void);
129*5c51f124SMoriah Waterland 
130*5c51f124SMoriah Waterland int
131*5c51f124SMoriah Waterland main(int argc, char **argv)
132*5c51f124SMoriah Waterland {
133*5c51f124SMoriah Waterland 	FILE		*pp;
134*5c51f124SMoriah Waterland 	VFP_T		*cfTmpVfp;
135*5c51f124SMoriah Waterland 	VFP_T		*cfVfp;
136*5c51f124SMoriah Waterland 	char		*cmd;
137*5c51f124SMoriah Waterland 	char		*tp;
138*5c51f124SMoriah Waterland 	char		*prog;
139*5c51f124SMoriah Waterland 	char		*pt;
140*5c51f124SMoriah Waterland 	char		*vfstab_file = NULL;
141*5c51f124SMoriah Waterland 	char		line[1024];
142*5c51f124SMoriah Waterland 	char		outbuf[PATH_MAX];
143*5c51f124SMoriah Waterland 	int		c;
144*5c51f124SMoriah Waterland 	int		dbchg;
145*5c51f124SMoriah Waterland 	int		err;
146*5c51f124SMoriah Waterland 	int		fflag = 0;
147*5c51f124SMoriah Waterland 	int		map_client = 1;
148*5c51f124SMoriah Waterland 	int		n;
149*5c51f124SMoriah Waterland 	int		pkgrmremote = 0;	/* don't remove remote files */
150*5c51f124SMoriah Waterland 	struct cfent	*ept;
151*5c51f124SMoriah Waterland 
152*5c51f124SMoriah Waterland 	/* hookup signals */
153*5c51f124SMoriah Waterland 
154*5c51f124SMoriah Waterland 	(void) signal(SIGHUP, exit);
155*5c51f124SMoriah Waterland 	(void) signal(SIGINT, exit);
156*5c51f124SMoriah Waterland 	(void) signal(SIGQUIT, exit);
157*5c51f124SMoriah Waterland 
158*5c51f124SMoriah Waterland 	/* initialize locale mechanism */
159*5c51f124SMoriah Waterland 
160*5c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
161*5c51f124SMoriah Waterland 
162*5c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
163*5c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
164*5c51f124SMoriah Waterland #endif	/* !defined(TEXT_DOMAIN) */
165*5c51f124SMoriah Waterland 
166*5c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
167*5c51f124SMoriah Waterland 
168*5c51f124SMoriah Waterland 	/* determine program name */
169*5c51f124SMoriah Waterland 
170*5c51f124SMoriah Waterland 	prog = set_prog_name(argv[0]);
171*5c51f124SMoriah Waterland 
172*5c51f124SMoriah Waterland 	/* tell instzones interface how to access package output functions */
173*5c51f124SMoriah Waterland 
174*5c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
175*5c51f124SMoriah Waterland 
176*5c51f124SMoriah Waterland 	/* only allow root to run this program */
177*5c51f124SMoriah Waterland 
178*5c51f124SMoriah Waterland 	if (getuid() != 0) {
179*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOTROOT), prog);
180*5c51f124SMoriah Waterland 		exit(1);
181*5c51f124SMoriah Waterland 	}
182*5c51f124SMoriah Waterland 
183*5c51f124SMoriah Waterland 	ulim = getenv("PKG_ULIMIT");
184*5c51f124SMoriah Waterland 	script = getenv("PKG_PROC_SCRIPT");
185*5c51f124SMoriah Waterland 
186*5c51f124SMoriah Waterland 	if (ulim && script) {
187*5c51f124SMoriah Waterland 		set_limit();
188*5c51f124SMoriah Waterland 		clr_ulimit();
189*5c51f124SMoriah Waterland 	}
190*5c51f124SMoriah Waterland 
191*5c51f124SMoriah Waterland 	/* bug id 4244631, not ABI compliant */
192*5c51f124SMoriah Waterland 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
193*5c51f124SMoriah Waterland 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)
194*5c51f124SMoriah Waterland 		set_nonABI_symlinks();
195*5c51f124SMoriah Waterland 
196*5c51f124SMoriah Waterland 	/* bugId 4012147 */
197*5c51f124SMoriah Waterland 	if ((uniTmp = getenv("PKG_NO_UNIFIED")) != NULL)
198*5c51f124SMoriah Waterland 		map_client = 0;
199*5c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
200*5c51f124SMoriah Waterland 		progerr(gettext(ERR_ROOT_SET));
201*5c51f124SMoriah Waterland 		exit(1);
202*5c51f124SMoriah Waterland 	}
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "c:V:fAMR:?")) != EOF) {
205*5c51f124SMoriah Waterland 		switch (c) {
206*5c51f124SMoriah Waterland 			case 'f':
207*5c51f124SMoriah Waterland 			fflag++;
208*5c51f124SMoriah Waterland 			break;
209*5c51f124SMoriah Waterland 
210*5c51f124SMoriah Waterland 			case 'c':
211*5c51f124SMoriah Waterland 			classname = optarg;
212*5c51f124SMoriah Waterland 			/* validate that classname is acceptable */
213*5c51f124SMoriah Waterland 			if (strlen(classname) > (size_t)CLSSIZ) {
214*5c51f124SMoriah Waterland 				progerr(gettext(ERR_CLASSLONG));
215*5c51f124SMoriah Waterland 				exit(1);
216*5c51f124SMoriah Waterland 			}
217*5c51f124SMoriah Waterland 			for (pt = classname; *pt; pt++) {
218*5c51f124SMoriah Waterland 				if (!isalpha(*pt) && !isdigit(*pt)) {
219*5c51f124SMoriah Waterland 					progerr(gettext(ERR_CLASSCHAR));
220*5c51f124SMoriah Waterland 					exit(1);
221*5c51f124SMoriah Waterland 				}
222*5c51f124SMoriah Waterland 			}
223*5c51f124SMoriah Waterland 			break;
224*5c51f124SMoriah Waterland 
225*5c51f124SMoriah Waterland 		/*
226*5c51f124SMoriah Waterland 		 * Don't map the client filesystem onto the server's. Assume
227*5c51f124SMoriah Waterland 		 * the mounts have been made for us.
228*5c51f124SMoriah Waterland 		 */
229*5c51f124SMoriah Waterland 			case 'M':
230*5c51f124SMoriah Waterland 			map_client = 0;
231*5c51f124SMoriah Waterland 			break;
232*5c51f124SMoriah Waterland 
233*5c51f124SMoriah Waterland 		/*
234*5c51f124SMoriah Waterland 		 * Allow admin to establish the client filesystem using a
235*5c51f124SMoriah Waterland 		 * vfstab-like file of stable format.
236*5c51f124SMoriah Waterland 		 */
237*5c51f124SMoriah Waterland 			case 'V':
238*5c51f124SMoriah Waterland 			vfstab_file = flex_device(optarg, 2);
239*5c51f124SMoriah Waterland 			map_client = 1;
240*5c51f124SMoriah Waterland 			break;
241*5c51f124SMoriah Waterland 
242*5c51f124SMoriah Waterland 			case 'A':
243*5c51f124SMoriah Waterland 			pkgrmremote++;
244*5c51f124SMoriah Waterland 			break;
245*5c51f124SMoriah Waterland 
246*5c51f124SMoriah Waterland 			case 'R':	/* added for newroot option */
247*5c51f124SMoriah Waterland 			if (!set_inst_root(optarg)) {
248*5c51f124SMoriah Waterland 				progerr(gettext(ERR_ROOT_CMD));
249*5c51f124SMoriah Waterland 				exit(1);
250*5c51f124SMoriah Waterland 			}
251*5c51f124SMoriah Waterland 			break;
252*5c51f124SMoriah Waterland 
253*5c51f124SMoriah Waterland 			default:
254*5c51f124SMoriah Waterland 			usage();
255*5c51f124SMoriah Waterland 			/*NOTREACHED*/
256*5c51f124SMoriah Waterland 			/*
257*5c51f124SMoriah Waterland 			 * Although usage() calls a noreturn function,
258*5c51f124SMoriah Waterland 			 * needed to add return (1);  so that main() would
259*5c51f124SMoriah Waterland 			 * pass compilation checks. The statement below
260*5c51f124SMoriah Waterland 			 * should never be executed.
261*5c51f124SMoriah Waterland 			 */
262*5c51f124SMoriah Waterland 			return (1);
263*5c51f124SMoriah Waterland 		}
264*5c51f124SMoriah Waterland 	}
265*5c51f124SMoriah Waterland 
266*5c51f124SMoriah Waterland 	if (pkgrmremote && (!is_an_inst_root() || fflag || INSTALF)) {
267*5c51f124SMoriah Waterland 		usage();
268*5c51f124SMoriah Waterland 		/*NOTREACHED*/
269*5c51f124SMoriah Waterland 	}
270*5c51f124SMoriah Waterland 
271*5c51f124SMoriah Waterland 	/*
272*5c51f124SMoriah Waterland 	 * Get the mount table info and store internally.
273*5c51f124SMoriah Waterland 	 */
274*5c51f124SMoriah Waterland 	if (get_mntinfo(map_client, vfstab_file))
275*5c51f124SMoriah Waterland 		exit(1);
276*5c51f124SMoriah Waterland 
277*5c51f124SMoriah Waterland 	/*
278*5c51f124SMoriah Waterland 	 * This function defines the standard /var/... directories used later
279*5c51f124SMoriah Waterland 	 * to construct the paths to the various databases.
280*5c51f124SMoriah Waterland 	 */
281*5c51f124SMoriah Waterland 	(void) set_PKGpaths(get_inst_root());
282*5c51f124SMoriah Waterland 
283*5c51f124SMoriah Waterland 	/*
284*5c51f124SMoriah Waterland 	 * If this is being installed on a client whose /var filesystem is
285*5c51f124SMoriah Waterland 	 * mounted in some odd way, remap the administrative paths to the
286*5c51f124SMoriah Waterland 	 * real filesystem. This could be avoided by simply mounting up the
287*5c51f124SMoriah Waterland 	 * client now; but we aren't yet to the point in the process where
288*5c51f124SMoriah Waterland 	 * modification of the filesystem is permitted.
289*5c51f124SMoriah Waterland 	 */
290*5c51f124SMoriah Waterland 	if (is_an_inst_root()) {
291*5c51f124SMoriah Waterland 		int fsys_value;
292*5c51f124SMoriah Waterland 
293*5c51f124SMoriah Waterland 		fsys_value = fsys(get_PKGLOC());
294*5c51f124SMoriah Waterland 		if (use_srvr_map_n(fsys_value))
295*5c51f124SMoriah Waterland 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
296*5c51f124SMoriah Waterland 
297*5c51f124SMoriah Waterland 		fsys_value = fsys(get_PKGADM());
298*5c51f124SMoriah Waterland 		if (use_srvr_map_n(fsys_value))
299*5c51f124SMoriah Waterland 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
300*5c51f124SMoriah Waterland 	}
301*5c51f124SMoriah Waterland 
302*5c51f124SMoriah Waterland 	sortflag = 0;
303*5c51f124SMoriah Waterland 
304*5c51f124SMoriah Waterland 	/*
305*5c51f124SMoriah Waterland 	 * get the package name and verify length is not too long
306*5c51f124SMoriah Waterland 	 */
307*5c51f124SMoriah Waterland 
308*5c51f124SMoriah Waterland 	pkginst = argv[optind++];
309*5c51f124SMoriah Waterland 	if (pkginst == NULL) {
310*5c51f124SMoriah Waterland 		usage();
311*5c51f124SMoriah Waterland 		/*NOTREACHED*/
312*5c51f124SMoriah Waterland 
313*5c51f124SMoriah Waterland 	}
314*5c51f124SMoriah Waterland 
315*5c51f124SMoriah Waterland 	n = strlen(pkginst);
316*5c51f124SMoriah Waterland 	if (n > PKGSIZ) {
317*5c51f124SMoriah Waterland 		progerr(gettext(ERR_PKGNAME_TOO_LONG), PKGSIZ, n, n-PKGSIZ,
318*5c51f124SMoriah Waterland 		    PKGSIZ);
319*5c51f124SMoriah Waterland 		usage();
320*5c51f124SMoriah Waterland 		/*NOTREACHED*/
321*5c51f124SMoriah Waterland 	}
322*5c51f124SMoriah Waterland 
323*5c51f124SMoriah Waterland 	/*
324*5c51f124SMoriah Waterland 	 * The following is used to setup the environment. Note that the
325*5c51f124SMoriah Waterland 	 * variable 'BASEDIR' is only meaningful for this utility if there
326*5c51f124SMoriah Waterland 	 * is an install root, recorded in PKG_INSTALL_ROOT. Otherwise, this
327*5c51f124SMoriah Waterland 	 * utility can create a file or directory anywhere unfettered by
328*5c51f124SMoriah Waterland 	 * the basedir associated with the package instance.
329*5c51f124SMoriah Waterland 	 */
330*5c51f124SMoriah Waterland 	if ((err = set_basedirs(0, NULL, pkginst, 1)) != 0)
331*5c51f124SMoriah Waterland 		exit(err);
332*5c51f124SMoriah Waterland 
333*5c51f124SMoriah Waterland 	if (INSTALF)
334*5c51f124SMoriah Waterland 		mkbasedir(0, get_basedir());
335*5c51f124SMoriah Waterland 
336*5c51f124SMoriah Waterland 	if (fflag) {
337*5c51f124SMoriah Waterland 		/* installf and removef must only have pkginst */
338*5c51f124SMoriah Waterland 		if (optind != argc) {
339*5c51f124SMoriah Waterland 			usage();
340*5c51f124SMoriah Waterland 			/*NOTREACHED*/
341*5c51f124SMoriah Waterland 		}
342*5c51f124SMoriah Waterland 	} else {
343*5c51f124SMoriah Waterland 		/*
344*5c51f124SMoriah Waterland 		 * installf and removef must have at minimum
345*5c51f124SMoriah Waterland 		 * pkginst & pathname specified on command line
346*5c51f124SMoriah Waterland 		 */
347*5c51f124SMoriah Waterland 		if (optind >= argc) {
348*5c51f124SMoriah Waterland 			usage();
349*5c51f124SMoriah Waterland 			/*NOTREACHED*/
350*5c51f124SMoriah Waterland 		}
351*5c51f124SMoriah Waterland 	}
352*5c51f124SMoriah Waterland 	if (REMOVEF) {
353*5c51f124SMoriah Waterland 		if (classname) {
354*5c51f124SMoriah Waterland 			usage();
355*5c51f124SMoriah Waterland 		}
356*5c51f124SMoriah Waterland 	}
357*5c51f124SMoriah Waterland 	if (pkgnmchk(pkginst, "all", 0)) {
358*5c51f124SMoriah Waterland 		progerr(gettext(ERR_INVAL), pkginst);
359*5c51f124SMoriah Waterland 		exit(1);
360*5c51f124SMoriah Waterland 	}
361*5c51f124SMoriah Waterland 	if (fpkginst(pkginst, NULL, NULL) == NULL) {
362*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOTINST), pkginst);
363*5c51f124SMoriah Waterland 		exit(1);
364*5c51f124SMoriah Waterland 	}
365*5c51f124SMoriah Waterland 
366*5c51f124SMoriah Waterland #ifdef	ALLOW_EXCEPTION_PKG_LIST
367*5c51f124SMoriah Waterland 	/*
368*5c51f124SMoriah Waterland 	 * *********************************************************************
369*5c51f124SMoriah Waterland 	 * this feature is removed starting with Solaris 10 - there is no built
370*5c51f124SMoriah Waterland 	 * in list of packages that should be run "the old way"
371*5c51f124SMoriah Waterland 	 * *********************************************************************
372*5c51f124SMoriah Waterland 	 */
373*5c51f124SMoriah Waterland 	/* Until 2.9, set it from the execption list */
374*5c51f124SMoriah Waterland 	if (pkginst && exception_pkg(pkginst, LINK))
375*5c51f124SMoriah Waterland 		set_nonABI_symlinks();
376*5c51f124SMoriah Waterland #endif
377*5c51f124SMoriah Waterland 	/*
378*5c51f124SMoriah Waterland 	 * This maps the client filesystems into the server's space.
379*5c51f124SMoriah Waterland 	 */
380*5c51f124SMoriah Waterland 	if (map_client && !mount_client())
381*5c51f124SMoriah Waterland 		logerr(gettext(MSG_MANMOUNT));
382*5c51f124SMoriah Waterland 
383*5c51f124SMoriah Waterland 	/* open the package database (contents) file */
384*5c51f124SMoriah Waterland 
385*5c51f124SMoriah Waterland 	if (!ocfile(&cfVfp, &cfTmpVfp, 0L)) {
386*5c51f124SMoriah Waterland 		quit(1);
387*5c51f124SMoriah Waterland 	}
388*5c51f124SMoriah Waterland 
389*5c51f124SMoriah Waterland 	if (fflag) {
390*5c51f124SMoriah Waterland 		dbchg = dofinal(cfVfp, cfTmpVfp, REMOVEF, classname, prog);
391*5c51f124SMoriah Waterland 	} else {
392*5c51f124SMoriah Waterland 		if (INSTALF) {
393*5c51f124SMoriah Waterland 			dbst = INST_RDY;
394*5c51f124SMoriah Waterland 			if (installf(argc-optind, &argv[optind]))
395*5c51f124SMoriah Waterland 				quit(1);
396*5c51f124SMoriah Waterland 		} else {
397*5c51f124SMoriah Waterland 			dbst = RM_RDY;
398*5c51f124SMoriah Waterland 			removef(argc-optind, &argv[optind]);
399*5c51f124SMoriah Waterland 		}
400*5c51f124SMoriah Waterland 
401*5c51f124SMoriah Waterland 		dbchg = pkgdbmerg(cfVfp, cfTmpVfp, extlist, 0);
402*5c51f124SMoriah Waterland 		if (dbchg < 0) {
403*5c51f124SMoriah Waterland 			progerr(gettext(ERR_MERG));
404*5c51f124SMoriah Waterland 			quit(99);
405*5c51f124SMoriah Waterland 		}
406*5c51f124SMoriah Waterland 	}
407*5c51f124SMoriah Waterland 
408*5c51f124SMoriah Waterland 	if (dbchg) {
409*5c51f124SMoriah Waterland 		if ((n = swapcfile(&cfVfp, &cfTmpVfp, pkginst, 1))
410*5c51f124SMoriah Waterland 			== RESULT_WRN) {
411*5c51f124SMoriah Waterland 		    warnflag++;
412*5c51f124SMoriah Waterland 		} else if (n == RESULT_ERR) {
413*5c51f124SMoriah Waterland 		    quit(99);
414*5c51f124SMoriah Waterland 		}
415*5c51f124SMoriah Waterland 	}
416*5c51f124SMoriah Waterland 
417*5c51f124SMoriah Waterland 	relslock();
418*5c51f124SMoriah Waterland 
419*5c51f124SMoriah Waterland 	if (REMOVEF && !fflag) {
420*5c51f124SMoriah Waterland 		for (n = 0; extlist[n]; n++) {
421*5c51f124SMoriah Waterland 			ept = &(extlist[n]->cf_ent);
422*5c51f124SMoriah Waterland 
423*5c51f124SMoriah Waterland 			/* Skip duplicated paths */
424*5c51f124SMoriah Waterland 			if ((n > 0) && (strncmp(ept->path,
425*5c51f124SMoriah Waterland 			    extlist[n-1]->cf_ent.path, PATH_MAX) == 0)) {
426*5c51f124SMoriah Waterland 				continue;
427*5c51f124SMoriah Waterland 			}
428*5c51f124SMoriah Waterland 
429*5c51f124SMoriah Waterland 			if (!extlist[n]->mstat.shared) {
430*5c51f124SMoriah Waterland 				/*
431*5c51f124SMoriah Waterland 				 * Only output paths that can be deleted.
432*5c51f124SMoriah Waterland 				 * so need to skip if the object is owned
433*5c51f124SMoriah Waterland 				 * by a remote server and removal is not
434*5c51f124SMoriah Waterland 				 * being forced.
435*5c51f124SMoriah Waterland 				 */
436*5c51f124SMoriah Waterland 				if (ept->pinfo &&
437*5c51f124SMoriah Waterland 				    (ept->pinfo->status == SERVED_FILE) &&
438*5c51f124SMoriah Waterland 				    !pkgrmremote)
439*5c51f124SMoriah Waterland 					continue;
440*5c51f124SMoriah Waterland 
441*5c51f124SMoriah Waterland 				c = 0;
442*5c51f124SMoriah Waterland 				if (is_a_cl_basedir() && !is_an_inst_root()) {
443*5c51f124SMoriah Waterland 					c = strlen(get_client_basedir());
444*5c51f124SMoriah Waterland 					(void) snprintf(outbuf, sizeof (outbuf),
445*5c51f124SMoriah Waterland 						"%s/%s\n", get_basedir(),
446*5c51f124SMoriah Waterland 						&(ept->path[c]));
447*5c51f124SMoriah Waterland 				} else if (is_an_inst_root()) {
448*5c51f124SMoriah Waterland 					(void) snprintf(outbuf, sizeof (outbuf),
449*5c51f124SMoriah Waterland 						"%s/%s\n", get_inst_root(),
450*5c51f124SMoriah Waterland 						&(ept->path[c]));
451*5c51f124SMoriah Waterland 				} else {
452*5c51f124SMoriah Waterland 					(void) snprintf(outbuf, sizeof (outbuf),
453*5c51f124SMoriah Waterland 						"%s\n", &(ept->path[c]));
454*5c51f124SMoriah Waterland 				}
455*5c51f124SMoriah Waterland 				canonize(outbuf);
456*5c51f124SMoriah Waterland 				(void) printf("%s", outbuf);
457*5c51f124SMoriah Waterland 			}
458*5c51f124SMoriah Waterland 		}
459*5c51f124SMoriah Waterland 	} else if (INSTALF && !fflag) {
460*5c51f124SMoriah Waterland 		for (n = 0; extlist[n]; n++) {
461*5c51f124SMoriah Waterland 			ept = &(extlist[n]->cf_ent);
462*5c51f124SMoriah Waterland 
463*5c51f124SMoriah Waterland 			if (strchr("dxcbp", ept->ftype)) {
464*5c51f124SMoriah Waterland 				tp = fixpath(ept->path);
465*5c51f124SMoriah Waterland 				(void) averify(1, &ept->ftype,
466*5c51f124SMoriah Waterland 					tp, &ept->ainfo);
467*5c51f124SMoriah Waterland 			}
468*5c51f124SMoriah Waterland 		}
469*5c51f124SMoriah Waterland 	}
470*5c51f124SMoriah Waterland 
471*5c51f124SMoriah Waterland 	/* Sort the contents files if needed */
472*5c51f124SMoriah Waterland 	if (sortflag) {
473*5c51f124SMoriah Waterland 		int n;
474*5c51f124SMoriah Waterland 
475*5c51f124SMoriah Waterland 		warnflag += (ocfile(&cfVfp, &cfTmpVfp, 0L)) ? 0 : 1;
476*5c51f124SMoriah Waterland 		if (!warnflag) {
477*5c51f124SMoriah Waterland 			size_t	len;
478*5c51f124SMoriah Waterland 
479*5c51f124SMoriah Waterland 			len = strlen(CMD_SORT) + strlen(get_PKGADM()) +
480*5c51f124SMoriah Waterland 				strlen("/contents") + 5;
481*5c51f124SMoriah Waterland 			cmd = (char *)malloc(len);
482*5c51f124SMoriah Waterland 			(void) snprintf(cmd, len, "%s %s/contents",
483*5c51f124SMoriah Waterland 				CMD_SORT, get_PKGADM());
484*5c51f124SMoriah Waterland 			pp = popen(cmd, "r");
485*5c51f124SMoriah Waterland 			if (pp == NULL) {
486*5c51f124SMoriah Waterland 				(void) vfpClose(&cfVfp);
487*5c51f124SMoriah Waterland 				(void) vfpClose(&cfTmpVfp);
488*5c51f124SMoriah Waterland 				free(cmd);
489*5c51f124SMoriah Waterland 				progerr(gettext(ERR_SORT));
490*5c51f124SMoriah Waterland 				quit(1);
491*5c51f124SMoriah Waterland 			}
492*5c51f124SMoriah Waterland 			while (fgets(line, 1024, pp) != NULL) {
493*5c51f124SMoriah Waterland 				if (line[0] != DUP_ENTRY) {
494*5c51f124SMoriah Waterland 					vfpPuts(cfTmpVfp, line);
495*5c51f124SMoriah Waterland 				}
496*5c51f124SMoriah Waterland 			}
497*5c51f124SMoriah Waterland 			free(cmd);
498*5c51f124SMoriah Waterland 			(void) pclose(pp);
499*5c51f124SMoriah Waterland 			n = swapcfile(&cfVfp, &cfTmpVfp, pkginst, 1);
500*5c51f124SMoriah Waterland 			if (n == RESULT_WRN) {
501*5c51f124SMoriah Waterland 				warnflag++;
502*5c51f124SMoriah Waterland 			} else if (n == RESULT_ERR) {
503*5c51f124SMoriah Waterland 				quit(99);
504*5c51f124SMoriah Waterland 			}
505*5c51f124SMoriah Waterland 
506*5c51f124SMoriah Waterland 			relslock();	/* Unlock the database. */
507*5c51f124SMoriah Waterland 		}
508*5c51f124SMoriah Waterland 	}
509*5c51f124SMoriah Waterland 
510*5c51f124SMoriah Waterland 	z_destroyMountTable();
511*5c51f124SMoriah Waterland 
512*5c51f124SMoriah Waterland 	quit(warnflag ? 1 : 0);
513*5c51f124SMoriah Waterland 	/* LINTED: no return */
514*5c51f124SMoriah Waterland }
515*5c51f124SMoriah Waterland 
516*5c51f124SMoriah Waterland void
517*5c51f124SMoriah Waterland quit(int n)
518*5c51f124SMoriah Waterland {
519*5c51f124SMoriah Waterland 	char *prog = get_prog_name();
520*5c51f124SMoriah Waterland 
521*5c51f124SMoriah Waterland 	unmount_client();
522*5c51f124SMoriah Waterland 
523*5c51f124SMoriah Waterland 	if (ulim && script) {
524*5c51f124SMoriah Waterland 		if (REMOVEF) {
525*5c51f124SMoriah Waterland 			set_ulimit(script, gettext(ERR_R_FAIL));
526*5c51f124SMoriah Waterland 		} else {
527*5c51f124SMoriah Waterland 			set_ulimit(script, gettext(ERR_I_FAIL));
528*5c51f124SMoriah Waterland 		}
529*5c51f124SMoriah Waterland 	}
530*5c51f124SMoriah Waterland 
531*5c51f124SMoriah Waterland 	exit(n);
532*5c51f124SMoriah Waterland }
533*5c51f124SMoriah Waterland 
534*5c51f124SMoriah Waterland void
535*5c51f124SMoriah Waterland usage(void)
536*5c51f124SMoriah Waterland {
537*5c51f124SMoriah Waterland 	char *prog = get_prog_name();
538*5c51f124SMoriah Waterland 
539*5c51f124SMoriah Waterland 	if (REMOVEF) {
540*5c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext(ERR_USAGE0), prog, prog);
541*5c51f124SMoriah Waterland 	} else {
542*5c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext(ERR_USAGE1), prog, prog, prog);
543*5c51f124SMoriah Waterland 	}
544*5c51f124SMoriah Waterland 	exit(1);
545*5c51f124SMoriah Waterland }
546