xref: /illumos-gate/usr/src/cmd/svr4pkg/pkgchk/main.c (revision dea58231)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
2232991bedSPeter Tribble /*
2332991bedSPeter Tribble  * Copyright (c) 2017 Peter Tribble.
2432991bedSPeter Tribble  */
2532991bedSPeter Tribble 
265c51f124SMoriah Waterland /*
275c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
285c51f124SMoriah Waterland  * Use is subject to license terms.
295c51f124SMoriah Waterland  */
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
325c51f124SMoriah Waterland /* All Rights Reserved */
335c51f124SMoriah Waterland 
345c51f124SMoriah Waterland 
355c51f124SMoriah Waterland #include <stdio.h>
365c51f124SMoriah Waterland #include <limits.h>
375c51f124SMoriah Waterland #include <unistd.h>
385c51f124SMoriah Waterland #include <stdlib.h>
395c51f124SMoriah Waterland #include <string.h>
405c51f124SMoriah Waterland #include <ctype.h>
415c51f124SMoriah Waterland #include <dirent.h>
425c51f124SMoriah Waterland #include <sys/stat.h>
435c51f124SMoriah Waterland #include <pkginfo.h>
445c51f124SMoriah Waterland #include <pkglocs.h>
455c51f124SMoriah Waterland #include <sys/types.h>
465c51f124SMoriah Waterland #include <pkgstrct.h>
475c51f124SMoriah Waterland #include <pkgtrans.h>
485c51f124SMoriah Waterland #include <locale.h>
495c51f124SMoriah Waterland #include <libintl.h>
505c51f124SMoriah Waterland #include <pkglib.h>
515c51f124SMoriah Waterland #include <libadm.h>
525c51f124SMoriah Waterland #include <libinst.h>
535c51f124SMoriah Waterland 
545c51f124SMoriah Waterland #define	MAXPATHS	1024
555c51f124SMoriah Waterland 
565c51f124SMoriah Waterland #define	MSG_CHK_STRM	"Checking uninstalled stream format package " \
575c51f124SMoriah Waterland 				"<%s> from <%s>\n"
585c51f124SMoriah Waterland #define	MSG_CHK_DIR	"Checking uninstalled directory format package " \
595c51f124SMoriah Waterland 				"<%s> from <%s>\n"
605c51f124SMoriah Waterland #define	MSG_NOTROOT	"NOTE: \"root\" permission may be required to " \
615c51f124SMoriah Waterland 				"validate all objects in the client filesystem."
625c51f124SMoriah Waterland #define	MSG_CONT	"Continuing."
635c51f124SMoriah Waterland 
645c51f124SMoriah Waterland #define	WRN_F_SPOOL	"WARNING: %s is spooled. Ignoring \"f\" argument"
655c51f124SMoriah Waterland 
665c51f124SMoriah Waterland #define	ERR_ROOT_SET	"Could not set install root from the environment."
675c51f124SMoriah Waterland #define	ERR_ROOT_CMD	"Command line install root contends with environment."
685c51f124SMoriah Waterland #define	ERR_IOPEN	"unable to open input file <%s>"
695c51f124SMoriah Waterland #define	ERR_IEMPTY	"no pathnames in file specified by -i option"
705c51f124SMoriah Waterland #define	ERR_POPTION	"no pathname included with -p option"
715c51f124SMoriah Waterland #define	ERR_PARTIAL_POPTION	"no pathname included with -P option"
725c51f124SMoriah Waterland #define	ERR_MAXPATHS	"too many pathnames in option list (limit is %d)"
735c51f124SMoriah Waterland #define	ERR_NOTROOT	"You must be \"root\" for \"%s -f\" to" \
745c51f124SMoriah Waterland 					"execute properly."
755c51f124SMoriah Waterland #define	ERR_SEL_PKG "No packages selected for verification."
765c51f124SMoriah Waterland #define	ERR_CAT_LNGTH "The category argument exceeds the SVr4 ABI\n" \
775c51f124SMoriah Waterland 		"        defined maximum supported length of 16 characters."
785c51f124SMoriah Waterland #define	ERR_CAT_FND "Category argument <%s> cannot be found."
795c51f124SMoriah Waterland #define	ERR_CAT_INV "Category argument <%s> is invalid."
805c51f124SMoriah Waterland #define	ERR_TOO_MANY "too many pathnames in list, limit is %d"
815c51f124SMoriah Waterland #define	ERR_PATHS_INVALID "Pathnames in %s are not valid."
825c51f124SMoriah Waterland #define	ERR_MKDIR "unable to make directory <%s>"
835c51f124SMoriah Waterland #define	ERR_USAGE	"usage:\n" \
845c51f124SMoriah Waterland 		"\t%s [-l|vqacnxf] [-R rootdir] [-p path[, ...] | " \
855c51f124SMoriah Waterland 		"-P path[, ...]]\n" \
865c51f124SMoriah Waterland 		"\t\t[-i file] [options]\n" \
875c51f124SMoriah Waterland 		"\t%s -d device [-f][-l|v] [-p path[, ...] | " \
885c51f124SMoriah Waterland 		"-P path[, ...]]\n" \
895c51f124SMoriah Waterland 		"\t\t[-V ...] [-M] [-i file] [-Y category[, ...] | " \
905c51f124SMoriah Waterland 		"pkginst [...]]\n" \
915c51f124SMoriah Waterland 		"\twhere options may include ONE of the " \
925c51f124SMoriah Waterland 		"following:\n " \
935c51f124SMoriah Waterland 		"\t\t-m pkgmap [-e envfile]\n" \
945c51f124SMoriah Waterland 		"\t\tpkginst [...]\n" \
955c51f124SMoriah Waterland 		"\t\t-Y category[, ...]\n"
965c51f124SMoriah Waterland 
975c51f124SMoriah Waterland #define	LINK	1
985c51f124SMoriah Waterland 
995c51f124SMoriah Waterland char	**pkg = NULL;
1005c51f124SMoriah Waterland int	pkgcnt = 0;
1015c51f124SMoriah Waterland char	*basedir;
1025c51f124SMoriah Waterland char	*pathlist[MAXPATHS], *ppathlist[MAXPATHS], pkgspool[PATH_MAX];
1035c51f124SMoriah Waterland short	used[MAXPATHS];
1045c51f124SMoriah Waterland short	npaths;
1055c51f124SMoriah Waterland struct cfent **eptlist;
1065c51f124SMoriah Waterland 
1075c51f124SMoriah Waterland int	aflag = (-1);
1085c51f124SMoriah Waterland int	cflag = (-1);
1095c51f124SMoriah Waterland int	vflag = 0;
1105c51f124SMoriah Waterland int	nflag = 0;
1115c51f124SMoriah Waterland int	lflag = 0;
1125c51f124SMoriah Waterland int	Lflag = 0;
1135c51f124SMoriah Waterland int	fflag = 0;
1145c51f124SMoriah Waterland int	xflag = 0;
1155c51f124SMoriah Waterland int	qflag = 0;
1165c51f124SMoriah Waterland int	Rflag = 0;
1175c51f124SMoriah Waterland int	dflag = 0;
1185c51f124SMoriah Waterland char 	*device;
1195c51f124SMoriah Waterland 
1205c51f124SMoriah Waterland char	*uniTmp;
1215c51f124SMoriah Waterland 
1225c51f124SMoriah Waterland static char	*mapfile,
1235c51f124SMoriah Waterland 		*spooldir,
1245c51f124SMoriah Waterland 		*tmpdir,
1255c51f124SMoriah Waterland 		*envfile;
1265c51f124SMoriah Waterland static int	errflg = 0;
1275c51f124SMoriah Waterland static int	map_client = 1;
1285c51f124SMoriah Waterland 
1295c51f124SMoriah Waterland void	quit(int);
1305c51f124SMoriah Waterland static void	setpathlist(char *);
1315c51f124SMoriah Waterland static void	usage(void);
1325c51f124SMoriah Waterland 
1335c51f124SMoriah Waterland extern	char	**environ;
1345c51f124SMoriah Waterland extern	char	*pkgdir;
1355c51f124SMoriah Waterland 
1365c51f124SMoriah Waterland /* checkmap.c */
1375c51f124SMoriah Waterland extern int	checkmap(int, int, char *, char *, char *, char *, int);
1385c51f124SMoriah Waterland /* scriptvfy.c */
1395c51f124SMoriah Waterland extern int	checkscripts(char *inst_dir, int silent);
1405c51f124SMoriah Waterland 
1415c51f124SMoriah Waterland int
1425c51f124SMoriah Waterland main(int argc, char *argv[])
1435c51f124SMoriah Waterland {
1445c51f124SMoriah Waterland 	int	pkgfmt = 0;	/* Makes more sense as a pointer, but */
1455c51f124SMoriah Waterland 				/*	18N is compromised. */
1465c51f124SMoriah Waterland 	char	file[PATH_MAX+1],
147*dea58231SPeter Tribble 	    *abi_sym_ptr,
148*dea58231SPeter Tribble 	    *vfstab_file = NULL;
1495c51f124SMoriah Waterland 	char *all_pkgs[4] = {"all", NULL};
1505c51f124SMoriah Waterland 	char **category = NULL;
1515c51f124SMoriah Waterland 	char *catg_arg = NULL;
1525c51f124SMoriah Waterland 	int	c;
1535c51f124SMoriah Waterland 	int	n = 0;
1545c51f124SMoriah Waterland 	char	*prog,
155*dea58231SPeter Tribble 	    *Rvalue,
156*dea58231SPeter Tribble 	    *dvalue;
1575c51f124SMoriah Waterland 	int pathtype;
1585c51f124SMoriah Waterland 
1595c51f124SMoriah Waterland 	/* initialize locale mechanism */
1605c51f124SMoriah Waterland 
1615c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
1625c51f124SMoriah Waterland 
1635c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1645c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
1655c51f124SMoriah Waterland #endif
1665c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
1675c51f124SMoriah Waterland 
1685c51f124SMoriah Waterland 	/* determine program name */
1695c51f124SMoriah Waterland 
1705c51f124SMoriah Waterland 	prog = set_prog_name(argv[0]);
1715c51f124SMoriah Waterland 
1725c51f124SMoriah Waterland 	/* establish installation root directory */
1735c51f124SMoriah Waterland 
1745c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
1755c51f124SMoriah Waterland 		progerr(gettext(ERR_ROOT_SET));
1765c51f124SMoriah Waterland 		quit(1);
1775c51f124SMoriah Waterland 	}
1785c51f124SMoriah Waterland 
1795c51f124SMoriah Waterland 	/* check if not ABI compliant mode */
1805c51f124SMoriah Waterland 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
1815c51f124SMoriah Waterland 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
1825c51f124SMoriah Waterland 		set_nonABI_symlinks();
1835c51f124SMoriah Waterland 	}
1845c51f124SMoriah Waterland 
1855c51f124SMoriah Waterland 	/* bugId 4012147 */
1865c51f124SMoriah Waterland 	if ((uniTmp = getenv("PKG_NO_UNIFIED")) != NULL)
1875c51f124SMoriah Waterland 		map_client = 0;
1885c51f124SMoriah Waterland 
189*dea58231SPeter Tribble 	while ((c = getopt(argc, argv, "Y:R:e:p:d:nLli:vaV:Mm:cqxfP:?"))
190*dea58231SPeter Tribble 	    != EOF) {
1915c51f124SMoriah Waterland 		switch (c) {
1925c51f124SMoriah Waterland 		case 'p':
1935c51f124SMoriah Waterland 			pathlist[npaths] = strtok(optarg, " , ");
1945c51f124SMoriah Waterland 			if (pathlist[npaths++] == NULL) {
1955c51f124SMoriah Waterland 				progerr(gettext(ERR_POPTION));
1965c51f124SMoriah Waterland 				quit(1);
1975c51f124SMoriah Waterland 			}
1985c51f124SMoriah Waterland 			while (pathlist[npaths] = strtok(NULL, " , ")) {
1995c51f124SMoriah Waterland 				if (npaths++ >= MAXPATHS) {
2005c51f124SMoriah Waterland 					progerr(gettext(ERR_MAXPATHS),
201*dea58231SPeter Tribble 					    MAXPATHS);
2025c51f124SMoriah Waterland 					quit(1);
2035c51f124SMoriah Waterland 				}
2045c51f124SMoriah Waterland 			}
2055c51f124SMoriah Waterland 			break;
2065c51f124SMoriah Waterland 
2075c51f124SMoriah Waterland 		case 'd':
2085c51f124SMoriah Waterland 			dvalue = optarg;
2095c51f124SMoriah Waterland 			dflag = 1;
2105c51f124SMoriah Waterland 			break;
2115c51f124SMoriah Waterland 
2125c51f124SMoriah Waterland 		case 'n':
2135c51f124SMoriah Waterland 			nflag++;
2145c51f124SMoriah Waterland 			break;
2155c51f124SMoriah Waterland 
2165c51f124SMoriah Waterland 		case 'M':
2175c51f124SMoriah Waterland 			map_client = 0;
2185c51f124SMoriah Waterland 			break;
2195c51f124SMoriah Waterland 
2205c51f124SMoriah Waterland 		/*
2215c51f124SMoriah Waterland 		 * Allow admin to establish the client filesystem using a
2225c51f124SMoriah Waterland 		 * vfstab-like file of stable format.
2235c51f124SMoriah Waterland 		 */
2245c51f124SMoriah Waterland 		case 'V':
2255c51f124SMoriah Waterland 			vfstab_file = flex_device(optarg, 2);
2265c51f124SMoriah Waterland 			map_client = 1;
2275c51f124SMoriah Waterland 			break;
2285c51f124SMoriah Waterland 
2295c51f124SMoriah Waterland 		case 'f':
2305c51f124SMoriah Waterland 			if (getuid()) {
2315c51f124SMoriah Waterland 				progerr(gettext(ERR_NOTROOT), prog);
2325c51f124SMoriah Waterland 				quit(1);
2335c51f124SMoriah Waterland 			}
2345c51f124SMoriah Waterland 			fflag++;
2355c51f124SMoriah Waterland 			break;
2365c51f124SMoriah Waterland 
2375c51f124SMoriah Waterland 		case 'i':
2385c51f124SMoriah Waterland 			setpathlist(optarg);
2395c51f124SMoriah Waterland 			break;
2405c51f124SMoriah Waterland 
2415c51f124SMoriah Waterland 		case 'v':
2425c51f124SMoriah Waterland 			vflag++;
2435c51f124SMoriah Waterland 			break;
2445c51f124SMoriah Waterland 
2455c51f124SMoriah Waterland 		case 'l':
2465c51f124SMoriah Waterland 			lflag++;
2475c51f124SMoriah Waterland 			break;
2485c51f124SMoriah Waterland 
2495c51f124SMoriah Waterland 		case 'L':
2505c51f124SMoriah Waterland 			Lflag++;
2515c51f124SMoriah Waterland 			break;
2525c51f124SMoriah Waterland 
2535c51f124SMoriah Waterland 		case 'x':
2545c51f124SMoriah Waterland 			if (aflag < 0)
2555c51f124SMoriah Waterland 				aflag = 0;
2565c51f124SMoriah Waterland 			if (cflag < 0)
2575c51f124SMoriah Waterland 				cflag = 0;
2585c51f124SMoriah Waterland 			xflag++;
2595c51f124SMoriah Waterland 			break;
2605c51f124SMoriah Waterland 
2615c51f124SMoriah Waterland 		case 'q':
2625c51f124SMoriah Waterland 			qflag++;
2635c51f124SMoriah Waterland 			break;
2645c51f124SMoriah Waterland 
2655c51f124SMoriah Waterland 		case 'a':
2665c51f124SMoriah Waterland 			if (cflag < 0)
2675c51f124SMoriah Waterland 				cflag = 0;
2685c51f124SMoriah Waterland 			aflag = 1;
2695c51f124SMoriah Waterland 			break;
2705c51f124SMoriah Waterland 
2715c51f124SMoriah Waterland 		case 'c':
2725c51f124SMoriah Waterland 			if (aflag < 0)
2735c51f124SMoriah Waterland 				aflag = 0;
2745c51f124SMoriah Waterland 			cflag = 1;
2755c51f124SMoriah Waterland 			break;
2765c51f124SMoriah Waterland 
2775c51f124SMoriah Waterland 		case 'e':
2785c51f124SMoriah Waterland 			envfile = optarg;
2795c51f124SMoriah Waterland 			break;
2805c51f124SMoriah Waterland 
2815c51f124SMoriah Waterland 		case 'm':
2825c51f124SMoriah Waterland 			mapfile = optarg;
2835c51f124SMoriah Waterland 			break;
2845c51f124SMoriah Waterland 
2855c51f124SMoriah Waterland 		case 'R':
2865c51f124SMoriah Waterland 			Rvalue = optarg;
2875c51f124SMoriah Waterland 			Rflag = 1;
2885c51f124SMoriah Waterland 			break;
2895c51f124SMoriah Waterland 
2905c51f124SMoriah Waterland 		case 'Y':
2915c51f124SMoriah Waterland 			catg_arg = strdup(optarg);
2925c51f124SMoriah Waterland 
2935c51f124SMoriah Waterland 			if ((category = get_categories(catg_arg)) == NULL) {
2945c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_INV), catg_arg);
2955c51f124SMoriah Waterland 				quit(1);
2965c51f124SMoriah Waterland 			} else if (is_not_valid_length(category)) {
2975c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_LNGTH));
2985c51f124SMoriah Waterland 				quit(1);
2995c51f124SMoriah Waterland 			}
3005c51f124SMoriah Waterland 			break;
3015c51f124SMoriah Waterland 
3025c51f124SMoriah Waterland 		case 'P':
3035c51f124SMoriah Waterland 			ppathlist[npaths] = strtok(optarg, " , ");
3045c51f124SMoriah Waterland 			if ((ppathlist[npaths] == NULL) ||
3055c51f124SMoriah Waterland 			    (ppathlist[npaths][0] == '-')) {
3065c51f124SMoriah Waterland 				progerr(gettext(ERR_PARTIAL_POPTION));
3075c51f124SMoriah Waterland 				quit(1);
3085c51f124SMoriah Waterland 			}
3095c51f124SMoriah Waterland 			npaths++;
3105c51f124SMoriah Waterland 			while (ppathlist[npaths] = strtok(NULL, " , ")) {
3115c51f124SMoriah Waterland 				if (npaths++ >= MAXPATHS) {
3125c51f124SMoriah Waterland 					progerr(gettext(ERR_MAXPATHS),
313*dea58231SPeter Tribble 					    MAXPATHS);
3145c51f124SMoriah Waterland 					quit(1);
3155c51f124SMoriah Waterland 				}
3165c51f124SMoriah Waterland 			}
3175c51f124SMoriah Waterland 			break;
3185c51f124SMoriah Waterland 
3195c51f124SMoriah Waterland 		default:
3205c51f124SMoriah Waterland 			usage();
3215c51f124SMoriah Waterland 			/*NOTREACHED*/
3225c51f124SMoriah Waterland 			/*
3235c51f124SMoriah Waterland 			 * Although usage() calls a noreturn function,
3245c51f124SMoriah Waterland 			 * needed to add return (1);  so that main() would
3255c51f124SMoriah Waterland 			 * pass compilation checks. The statement below
3265c51f124SMoriah Waterland 			 * should never be executed.
3275c51f124SMoriah Waterland 			 */
3285c51f124SMoriah Waterland 			return (1);
3295c51f124SMoriah Waterland 		}
3305c51f124SMoriah Waterland 	}
3315c51f124SMoriah Waterland 
3325c51f124SMoriah Waterland 	/* Check for incompatible options */
3335c51f124SMoriah Waterland 	if (dflag && Rflag)
3345c51f124SMoriah Waterland 		usage();
3355c51f124SMoriah Waterland 
3365c51f124SMoriah Waterland 	/* Check for root dir and device dir if set */
3375c51f124SMoriah Waterland 	if (Rflag) {
3385c51f124SMoriah Waterland 		if (!set_inst_root(Rvalue)) {
3395c51f124SMoriah Waterland 			progerr(gettext(ERR_ROOT_CMD));
3405c51f124SMoriah Waterland 			quit(1);
3415c51f124SMoriah Waterland 		}
3425c51f124SMoriah Waterland 	}
3435c51f124SMoriah Waterland 
3445c51f124SMoriah Waterland 	if (dflag)
3455c51f124SMoriah Waterland 		device = flex_device(dvalue, 1);
3465c51f124SMoriah Waterland 
3475c51f124SMoriah Waterland 	if (lflag || Lflag) {
3485c51f124SMoriah Waterland 		/* we're only supposed to list information */
3495c51f124SMoriah Waterland 		if ((cflag >= 0) || (aflag >= 0) ||
350*dea58231SPeter Tribble 		    qflag || xflag || fflag || nflag || vflag)
3515c51f124SMoriah Waterland 			usage();
3525c51f124SMoriah Waterland 	}
3535c51f124SMoriah Waterland 
3545c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
3555c51f124SMoriah Waterland 
3565c51f124SMoriah Waterland 	if (catg_arg != NULL && device == NULL) {
3575c51f124SMoriah Waterland 		if (argc - optind) {
3585c51f124SMoriah Waterland 			usage();
3595c51f124SMoriah Waterland 		}
3605c51f124SMoriah Waterland 		pkg = gpkglist(pkgdir, all_pkgs, category);
3615c51f124SMoriah Waterland 		if (pkg == NULL) {
3625c51f124SMoriah Waterland 			progerr(gettext(ERR_CAT_FND), catg_arg);
3635c51f124SMoriah Waterland 			quit(1);
3645c51f124SMoriah Waterland 		} else {
365*dea58231SPeter Tribble 			for (pkgcnt = 0; pkg[pkgcnt] != NULL; pkgcnt++)
366*dea58231SPeter Tribble 				;
3675c51f124SMoriah Waterland 		}
3685c51f124SMoriah Waterland 	} else if (catg_arg != NULL && optind < argc) {
3695c51f124SMoriah Waterland 		usage();
3705c51f124SMoriah Waterland 	} else {
3715c51f124SMoriah Waterland 		pkg = &argv[optind];
3725c51f124SMoriah Waterland 		pkgcnt = (argc - optind);
3735c51f124SMoriah Waterland 	}
3745c51f124SMoriah Waterland 
37562224350SCasper H.S. Dik 	/* read the environment for the pkgserver */
37662224350SCasper H.S. Dik 	pkgserversetmode(DEFAULTMODE);
37762224350SCasper H.S. Dik 
3785c51f124SMoriah Waterland 	environ = NULL;		/* Sever the parent environment. */
3795c51f124SMoriah Waterland 
3805c51f124SMoriah Waterland 	if (vcfile() == 0) {
3815c51f124SMoriah Waterland 		quit(99);
3825c51f124SMoriah Waterland 	}
3835c51f124SMoriah Waterland 
3845c51f124SMoriah Waterland 	errflg = 0;
3855c51f124SMoriah Waterland 	if (mapfile) {
3865c51f124SMoriah Waterland 		/* check for incompatible options */
3875c51f124SMoriah Waterland 		if (device || pkgcnt)
3885c51f124SMoriah Waterland 			usage();
3895c51f124SMoriah Waterland 		put_path_params();	/* Restore what's needed. */
3905c51f124SMoriah Waterland 
3915c51f124SMoriah Waterland 		/* send pathtype if partial path */
3925c51f124SMoriah Waterland 		pathtype = (ppathlist[0] != NULL) ? 1 : 0;
3935c51f124SMoriah Waterland 		if (checkmap(0, (device != NULL), mapfile, envfile, NULL,
3945c51f124SMoriah Waterland 		    NULL, pathtype))
3955c51f124SMoriah Waterland 			errflg++;
3965c51f124SMoriah Waterland 	} else if (device) {
3975c51f124SMoriah Waterland 		/* check for incompatible options */
3985c51f124SMoriah Waterland 		if ((cflag >= 0) || (aflag >= 0))
3995c51f124SMoriah Waterland 			usage();
4005c51f124SMoriah Waterland 		if (qflag || xflag || nflag || envfile)
4015c51f124SMoriah Waterland 			usage();
4025c51f124SMoriah Waterland 		tmpdir = NULL;
4035c51f124SMoriah Waterland 		if ((spooldir = devattr(device, "pathname")) == NULL)
4045c51f124SMoriah Waterland 			spooldir = device;
4055c51f124SMoriah Waterland 		if (isdir(spooldir)) {
4065c51f124SMoriah Waterland 			tmpdir = spooldir = qstrdup(tmpnam(NULL));
4075c51f124SMoriah Waterland 			if (fflag) {
4085c51f124SMoriah Waterland 				logerr(gettext(WRN_F_SPOOL), *pkg);
4095c51f124SMoriah Waterland 				fflag = 0;
4105c51f124SMoriah Waterland 			}
4115c51f124SMoriah Waterland 			if (mkdir(spooldir, 0755)) {
4125c51f124SMoriah Waterland 				progerr(gettext(ERR_MKDIR), spooldir);
4135c51f124SMoriah Waterland 				quit(99);
4145c51f124SMoriah Waterland 			}
41532991bedSPeter Tribble 			if (n = pkgtrans(device, spooldir, pkg, PT_SILENT))
4165c51f124SMoriah Waterland 				quit(n);
4175c51f124SMoriah Waterland 			if (catg_arg != NULL)
4185c51f124SMoriah Waterland 				pkg = gpkglist(spooldir, all_pkgs, category);
4195c51f124SMoriah Waterland 			else
4205c51f124SMoriah Waterland 				pkg = gpkglist(spooldir, all_pkgs, NULL);
4215c51f124SMoriah Waterland 			pkgfmt = 0;
4225c51f124SMoriah Waterland 		} else {
4235c51f124SMoriah Waterland 			if (catg_arg != NULL)
4245c51f124SMoriah Waterland 				pkg = gpkglist(spooldir,
425*dea58231SPeter Tribble 				    pkgcnt ? pkg : all_pkgs, category);
4265c51f124SMoriah Waterland 			else
4275c51f124SMoriah Waterland 				pkg = gpkglist(spooldir,
428*dea58231SPeter Tribble 				    pkgcnt ? pkg : all_pkgs, NULL);
4295c51f124SMoriah Waterland 			pkgfmt = 1;
4305c51f124SMoriah Waterland 		}
4315c51f124SMoriah Waterland 
4325c51f124SMoriah Waterland 		/*
4335c51f124SMoriah Waterland 		 * At this point pkg[] is the list of packages to check. They
4345c51f124SMoriah Waterland 		 * are in directory format in spooldir.
4355c51f124SMoriah Waterland 		 */
4365c51f124SMoriah Waterland 		if (pkg == NULL) {
4375c51f124SMoriah Waterland 			if (catg_arg != NULL) {
4385c51f124SMoriah Waterland 				progerr(gettext(ERR_CAT_FND), catg_arg);
4395c51f124SMoriah Waterland 				quit(1);
4405c51f124SMoriah Waterland 			} else {
4415c51f124SMoriah Waterland 				progerr(gettext(ERR_SEL_PKG));
4425c51f124SMoriah Waterland 				quit(1);
4435c51f124SMoriah Waterland 			}
4445c51f124SMoriah Waterland 		}
4455c51f124SMoriah Waterland 
4465c51f124SMoriah Waterland 		aflag = 0;
4475c51f124SMoriah Waterland 
4485c51f124SMoriah Waterland 		for (n = 0; pkg[n]; n++) {
4495c51f124SMoriah Waterland 			char locenv[PATH_MAX];
4505c51f124SMoriah Waterland 
4515c51f124SMoriah Waterland 			if (pkgfmt)
4525c51f124SMoriah Waterland 				(void) printf(
453*dea58231SPeter Tribble 				    gettext(MSG_CHK_DIR), pkg[n], device);
4545c51f124SMoriah Waterland 			else
4555c51f124SMoriah Waterland 				(void) printf(
456*dea58231SPeter Tribble 				    gettext(MSG_CHK_STRM), pkg[n], device);
4575c51f124SMoriah Waterland 
4585c51f124SMoriah Waterland 			(void) snprintf(pkgspool, sizeof (pkgspool),
459*dea58231SPeter Tribble 			    "%s/%s", spooldir, pkg[n]);
4605c51f124SMoriah Waterland 			(void) snprintf(file, sizeof (file),
461*dea58231SPeter Tribble 			    "%s/install", pkgspool);
4625c51f124SMoriah Waterland 			/* Here we check the install scripts. */
4635c51f124SMoriah Waterland 			(void) printf(
464*dea58231SPeter Tribble 			    gettext("## Checking control scripts.\n"));
4655c51f124SMoriah Waterland 			(void) checkscripts(file, 0);
4665c51f124SMoriah Waterland 			/* Verify consistency with the pkgmap. */
4675c51f124SMoriah Waterland 			(void) printf(
468*dea58231SPeter Tribble 			    gettext("## Checking package objects.\n"));
4695c51f124SMoriah Waterland 			(void) snprintf(file, sizeof (file),
470*dea58231SPeter Tribble 			    "%s/pkgmap", pkgspool);
4715c51f124SMoriah Waterland 			(void) snprintf(locenv, sizeof (locenv),
472*dea58231SPeter Tribble 			    "%s/pkginfo", pkgspool);
4735c51f124SMoriah Waterland 			envfile = locenv;
4745c51f124SMoriah Waterland 
4755c51f124SMoriah Waterland 			/*
4765c51f124SMoriah Waterland 			 * NOTE : checkmap() frees the environ data and
4775c51f124SMoriah Waterland 			 * pointer when it's through with them.
4785c51f124SMoriah Waterland 			 */
4795c51f124SMoriah Waterland 			if (checkmap(0, (device != NULL), file, envfile,
480*dea58231SPeter Tribble 			    pkg[n], NULL, 0))
4815c51f124SMoriah Waterland 				errflg++;
4825c51f124SMoriah Waterland 			(void) printf(
483*dea58231SPeter Tribble 			    gettext("## Checking is complete.\n"));
4845c51f124SMoriah Waterland 		}
4855c51f124SMoriah Waterland 	} else {
4865c51f124SMoriah Waterland 		if (envfile)
4875c51f124SMoriah Waterland 			usage();
4885c51f124SMoriah Waterland 
4895c51f124SMoriah Waterland 		put_path_params();	/* Restore what's needed. */
4905c51f124SMoriah Waterland 
4915c51f124SMoriah Waterland 		/*
4925c51f124SMoriah Waterland 		 * If this is a check of a client of some sort, we'll need to
4935c51f124SMoriah Waterland 		 * mount up the client's filesystems. If the caller isn't
4945c51f124SMoriah Waterland 		 * root, this may not be possible.
4955c51f124SMoriah Waterland 		 */
4965c51f124SMoriah Waterland 		if (is_an_inst_root()) {
4975c51f124SMoriah Waterland 			if (getuid()) {
4985c51f124SMoriah Waterland 				logerr(gettext(MSG_NOTROOT));
4995c51f124SMoriah Waterland 				logerr(gettext(MSG_CONT));
5005c51f124SMoriah Waterland 			} else {
5015c51f124SMoriah Waterland 				if (get_mntinfo(map_client, vfstab_file))
5025c51f124SMoriah Waterland 					map_client = 0;
5035c51f124SMoriah Waterland 				if (map_client)
5045c51f124SMoriah Waterland 					mount_client();
5055c51f124SMoriah Waterland 			}
5065c51f124SMoriah Waterland 		}
5075c51f124SMoriah Waterland 
5085c51f124SMoriah Waterland 		(void) snprintf(file, sizeof (file),
509*dea58231SPeter Tribble 		    "%s/contents", get_PKGADM());
5105c51f124SMoriah Waterland 		if (ppathlist[0] != NULL) {
5115c51f124SMoriah Waterland 			for (n = 0; ppathlist[n]; n++) {
5125c51f124SMoriah Waterland 				if (checkmap(1, (device != NULL), file, NULL,
513*dea58231SPeter Tribble 				    NULL, ppathlist[n], 1))
5145c51f124SMoriah Waterland 					errflg++;
5155c51f124SMoriah Waterland 			}
5165c51f124SMoriah Waterland 		} else if (pkg[0] != NULL) {
5175c51f124SMoriah Waterland 				if (checkmap(1, (device != NULL), file, NULL,
518*dea58231SPeter Tribble 				    pkg[0], NULL, 0)) {
5195c51f124SMoriah Waterland 					errflg++;
5205c51f124SMoriah Waterland 				}
5215c51f124SMoriah Waterland 		} else {
5225c51f124SMoriah Waterland 			if (checkmap(1, (device != NULL), file, NULL,
523*dea58231SPeter Tribble 			    NULL, NULL, 0)) {
5245c51f124SMoriah Waterland 				errflg++;
5255c51f124SMoriah Waterland 			}
5265c51f124SMoriah Waterland 		}
5275c51f124SMoriah Waterland 
5285c51f124SMoriah Waterland 		if (map_client) {
5295c51f124SMoriah Waterland 			unmount_client();
5305c51f124SMoriah Waterland 		}
5315c51f124SMoriah Waterland 	}
5325c51f124SMoriah Waterland 	quit(errflg ? 1 : 0);
5335c51f124SMoriah Waterland 	/* LINTED: no return */
5345c51f124SMoriah Waterland }
5355c51f124SMoriah Waterland 
5365c51f124SMoriah Waterland static void
5375c51f124SMoriah Waterland setpathlist(char *file)
5385c51f124SMoriah Waterland {
5395c51f124SMoriah Waterland 	int fd;
5405c51f124SMoriah Waterland 	struct stat st;
5415c51f124SMoriah Waterland 	FILE *fplist;
5425c51f124SMoriah Waterland 	char pathname[PATH_MAX];
5435c51f124SMoriah Waterland 	/*
5445c51f124SMoriah Waterland 	 * This trap laid to catch a mismatch between the declaration above and
5455c51f124SMoriah Waterland 	 * the hard-coded constant in the fscanf below
5465c51f124SMoriah Waterland 	 */
5475c51f124SMoriah Waterland #if PATH_MAX != 1024
5485c51f124SMoriah Waterland #error "PATH_MAX changed, so we have a bug to fix"
5495c51f124SMoriah Waterland #endif
5505c51f124SMoriah Waterland 
5515c51f124SMoriah Waterland 	if (strcmp(file, "-") == 0) {
5525c51f124SMoriah Waterland 		fplist = stdin;
5535c51f124SMoriah Waterland 	} else {
5545c51f124SMoriah Waterland 		if ((fd = open(file, O_RDONLY)) == -1) {
5555c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
5565c51f124SMoriah Waterland 			quit(1);
5575c51f124SMoriah Waterland 		}
5585c51f124SMoriah Waterland 		if (fstat(fd, &st) == -1) {
5595c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
5605c51f124SMoriah Waterland 			quit(1);
5615c51f124SMoriah Waterland 		}
5625c51f124SMoriah Waterland 		if (S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
5635c51f124SMoriah Waterland 			progerr(gettext(ERR_PATHS_INVALID), file);
5645c51f124SMoriah Waterland 			quit(1);
5655c51f124SMoriah Waterland 		}
5665c51f124SMoriah Waterland 		if ((fplist = fdopen(fd, "r")) == NULL) {
5675c51f124SMoriah Waterland 			progerr(gettext(ERR_IOPEN), file);
5685c51f124SMoriah Waterland 			quit(1);
5695c51f124SMoriah Waterland 		}
5705c51f124SMoriah Waterland 	}
5715c51f124SMoriah Waterland 	while (fscanf(fplist, "%1024s", pathname) == 1) {
5725c51f124SMoriah Waterland 		if (*pathname == '\0') {
5735c51f124SMoriah Waterland 			progerr(gettext(ERR_PATHS_INVALID), file);
5745c51f124SMoriah Waterland 			quit(1);
5755c51f124SMoriah Waterland 		}
5765c51f124SMoriah Waterland 		pathlist[npaths] = qstrdup(pathname);
5775c51f124SMoriah Waterland 		if (npaths++ > MAXPATHS) {
5785c51f124SMoriah Waterland 			progerr(gettext(ERR_TOO_MANY), MAXPATHS);
5795c51f124SMoriah Waterland 			quit(1);
5805c51f124SMoriah Waterland 		}
5815c51f124SMoriah Waterland 	}
5825c51f124SMoriah Waterland 	if (npaths == 0) {
5835c51f124SMoriah Waterland 		progerr(gettext(ERR_IEMPTY));
5845c51f124SMoriah Waterland 		quit(1);
5855c51f124SMoriah Waterland 	}
5865c51f124SMoriah Waterland 	(void) fclose(fplist);
5875c51f124SMoriah Waterland }
5885c51f124SMoriah Waterland 
5895c51f124SMoriah Waterland void
5905c51f124SMoriah Waterland quit(int n)
5915c51f124SMoriah Waterland {
5925c51f124SMoriah Waterland 	/* cleanup any temporary directories */
5935c51f124SMoriah Waterland 	(void) chdir("/");
5945c51f124SMoriah Waterland 	if (tmpdir != NULL) {
5955c51f124SMoriah Waterland 		(void) rrmdir(tmpdir);
5965c51f124SMoriah Waterland 		free(tmpdir);
5975c51f124SMoriah Waterland 		tmpdir = NULL;
5985c51f124SMoriah Waterland 	}
5995c51f124SMoriah Waterland 	(void) pkghead(NULL);
6005c51f124SMoriah Waterland 	exit(n);
6015c51f124SMoriah Waterland 	/*NOTREACHED*/
6025c51f124SMoriah Waterland }
6035c51f124SMoriah Waterland 
6045c51f124SMoriah Waterland static void
6055c51f124SMoriah Waterland usage(void)
6065c51f124SMoriah Waterland {
6075c51f124SMoriah Waterland 	char *prog = get_prog_name();
6085c51f124SMoriah Waterland 
6095c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(ERR_USAGE), prog, prog);
6105c51f124SMoriah Waterland 	quit(1);
6115c51f124SMoriah Waterland 	/*NOTREACHED*/
6125c51f124SMoriah Waterland }
613