xref: /illumos-gate/usr/src/cmd/svr4pkg/pkgchk/main.c (revision 5c51f124)
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 <limits.h>
33*5c51f124SMoriah Waterland #include <unistd.h>
34*5c51f124SMoriah Waterland #include <stdlib.h>
35*5c51f124SMoriah Waterland #include <string.h>
36*5c51f124SMoriah Waterland #include <ctype.h>
37*5c51f124SMoriah Waterland #include <dirent.h>
38*5c51f124SMoriah Waterland #include <sys/stat.h>
39*5c51f124SMoriah Waterland #include <pkginfo.h>
40*5c51f124SMoriah Waterland #include <pkglocs.h>
41*5c51f124SMoriah Waterland #include <sys/types.h>
42*5c51f124SMoriah Waterland #include <pkgstrct.h>
43*5c51f124SMoriah Waterland #include <pkgtrans.h>
44*5c51f124SMoriah Waterland #include <locale.h>
45*5c51f124SMoriah Waterland #include <libintl.h>
46*5c51f124SMoriah Waterland #include <pkglib.h>
47*5c51f124SMoriah Waterland #include <libadm.h>
48*5c51f124SMoriah Waterland #include <libinst.h>
49*5c51f124SMoriah Waterland 
50*5c51f124SMoriah Waterland #define	MAXPATHS	1024
51*5c51f124SMoriah Waterland 
52*5c51f124SMoriah Waterland #define	MSG_CHK_STRM	"Checking uninstalled stream format package " \
53*5c51f124SMoriah Waterland 				"<%s> from <%s>\n"
54*5c51f124SMoriah Waterland #define	MSG_CHK_DIR	"Checking uninstalled directory format package " \
55*5c51f124SMoriah Waterland 				"<%s> from <%s>\n"
56*5c51f124SMoriah Waterland #define	MSG_NOTROOT	"NOTE: \"root\" permission may be required to " \
57*5c51f124SMoriah Waterland 				"validate all objects in the client filesystem."
58*5c51f124SMoriah Waterland #define	MSG_CONT	"Continuing."
59*5c51f124SMoriah Waterland 
60*5c51f124SMoriah Waterland #define	WRN_F_SPOOL	"WARNING: %s is spooled. Ignoring \"f\" argument"
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland #define	ERR_ROOT_SET	"Could not set install root from the environment."
63*5c51f124SMoriah Waterland #define	ERR_ROOT_CMD	"Command line install root contends with environment."
64*5c51f124SMoriah Waterland #define	ERR_IOPEN	"unable to open input file <%s>"
65*5c51f124SMoriah Waterland #define	ERR_IEMPTY	"no pathnames in file specified by -i option"
66*5c51f124SMoriah Waterland #define	ERR_POPTION	"no pathname included with -p option"
67*5c51f124SMoriah Waterland #define	ERR_PARTIAL_POPTION	"no pathname included with -P option"
68*5c51f124SMoriah Waterland #define	ERR_MAXPATHS	"too many pathnames in option list (limit is %d)"
69*5c51f124SMoriah Waterland #define	ERR_NOTROOT	"You must be \"root\" for \"%s -f\" to" \
70*5c51f124SMoriah Waterland 					"execute properly."
71*5c51f124SMoriah Waterland #define	ERR_SEL_PKG "No packages selected for verification."
72*5c51f124SMoriah Waterland #define	ERR_CAT_LNGTH "The category argument exceeds the SVr4 ABI\n" \
73*5c51f124SMoriah Waterland 		"        defined maximum supported length of 16 characters."
74*5c51f124SMoriah Waterland #define	ERR_CAT_FND "Category argument <%s> cannot be found."
75*5c51f124SMoriah Waterland #define	ERR_CAT_INV "Category argument <%s> is invalid."
76*5c51f124SMoriah Waterland #define	ERR_TOO_MANY "too many pathnames in list, limit is %d"
77*5c51f124SMoriah Waterland #define	ERR_PATHS_INVALID "Pathnames in %s are not valid."
78*5c51f124SMoriah Waterland #define	ERR_MKDIR "unable to make directory <%s>"
79*5c51f124SMoriah Waterland #define	ERR_USAGE	"usage:\n" \
80*5c51f124SMoriah Waterland 		"\t%s [-l|vqacnxf] [-R rootdir] [-p path[, ...] | " \
81*5c51f124SMoriah Waterland 		"-P path[, ...]]\n" \
82*5c51f124SMoriah Waterland 		"\t\t[-i file] [options]\n" \
83*5c51f124SMoriah Waterland 		"\t%s -d device [-f][-l|v] [-p path[, ...] | " \
84*5c51f124SMoriah Waterland 		"-P path[, ...]]\n" \
85*5c51f124SMoriah Waterland 		"\t\t[-V ...] [-M] [-i file] [-Y category[, ...] | " \
86*5c51f124SMoriah Waterland 		"pkginst [...]]\n" \
87*5c51f124SMoriah Waterland 		"\twhere options may include ONE of the " \
88*5c51f124SMoriah Waterland 		"following:\n " \
89*5c51f124SMoriah Waterland 		"\t\t-m pkgmap [-e envfile]\n" \
90*5c51f124SMoriah Waterland 		"\t\tpkginst [...]\n" \
91*5c51f124SMoriah Waterland 		"\t\t-Y category[, ...]\n"
92*5c51f124SMoriah Waterland 
93*5c51f124SMoriah Waterland #define	LINK	1
94*5c51f124SMoriah Waterland 
95*5c51f124SMoriah Waterland char	**pkg = NULL;
96*5c51f124SMoriah Waterland int	pkgcnt = 0;
97*5c51f124SMoriah Waterland char	*basedir;
98*5c51f124SMoriah Waterland char	*pathlist[MAXPATHS], *ppathlist[MAXPATHS], pkgspool[PATH_MAX];
99*5c51f124SMoriah Waterland short	used[MAXPATHS];
100*5c51f124SMoriah Waterland short	npaths;
101*5c51f124SMoriah Waterland struct cfent **eptlist;
102*5c51f124SMoriah Waterland 
103*5c51f124SMoriah Waterland int	aflag = (-1);
104*5c51f124SMoriah Waterland int	cflag = (-1);
105*5c51f124SMoriah Waterland int	vflag = 0;
106*5c51f124SMoriah Waterland int	nflag = 0;
107*5c51f124SMoriah Waterland int	lflag = 0;
108*5c51f124SMoriah Waterland int	Lflag = 0;
109*5c51f124SMoriah Waterland int	fflag = 0;
110*5c51f124SMoriah Waterland int	xflag = 0;
111*5c51f124SMoriah Waterland int	qflag = 0;
112*5c51f124SMoriah Waterland int	Rflag = 0;
113*5c51f124SMoriah Waterland int	dflag = 0;
114*5c51f124SMoriah Waterland char 	*device;
115*5c51f124SMoriah Waterland 
116*5c51f124SMoriah Waterland char	*uniTmp;
117*5c51f124SMoriah Waterland 
118*5c51f124SMoriah Waterland static char	*mapfile,
119*5c51f124SMoriah Waterland 		*spooldir,
120*5c51f124SMoriah Waterland 		*tmpdir,
121*5c51f124SMoriah Waterland 		*envfile;
122*5c51f124SMoriah Waterland static int	errflg = 0;
123*5c51f124SMoriah Waterland static int	map_client = 1;
124*5c51f124SMoriah Waterland 
125*5c51f124SMoriah Waterland void	quit(int);
126*5c51f124SMoriah Waterland static void	setpathlist(char *);
127*5c51f124SMoriah Waterland static void	usage(void);
128*5c51f124SMoriah Waterland 
129*5c51f124SMoriah Waterland extern	char	**environ;
130*5c51f124SMoriah Waterland extern	char	*pkgdir;
131*5c51f124SMoriah Waterland 
132*5c51f124SMoriah Waterland /* checkmap.c */
133*5c51f124SMoriah Waterland extern int	checkmap(int, int, char *, char *, char *, char *, int);
134*5c51f124SMoriah Waterland /* scriptvfy.c */
135*5c51f124SMoriah Waterland extern int	checkscripts(char *inst_dir, int silent);
136*5c51f124SMoriah Waterland 
137*5c51f124SMoriah Waterland int
138*5c51f124SMoriah Waterland main(int argc, char *argv[])
139*5c51f124SMoriah Waterland {
140*5c51f124SMoriah Waterland 	int	pkgfmt = 0;	/* Makes more sense as a pointer, but */
141*5c51f124SMoriah Waterland 				/*	18N is compromised. */
142*5c51f124SMoriah Waterland 	char	file[PATH_MAX+1],
143*5c51f124SMoriah Waterland 		*abi_sym_ptr,
144*5c51f124SMoriah Waterland 		*vfstab_file = NULL;
145*5c51f124SMoriah Waterland 	char *all_pkgs[4] = {"all", NULL};
146*5c51f124SMoriah Waterland 	char **category = NULL;
147*5c51f124SMoriah Waterland 	char *catg_arg = NULL;
148*5c51f124SMoriah Waterland 	int	c;
149*5c51f124SMoriah Waterland 	int	n = 0;
150*5c51f124SMoriah Waterland 	char	*prog,
151*5c51f124SMoriah Waterland 		*Rvalue,
152*5c51f124SMoriah Waterland 		*dvalue;
153*5c51f124SMoriah Waterland 	int dbcreate = 0;
154*5c51f124SMoriah Waterland 	int pathtype;
155*5c51f124SMoriah Waterland 
156*5c51f124SMoriah Waterland 	/* initialize locale mechanism */
157*5c51f124SMoriah Waterland 
158*5c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
159*5c51f124SMoriah Waterland 
160*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
161*5c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
162*5c51f124SMoriah Waterland #endif
163*5c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
164*5c51f124SMoriah Waterland 
165*5c51f124SMoriah Waterland 	/* determine program name */
166*5c51f124SMoriah Waterland 
167*5c51f124SMoriah Waterland 	prog = set_prog_name(argv[0]);
168*5c51f124SMoriah Waterland 
169*5c51f124SMoriah Waterland 	/* establish installation root directory */
170*5c51f124SMoriah Waterland 
171*5c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
172*5c51f124SMoriah Waterland 		progerr(gettext(ERR_ROOT_SET));
173*5c51f124SMoriah Waterland 		quit(1);
174*5c51f124SMoriah Waterland 	}
175*5c51f124SMoriah Waterland 
176*5c51f124SMoriah Waterland 	/* check if not ABI compliant mode */
177*5c51f124SMoriah Waterland 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
178*5c51f124SMoriah Waterland 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
179*5c51f124SMoriah Waterland 		set_nonABI_symlinks();
180*5c51f124SMoriah Waterland 	}
181*5c51f124SMoriah Waterland 
182*5c51f124SMoriah Waterland 	/* bugId 4012147 */
183*5c51f124SMoriah Waterland 	if ((uniTmp = getenv("PKG_NO_UNIFIED")) != NULL)
184*5c51f124SMoriah Waterland 		map_client = 0;
185*5c51f124SMoriah Waterland 
186*5c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "Y:R:e:p:d:nLli:vaV:Mm:cqxfQP:?"))
187*5c51f124SMoriah Waterland 			!= EOF) {
188*5c51f124SMoriah Waterland 		switch (c) {
189*5c51f124SMoriah Waterland 		case 'p':
190*5c51f124SMoriah Waterland 			pathlist[npaths] = strtok(optarg, " , ");
191*5c51f124SMoriah Waterland 			if (pathlist[npaths++] == NULL) {
192*5c51f124SMoriah Waterland 				progerr(gettext(ERR_POPTION));
193*5c51f124SMoriah Waterland 				quit(1);
194*5c51f124SMoriah Waterland 			}
195*5c51f124SMoriah Waterland 			while (pathlist[npaths] = strtok(NULL, " , ")) {
196*5c51f124SMoriah Waterland 				if (npaths++ >= MAXPATHS) {
197*5c51f124SMoriah Waterland 					progerr(gettext(ERR_MAXPATHS),
198*5c51f124SMoriah Waterland 						MAXPATHS);
199*5c51f124SMoriah Waterland 					quit(1);
200*5c51f124SMoriah Waterland 				}
201*5c51f124SMoriah Waterland 			}
202*5c51f124SMoriah Waterland 			break;
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 		case 'd':
205*5c51f124SMoriah Waterland 			dvalue = optarg;
206*5c51f124SMoriah Waterland 			dflag = 1;
207*5c51f124SMoriah Waterland 			break;
208*5c51f124SMoriah Waterland 
209*5c51f124SMoriah Waterland 		case 'n':
210*5c51f124SMoriah Waterland 			nflag++;
211*5c51f124SMoriah Waterland 			break;
212*5c51f124SMoriah Waterland 
213*5c51f124SMoriah Waterland 		case 'M':
214*5c51f124SMoriah Waterland 			map_client = 0;
215*5c51f124SMoriah Waterland 			break;
216*5c51f124SMoriah Waterland 
217*5c51f124SMoriah Waterland 		/*
218*5c51f124SMoriah Waterland 		 * Allow admin to establish the client filesystem using a
219*5c51f124SMoriah Waterland 		 * vfstab-like file of stable format.
220*5c51f124SMoriah Waterland 		 */
221*5c51f124SMoriah Waterland 		case 'V':
222*5c51f124SMoriah Waterland 			vfstab_file = flex_device(optarg, 2);
223*5c51f124SMoriah Waterland 			map_client = 1;
224*5c51f124SMoriah Waterland 			break;
225*5c51f124SMoriah Waterland 
226*5c51f124SMoriah Waterland 		case 'f':
227*5c51f124SMoriah Waterland 			if (getuid()) {
228*5c51f124SMoriah Waterland 				progerr(gettext(ERR_NOTROOT), prog);
229*5c51f124SMoriah Waterland 				quit(1);
230*5c51f124SMoriah Waterland 			}
231*5c51f124SMoriah Waterland 			fflag++;
232*5c51f124SMoriah Waterland 			break;
233*5c51f124SMoriah Waterland 
234*5c51f124SMoriah Waterland 		case 'i':
235*5c51f124SMoriah Waterland 			setpathlist(optarg);
236*5c51f124SMoriah Waterland 			break;
237*5c51f124SMoriah Waterland 
238*5c51f124SMoriah Waterland 		case 'v':
239*5c51f124SMoriah Waterland 			vflag++;
240*5c51f124SMoriah Waterland 			break;
241*5c51f124SMoriah Waterland 
242*5c51f124SMoriah Waterland 		case 'l':
243*5c51f124SMoriah Waterland 			lflag++;
244*5c51f124SMoriah Waterland 			break;
245*5c51f124SMoriah Waterland 
246*5c51f124SMoriah Waterland 		case 'L':
247*5c51f124SMoriah Waterland 			Lflag++;
248*5c51f124SMoriah Waterland 			break;
249*5c51f124SMoriah Waterland 
250*5c51f124SMoriah Waterland 		case 'x':
251*5c51f124SMoriah Waterland 			if (aflag < 0)
252*5c51f124SMoriah Waterland 				aflag = 0;
253*5c51f124SMoriah Waterland 			if (cflag < 0)
254*5c51f124SMoriah Waterland 				cflag = 0;
255*5c51f124SMoriah Waterland 			xflag++;
256*5c51f124SMoriah Waterland 			break;
257*5c51f124SMoriah Waterland 
258*5c51f124SMoriah Waterland 		case 'q':
259*5c51f124SMoriah Waterland 			qflag++;
260*5c51f124SMoriah Waterland 			break;
261*5c51f124SMoriah Waterland 
262*5c51f124SMoriah Waterland 		case 'a':
263*5c51f124SMoriah Waterland 			if (cflag < 0)
264*5c51f124SMoriah Waterland 				cflag = 0;
265*5c51f124SMoriah Waterland 			aflag = 1;
266*5c51f124SMoriah Waterland 			break;
267*5c51f124SMoriah Waterland 
268*5c51f124SMoriah Waterland 		case 'c':
269*5c51f124SMoriah Waterland 			if (aflag < 0)
270*5c51f124SMoriah Waterland 				aflag = 0;
271*5c51f124SMoriah Waterland 			cflag = 1;
272*5c51f124SMoriah Waterland 			break;
273*5c51f124SMoriah Waterland 
274*5c51f124SMoriah Waterland 		case 'e':
275*5c51f124SMoriah Waterland 			envfile = optarg;
276*5c51f124SMoriah Waterland 			break;
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland 		case 'm':
279*5c51f124SMoriah Waterland 			mapfile = optarg;
280*5c51f124SMoriah Waterland 			break;
281*5c51f124SMoriah Waterland 
282*5c51f124SMoriah Waterland 		case 'R':
283*5c51f124SMoriah Waterland 			Rvalue = optarg;
284*5c51f124SMoriah Waterland 			Rflag = 1;
285*5c51f124SMoriah Waterland 			break;
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland 		case 'Y':
288*5c51f124SMoriah Waterland 			catg_arg = strdup(optarg);
289*5c51f124SMoriah Waterland 
290*5c51f124SMoriah Waterland 			if ((category = get_categories(catg_arg)) == NULL) {
291*5c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_INV), catg_arg);
292*5c51f124SMoriah Waterland 				quit(1);
293*5c51f124SMoriah Waterland 			} else if (is_not_valid_length(category)) {
294*5c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_LNGTH));
295*5c51f124SMoriah Waterland 				quit(1);
296*5c51f124SMoriah Waterland 			}
297*5c51f124SMoriah Waterland 			break;
298*5c51f124SMoriah Waterland 
299*5c51f124SMoriah Waterland 		case 'Q':
300*5c51f124SMoriah Waterland 			dbcreate++;
301*5c51f124SMoriah Waterland 			break;
302*5c51f124SMoriah Waterland 
303*5c51f124SMoriah Waterland 		case 'P':
304*5c51f124SMoriah Waterland 			ppathlist[npaths] = strtok(optarg, " , ");
305*5c51f124SMoriah Waterland 			if ((ppathlist[npaths] == NULL) ||
306*5c51f124SMoriah Waterland 			    (ppathlist[npaths][0] == '-')) {
307*5c51f124SMoriah Waterland 				progerr(gettext(ERR_PARTIAL_POPTION));
308*5c51f124SMoriah Waterland 				quit(1);
309*5c51f124SMoriah Waterland 			}
310*5c51f124SMoriah Waterland 			npaths++;
311*5c51f124SMoriah Waterland 			while (ppathlist[npaths] = strtok(NULL, " , ")) {
312*5c51f124SMoriah Waterland 				if (npaths++ >= MAXPATHS) {
313*5c51f124SMoriah Waterland 					progerr(gettext(ERR_MAXPATHS),
314*5c51f124SMoriah Waterland 						MAXPATHS);
315*5c51f124SMoriah Waterland 					quit(1);
316*5c51f124SMoriah Waterland 				}
317*5c51f124SMoriah Waterland 			}
318*5c51f124SMoriah Waterland 			break;
319*5c51f124SMoriah Waterland 
320*5c51f124SMoriah Waterland 		default:
321*5c51f124SMoriah Waterland 			usage();
322*5c51f124SMoriah Waterland 			/*NOTREACHED*/
323*5c51f124SMoriah Waterland 			/*
324*5c51f124SMoriah Waterland 			 * Although usage() calls a noreturn function,
325*5c51f124SMoriah Waterland 			 * needed to add return (1);  so that main() would
326*5c51f124SMoriah Waterland 			 * pass compilation checks. The statement below
327*5c51f124SMoriah Waterland 			 * should never be executed.
328*5c51f124SMoriah Waterland 			 */
329*5c51f124SMoriah Waterland 			return (1);
330*5c51f124SMoriah Waterland 		}
331*5c51f124SMoriah Waterland 	}
332*5c51f124SMoriah Waterland 
333*5c51f124SMoriah Waterland 	/* Check for incompatible options */
334*5c51f124SMoriah Waterland 	if (dflag && Rflag)
335*5c51f124SMoriah Waterland 		usage();
336*5c51f124SMoriah Waterland 
337*5c51f124SMoriah Waterland 	/* Check for root dir and device dir if set */
338*5c51f124SMoriah Waterland 	if (Rflag) {
339*5c51f124SMoriah Waterland 		if (!set_inst_root(Rvalue)) {
340*5c51f124SMoriah Waterland 			progerr(gettext(ERR_ROOT_CMD));
341*5c51f124SMoriah Waterland 			quit(1);
342*5c51f124SMoriah Waterland 		}
343*5c51f124SMoriah Waterland 	}
344*5c51f124SMoriah Waterland 
345*5c51f124SMoriah Waterland 	if (dflag)
346*5c51f124SMoriah Waterland 		device = flex_device(dvalue, 1);
347*5c51f124SMoriah Waterland 
348*5c51f124SMoriah Waterland 	if (lflag || Lflag) {
349*5c51f124SMoriah Waterland 		/* we're only supposed to list information */
350*5c51f124SMoriah Waterland 		if ((cflag >= 0) || (aflag >= 0) ||
351*5c51f124SMoriah Waterland 		qflag || xflag || fflag || nflag || vflag)
352*5c51f124SMoriah Waterland 			usage();
353*5c51f124SMoriah Waterland 	}
354*5c51f124SMoriah Waterland 
355*5c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
356*5c51f124SMoriah Waterland 
357*5c51f124SMoriah Waterland 	if (catg_arg != NULL && device == NULL) {
358*5c51f124SMoriah Waterland 		if (argc - optind) {
359*5c51f124SMoriah Waterland 			usage();
360*5c51f124SMoriah Waterland 		}
361*5c51f124SMoriah Waterland 		pkg = gpkglist(pkgdir, all_pkgs, category);
362*5c51f124SMoriah Waterland 		if (pkg == NULL) {
363*5c51f124SMoriah Waterland 			progerr(gettext(ERR_CAT_FND), catg_arg);
364*5c51f124SMoriah Waterland 			quit(1);
365*5c51f124SMoriah Waterland 		} else {
366*5c51f124SMoriah Waterland 			for (pkgcnt = 0; pkg[pkgcnt] != NULL; pkgcnt++);
367*5c51f124SMoriah Waterland 		}
368*5c51f124SMoriah Waterland 	} else if (catg_arg != NULL && optind < argc) {
369*5c51f124SMoriah Waterland 		usage();
370*5c51f124SMoriah Waterland 	} else {
371*5c51f124SMoriah Waterland 		pkg = &argv[optind];
372*5c51f124SMoriah Waterland 		pkgcnt = (argc - optind);
373*5c51f124SMoriah Waterland 	}
374*5c51f124SMoriah Waterland 
375*5c51f124SMoriah Waterland 	environ = NULL;		/* Sever the parent environment. */
376*5c51f124SMoriah Waterland 
377*5c51f124SMoriah Waterland 	if (vcfile() == 0) {
378*5c51f124SMoriah Waterland 		quit(99);
379*5c51f124SMoriah Waterland 	}
380*5c51f124SMoriah Waterland 
381*5c51f124SMoriah Waterland 	errflg = 0;
382*5c51f124SMoriah Waterland 	if (mapfile) {
383*5c51f124SMoriah Waterland 		/* check for incompatible options */
384*5c51f124SMoriah Waterland 		if (device || pkgcnt)
385*5c51f124SMoriah Waterland 			usage();
386*5c51f124SMoriah Waterland 		put_path_params();	/* Restore what's needed. */
387*5c51f124SMoriah Waterland 
388*5c51f124SMoriah Waterland 		/* send pathtype if partial path */
389*5c51f124SMoriah Waterland 		pathtype = (ppathlist[0] != NULL) ? 1 : 0;
390*5c51f124SMoriah Waterland 		if (checkmap(0, (device != NULL), mapfile, envfile, NULL,
391*5c51f124SMoriah Waterland 		    NULL, pathtype))
392*5c51f124SMoriah Waterland 			errflg++;
393*5c51f124SMoriah Waterland 	} else if (device) {
394*5c51f124SMoriah Waterland 		/* check for incompatible options */
395*5c51f124SMoriah Waterland 		if ((cflag >= 0) || (aflag >= 0))
396*5c51f124SMoriah Waterland 			usage();
397*5c51f124SMoriah Waterland 		if (qflag || xflag || nflag || envfile)
398*5c51f124SMoriah Waterland 			usage();
399*5c51f124SMoriah Waterland 		tmpdir = NULL;
400*5c51f124SMoriah Waterland 		if ((spooldir = devattr(device, "pathname")) == NULL)
401*5c51f124SMoriah Waterland 			spooldir = device;
402*5c51f124SMoriah Waterland 		if (isdir(spooldir)) {
403*5c51f124SMoriah Waterland 			tmpdir = spooldir = qstrdup(tmpnam(NULL));
404*5c51f124SMoriah Waterland 			if (fflag) {
405*5c51f124SMoriah Waterland 				logerr(gettext(WRN_F_SPOOL), *pkg);
406*5c51f124SMoriah Waterland 				fflag = 0;
407*5c51f124SMoriah Waterland 			}
408*5c51f124SMoriah Waterland 			if (mkdir(spooldir, 0755)) {
409*5c51f124SMoriah Waterland 				progerr(gettext(ERR_MKDIR), spooldir);
410*5c51f124SMoriah Waterland 				quit(99);
411*5c51f124SMoriah Waterland 			}
412*5c51f124SMoriah Waterland 			if (n = pkgtrans(device, spooldir, pkg, PT_SILENT,
413*5c51f124SMoriah Waterland 				NULL, NULL))
414*5c51f124SMoriah Waterland 				quit(n);
415*5c51f124SMoriah Waterland 			if (catg_arg != NULL)
416*5c51f124SMoriah Waterland 				pkg = gpkglist(spooldir, all_pkgs, category);
417*5c51f124SMoriah Waterland 			else
418*5c51f124SMoriah Waterland 				pkg = gpkglist(spooldir, all_pkgs, NULL);
419*5c51f124SMoriah Waterland 			pkgfmt = 0;
420*5c51f124SMoriah Waterland 		} else {
421*5c51f124SMoriah Waterland 			if (catg_arg != NULL)
422*5c51f124SMoriah Waterland 				pkg = gpkglist(spooldir,
423*5c51f124SMoriah Waterland 					pkgcnt ? pkg : all_pkgs, category);
424*5c51f124SMoriah Waterland 			else
425*5c51f124SMoriah Waterland 				pkg = gpkglist(spooldir,
426*5c51f124SMoriah Waterland 					pkgcnt ? pkg : all_pkgs, NULL);
427*5c51f124SMoriah Waterland 			pkgfmt = 1;
428*5c51f124SMoriah Waterland 		}
429*5c51f124SMoriah Waterland 
430*5c51f124SMoriah Waterland 		/*
431*5c51f124SMoriah Waterland 		 * At this point pkg[] is the list of packages to check. They
432*5c51f124SMoriah Waterland 		 * are in directory format in spooldir.
433*5c51f124SMoriah Waterland 		 */
434*5c51f124SMoriah Waterland 		if (pkg == NULL) {
435*5c51f124SMoriah Waterland 			if (catg_arg != NULL) {
436*5c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_FND), catg_arg);
437*5c51f124SMoriah Waterland 				quit(1);
438*5c51f124SMoriah Waterland 			} else {
439*5c51f124SMoriah Waterland 				progerr(gettext(ERR_SEL_PKG));
440*5c51f124SMoriah Waterland 				quit(1);
441*5c51f124SMoriah Waterland 			}
442*5c51f124SMoriah Waterland 		}
443*5c51f124SMoriah Waterland 
444*5c51f124SMoriah Waterland 		aflag = 0;
445*5c51f124SMoriah Waterland 
446*5c51f124SMoriah Waterland 		for (n = 0; pkg[n]; n++) {
447*5c51f124SMoriah Waterland 			char locenv[PATH_MAX];
448*5c51f124SMoriah Waterland 
449*5c51f124SMoriah Waterland 	/*
450*5c51f124SMoriah Waterland 	 * *********************************************************************
451*5c51f124SMoriah Waterland 	 * this feature is removed starting with Solaris 10 - there is no built
452*5c51f124SMoriah Waterland 	 * in list of packages that should be run "the old way"
453*5c51f124SMoriah Waterland 	 * *********************************************************************
454*5c51f124SMoriah Waterland 	 */
455*5c51f124SMoriah Waterland #ifdef	ALLOW_EXCEPTION_PKG_LIST
456*5c51f124SMoriah Waterland 			/* Until 2.9, set it from the execption list */
457*5c51f124SMoriah Waterland 			if (exception_pkg(pkg[n], LINK))
458*5c51f124SMoriah Waterland 				set_nonABI_symlinks();
459*5c51f124SMoriah Waterland #endif
460*5c51f124SMoriah Waterland 
461*5c51f124SMoriah Waterland 			if (pkgfmt)
462*5c51f124SMoriah Waterland 				(void) printf(
463*5c51f124SMoriah Waterland 					gettext(MSG_CHK_DIR), pkg[n], device);
464*5c51f124SMoriah Waterland 			else
465*5c51f124SMoriah Waterland 				(void) printf(
466*5c51f124SMoriah Waterland 					gettext(MSG_CHK_STRM), pkg[n], device);
467*5c51f124SMoriah Waterland 
468*5c51f124SMoriah Waterland 			(void) snprintf(pkgspool, sizeof (pkgspool),
469*5c51f124SMoriah Waterland 				"%s/%s", spooldir, pkg[n]);
470*5c51f124SMoriah Waterland 			(void) snprintf(file, sizeof (file),
471*5c51f124SMoriah Waterland 				"%s/install", pkgspool);
472*5c51f124SMoriah Waterland 			/* Here we check the install scripts. */
473*5c51f124SMoriah Waterland 			(void) printf(
474*5c51f124SMoriah Waterland 				gettext("## Checking control scripts.\n"));
475*5c51f124SMoriah Waterland 			(void) checkscripts(file, 0);
476*5c51f124SMoriah Waterland 			/* Verify consistency with the pkgmap. */
477*5c51f124SMoriah Waterland 			(void) printf(
478*5c51f124SMoriah Waterland 				gettext("## Checking package objects.\n"));
479*5c51f124SMoriah Waterland 			(void) snprintf(file, sizeof (file),
480*5c51f124SMoriah Waterland 				"%s/pkgmap", pkgspool);
481*5c51f124SMoriah Waterland 			(void) snprintf(locenv, sizeof (locenv),
482*5c51f124SMoriah Waterland 				"%s/pkginfo", pkgspool);
483*5c51f124SMoriah Waterland 			envfile = locenv;
484*5c51f124SMoriah Waterland 
485*5c51f124SMoriah Waterland 			/*
486*5c51f124SMoriah Waterland 			 * NOTE : checkmap() frees the environ data and
487*5c51f124SMoriah Waterland 			 * pointer when it's through with them.
488*5c51f124SMoriah Waterland 			 */
489*5c51f124SMoriah Waterland 			if (checkmap(0, (device != NULL), file, envfile,
490*5c51f124SMoriah Waterland 					pkg[n], NULL, 0))
491*5c51f124SMoriah Waterland 				errflg++;
492*5c51f124SMoriah Waterland 			(void) printf(
493*5c51f124SMoriah Waterland 				gettext("## Checking is complete.\n"));
494*5c51f124SMoriah Waterland 		}
495*5c51f124SMoriah Waterland 	} else {
496*5c51f124SMoriah Waterland 		if (envfile)
497*5c51f124SMoriah Waterland 			usage();
498*5c51f124SMoriah Waterland 
499*5c51f124SMoriah Waterland 		put_path_params();	/* Restore what's needed. */
500*5c51f124SMoriah Waterland 
501*5c51f124SMoriah Waterland 		/*
502*5c51f124SMoriah Waterland 		 * If this is a check of a client of some sort, we'll need to
503*5c51f124SMoriah Waterland 		 * mount up the client's filesystems. If the caller isn't
504*5c51f124SMoriah Waterland 		 * root, this may not be possible.
505*5c51f124SMoriah Waterland 		 */
506*5c51f124SMoriah Waterland 		if (is_an_inst_root()) {
507*5c51f124SMoriah Waterland 			if (getuid()) {
508*5c51f124SMoriah Waterland 				logerr(gettext(MSG_NOTROOT));
509*5c51f124SMoriah Waterland 				logerr(gettext(MSG_CONT));
510*5c51f124SMoriah Waterland 			} else {
511*5c51f124SMoriah Waterland 				if (get_mntinfo(map_client, vfstab_file))
512*5c51f124SMoriah Waterland 					map_client = 0;
513*5c51f124SMoriah Waterland 				if (map_client)
514*5c51f124SMoriah Waterland 					mount_client();
515*5c51f124SMoriah Waterland 			}
516*5c51f124SMoriah Waterland 		}
517*5c51f124SMoriah Waterland 
518*5c51f124SMoriah Waterland 		(void) snprintf(file, sizeof (file),
519*5c51f124SMoriah Waterland 			"%s/contents", get_PKGADM());
520*5c51f124SMoriah Waterland 		if (ppathlist[0] != NULL) {
521*5c51f124SMoriah Waterland 			for (n = 0; ppathlist[n]; n++) {
522*5c51f124SMoriah Waterland 				if (checkmap(1, (device != NULL), file, NULL,
523*5c51f124SMoriah Waterland 						NULL, ppathlist[n], 1))
524*5c51f124SMoriah Waterland 					errflg++;
525*5c51f124SMoriah Waterland 			}
526*5c51f124SMoriah Waterland 		} else if (pkg[0] != NULL) {
527*5c51f124SMoriah Waterland 				if (checkmap(1, (device != NULL), file, NULL,
528*5c51f124SMoriah Waterland 					pkg[0], NULL, 0)) {
529*5c51f124SMoriah Waterland 					errflg++;
530*5c51f124SMoriah Waterland 				}
531*5c51f124SMoriah Waterland 		} else {
532*5c51f124SMoriah Waterland 			if (checkmap(1, (device != NULL), file, NULL,
533*5c51f124SMoriah Waterland 					NULL, NULL, 0)) {
534*5c51f124SMoriah Waterland 				errflg++;
535*5c51f124SMoriah Waterland 			}
536*5c51f124SMoriah Waterland 		}
537*5c51f124SMoriah Waterland 
538*5c51f124SMoriah Waterland 		if (map_client) {
539*5c51f124SMoriah Waterland 			unmount_client();
540*5c51f124SMoriah Waterland 		}
541*5c51f124SMoriah Waterland 	}
542*5c51f124SMoriah Waterland 	quit(errflg ? 1 : 0);
543*5c51f124SMoriah Waterland 	/* LINTED: no return */
544*5c51f124SMoriah Waterland }
545*5c51f124SMoriah Waterland 
546*5c51f124SMoriah Waterland static void
547*5c51f124SMoriah Waterland setpathlist(char *file)
548*5c51f124SMoriah Waterland {
549*5c51f124SMoriah Waterland 	int fd;
550*5c51f124SMoriah Waterland 	struct stat st;
551*5c51f124SMoriah Waterland 	FILE *fplist;
552*5c51f124SMoriah Waterland 	char pathname[PATH_MAX];
553*5c51f124SMoriah Waterland 	/*
554*5c51f124SMoriah Waterland 	 * This trap laid to catch a mismatch between the declaration above and
555*5c51f124SMoriah Waterland 	 * the hard-coded constant in the fscanf below
556*5c51f124SMoriah Waterland 	 */
557*5c51f124SMoriah Waterland #if PATH_MAX != 1024
558*5c51f124SMoriah Waterland #error "PATH_MAX changed, so we have a bug to fix"
559*5c51f124SMoriah Waterland #endif
560*5c51f124SMoriah Waterland 
561*5c51f124SMoriah Waterland 	if (strcmp(file, "-") == 0) {
562*5c51f124SMoriah Waterland 		fplist = stdin;
563*5c51f124SMoriah Waterland 	} else {
564*5c51f124SMoriah Waterland 		if ((fd = open(file, O_RDONLY)) == -1) {
565*5c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
566*5c51f124SMoriah Waterland 			quit(1);
567*5c51f124SMoriah Waterland 		}
568*5c51f124SMoriah Waterland 		if (fstat(fd, &st) == -1) {
569*5c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
570*5c51f124SMoriah Waterland 			quit(1);
571*5c51f124SMoriah Waterland 		}
572*5c51f124SMoriah Waterland 		if (S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
573*5c51f124SMoriah Waterland 			progerr(gettext(ERR_PATHS_INVALID), file);
574*5c51f124SMoriah Waterland 			quit(1);
575*5c51f124SMoriah Waterland 		}
576*5c51f124SMoriah Waterland 		if ((fplist = fdopen(fd, "r")) == NULL) {
577*5c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
578*5c51f124SMoriah Waterland 			quit(1);
579*5c51f124SMoriah Waterland 		}
580*5c51f124SMoriah Waterland 	}
581*5c51f124SMoriah Waterland 	while (fscanf(fplist, "%1024s", pathname) == 1) {
582*5c51f124SMoriah Waterland 		if (*pathname == '\0') {
583*5c51f124SMoriah Waterland 			progerr(gettext(ERR_PATHS_INVALID), file);
584*5c51f124SMoriah Waterland 			quit(1);
585*5c51f124SMoriah Waterland 		}
586*5c51f124SMoriah Waterland 		pathlist[npaths] = qstrdup(pathname);
587*5c51f124SMoriah Waterland 		if (npaths++ > MAXPATHS) {
588*5c51f124SMoriah Waterland 			progerr(gettext(ERR_TOO_MANY), MAXPATHS);
589*5c51f124SMoriah Waterland 			quit(1);
590*5c51f124SMoriah Waterland 		}
591*5c51f124SMoriah Waterland 	}
592*5c51f124SMoriah Waterland 	if (npaths == 0) {
593*5c51f124SMoriah Waterland 		progerr(gettext(ERR_IEMPTY));
594*5c51f124SMoriah Waterland 		quit(1);
595*5c51f124SMoriah Waterland 	}
596*5c51f124SMoriah Waterland 	(void) fclose(fplist);
597*5c51f124SMoriah Waterland }
598*5c51f124SMoriah Waterland 
599*5c51f124SMoriah Waterland void
600*5c51f124SMoriah Waterland quit(int n)
601*5c51f124SMoriah Waterland {
602*5c51f124SMoriah Waterland 	/* cleanup any temporary directories */
603*5c51f124SMoriah Waterland 	(void) chdir("/");
604*5c51f124SMoriah Waterland 	if (tmpdir != NULL) {
605*5c51f124SMoriah Waterland 		(void) rrmdir(tmpdir);
606*5c51f124SMoriah Waterland 		free(tmpdir);
607*5c51f124SMoriah Waterland 		tmpdir = NULL;
608*5c51f124SMoriah Waterland 	}
609*5c51f124SMoriah Waterland 	(void) pkghead(NULL);
610*5c51f124SMoriah Waterland 	exit(n);
611*5c51f124SMoriah Waterland 	/*NOTREACHED*/
612*5c51f124SMoriah Waterland }
613*5c51f124SMoriah Waterland 
614*5c51f124SMoriah Waterland static void
615*5c51f124SMoriah Waterland usage(void)
616*5c51f124SMoriah Waterland {
617*5c51f124SMoriah Waterland 	char *prog = get_prog_name();
618*5c51f124SMoriah Waterland 
619*5c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(ERR_USAGE), prog, prog);
620*5c51f124SMoriah Waterland 	quit(1);
621*5c51f124SMoriah Waterland 	/*NOTREACHED*/
622*5c51f124SMoriah Waterland }
623