xref: /illumos-gate/usr/src/cmd/svr4pkg/pkgmk/main.c (revision c57b7750)
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 
225c51f124SMoriah Waterland /*
23c89503b9S"Nagaraj Yedathore - Sun Microsystems - Bangalore India"  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
245c51f124SMoriah Waterland  * Use is subject to license terms.
255c51f124SMoriah Waterland  */
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland 
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland #include <stdio.h>
325c51f124SMoriah Waterland #include <string.h>
335c51f124SMoriah Waterland #include <signal.h>
345c51f124SMoriah Waterland #include <errno.h>
355c51f124SMoriah Waterland #include <malloc.h>
365c51f124SMoriah Waterland #include <stdlib.h>
375c51f124SMoriah Waterland #include <unistd.h>
385c51f124SMoriah Waterland #include <time.h>
395c51f124SMoriah Waterland #include <fcntl.h>
405c51f124SMoriah Waterland #include <sys/types.h>
415c51f124SMoriah Waterland #include <sys/stat.h>
425c51f124SMoriah Waterland #include <sys/param.h>
435c51f124SMoriah Waterland #include <ctype.h>
445c51f124SMoriah Waterland #include <sys/mman.h>
455c51f124SMoriah Waterland #include <sys/sysmacros.h>
465c51f124SMoriah Waterland #include <strings.h>
475c51f124SMoriah Waterland #include <pkgstrct.h>
485c51f124SMoriah Waterland #include <pkgdev.h>
495c51f124SMoriah Waterland #include <pkginfo.h>
505c51f124SMoriah Waterland #include <pkglocs.h>
515c51f124SMoriah Waterland #include <locale.h>
525c51f124SMoriah Waterland #include <libintl.h>
535c51f124SMoriah Waterland #include <sys/statvfs.h>
545c51f124SMoriah Waterland #include <sys/utsname.h>
555c51f124SMoriah Waterland #include <instzones_api.h>
565c51f124SMoriah Waterland #include <pkglib.h>
575c51f124SMoriah Waterland #include <libadm.h>
585c51f124SMoriah Waterland #include <libinst.h>
595c51f124SMoriah Waterland 
605c51f124SMoriah Waterland extern char	**environ, *pkgdir;
615c51f124SMoriah Waterland 
625c51f124SMoriah Waterland /* mkpkgmap.c */
635c51f124SMoriah Waterland extern int	mkpkgmap(char *outfile, char *protofile, char **cmdparam);
645c51f124SMoriah Waterland /* splpkgmap.c */
655c51f124SMoriah Waterland extern int	splpkgmap(struct cfent **eptlist, unsigned int eptnum,
665c51f124SMoriah Waterland     char *order[], ulong_t bsize, ulong_t frsize, fsblkcnt_t *plimit,
675c51f124SMoriah Waterland     fsfilcnt_t *pilimit, fsblkcnt_t *pllimit);
685c51f124SMoriah Waterland /* scriptvfy.c */
695c51f124SMoriah Waterland extern int	checkscripts(char *inst_dir, int silent);
705c51f124SMoriah Waterland 
715c51f124SMoriah Waterland /* libpkg/gpkgmap.c */
725c51f124SMoriah Waterland extern void	setmapmode(int mode_no);
735c51f124SMoriah Waterland 
745c51f124SMoriah Waterland static boolean_t valid_zone_attr(struct cfent **eptlist);
755c51f124SMoriah Waterland 
765c51f124SMoriah Waterland #define	MALSIZ	16
775c51f124SMoriah Waterland #define	NROOT	8
785c51f124SMoriah Waterland #define	SPOOLDEV	"spool"
795c51f124SMoriah Waterland 
805c51f124SMoriah Waterland #define	MSG_PROTOTYPE	"## Building pkgmap from package prototype file.\n"
815c51f124SMoriah Waterland #define	MSG_PKGINFO	"## Processing pkginfo file.\n"
825c51f124SMoriah Waterland #define	MSG_VOLUMIZE	"## Attempting to volumize %d entries in pkgmap.\n"
835c51f124SMoriah Waterland #define	MSG_PACKAGE1	"## Packaging one part.\n"
845c51f124SMoriah Waterland #define	MSG_PACKAGEM	"## Packaging %d parts.\n"
855c51f124SMoriah Waterland #define	MSG_VALSCRIPTS	"## Validating control scripts.\n"
865c51f124SMoriah Waterland 
875c51f124SMoriah Waterland /* Other problems */
885c51f124SMoriah Waterland #define	ERR_MEMORY	"memory allocation failure, errno=%d"
895c51f124SMoriah Waterland #define	ERR_NROOT	"too many paths listed with -r option, limit is %d"
905c51f124SMoriah Waterland #define	ERR_PKGINST	"invalid package instance identifier <%s>"
915c51f124SMoriah Waterland #define	ERR_PKGABRV	"invalid package abbreviation <%s>"
925c51f124SMoriah Waterland #define	ERR_BADDEV	"unknown or invalid device specified <%s>"
935c51f124SMoriah Waterland #define	ERR_TEMP	"unable to obtain temporary file resources, errno=%d"
945c51f124SMoriah Waterland #define	ERR_DSTREAM	"invalid device specified (datastream) <%s>"
955c51f124SMoriah Waterland #define	ERR_SPLIT	"unable to volumize package"
965c51f124SMoriah Waterland #define	ERR_MKDIR	"unable to make directory <%s>"
975c51f124SMoriah Waterland #define	ERR_SYMLINK	"unable to create symbolic link for <%s>"
985c51f124SMoriah Waterland #define	ERR_OVERWRITE	"must use -o option to overwrite <%s>"
995c51f124SMoriah Waterland #define	ERR_UMOUNT	"unable to unmount device <%s>"
1005c51f124SMoriah Waterland #define	ERR_NOPKGINFO	"required pkginfo file is not specified in prototype " \
1015c51f124SMoriah Waterland 			"file"
1025c51f124SMoriah Waterland #define	ERR_RDPKGINFO	"unable to process pkginfo file <%s>"
1035c51f124SMoriah Waterland #define	ERR_PROTOTYPE	"unable to locate prototype file"
1045c51f124SMoriah Waterland #define	ERR_STATVFS	"unable to stat filesystem <%s>"
1055c51f124SMoriah Waterland #define	ERR_WHATVFS	"unable to determine or access output filesystem for " \
1065c51f124SMoriah Waterland 			"device <%s>"
1075c51f124SMoriah Waterland #define	ERR_DEVICE	"unable to find info for device <%s>"
1085c51f124SMoriah Waterland #define	ERR_BUILD	"unable to build pkgmap from prototype file"
1095c51f124SMoriah Waterland #define	ERR_ONEVOL	"other packages found - package must fit on a single " \
1105c51f124SMoriah Waterland 			"volume"
1115c51f124SMoriah Waterland #define	ERR_NOPARAM	"parameter <%s> is not defined in <%s>"
1125c51f124SMoriah Waterland #define	ERR_PKGMTCH	"PKG parameter <%s> does not match instance <%s>"
1135c51f124SMoriah Waterland #define	ERR_NO_PKG_INFOFILE	"unable to open pkginfo file <%s>: %s"
1145c51f124SMoriah Waterland #define	ERR_ALLZONES_AND_THISZONE	"The package <%s> has <%s> = true " \
1155c51f124SMoriah Waterland 					"and <%s> = true: the package may " \
1165c51f124SMoriah Waterland 					"set either parameter to true, but " \
1175c51f124SMoriah Waterland 					"may not set both parameters to " \
1185c51f124SMoriah Waterland 					"true. NOTE: if the package " \
1195c51f124SMoriah Waterland 					"contains a request script, it is " \
1205c51f124SMoriah Waterland 					"treated as though it has " \
1215c51f124SMoriah Waterland 					"<SUNW_PKG_THISZONE> = true"
1225c51f124SMoriah Waterland #define	ERR_NO_ALLZONES_AND_HOLLOW	"The package <%s> has <%s> = false " \
1235c51f124SMoriah Waterland 					"and <%s> = true: a hollow package " \
1245c51f124SMoriah Waterland 					"must also be set to install in all " \
1255c51f124SMoriah Waterland 					"zones"
1265c51f124SMoriah Waterland #define	ERR_PKGINFO_INVALID_OPTION_COMB	"Invalid combinations of zone " \
1275c51f124SMoriah Waterland 					"parameters in pkginfo file"
1285c51f124SMoriah Waterland 
1295c51f124SMoriah Waterland #define	ERR_USAGE	"usage: %s [options] [VAR=value [VAR=value]] " \
1305c51f124SMoriah Waterland 			"[pkginst]\n" \
1315c51f124SMoriah Waterland 			"   where options may include:\n" \
1325c51f124SMoriah Waterland 			"\t-o\n" \
1335c51f124SMoriah Waterland 			"\t-a arch\n" \
1345c51f124SMoriah Waterland 			"\t-v version\n" \
1355c51f124SMoriah Waterland 			"\t-p pstamp\n" \
1365c51f124SMoriah Waterland 			"\t-l limit\n" \
1375c51f124SMoriah Waterland 			"\t-r rootpath\n" \
1385c51f124SMoriah Waterland 			"\t-b basedir\n" \
1395c51f124SMoriah Waterland 			"\t-d device\n" \
1405c51f124SMoriah Waterland 			"\t-f protofile\n"
1415c51f124SMoriah Waterland #define	WRN_MISSINGDIR	"WARNING: missing directory entry for <%s>"
1425c51f124SMoriah Waterland #define	WRN_SETPARAM	"WARNING: parameter <%s> set to \"%s\""
1435c51f124SMoriah Waterland #define	WRN_CLASSES	"WARNING: unreferenced class <%s> in prototype file"
1445c51f124SMoriah Waterland 
1455c51f124SMoriah Waterland #define	LINK    1
1465c51f124SMoriah Waterland 
1475c51f124SMoriah Waterland struct pkgdev pkgdev; 	/* holds info about the installation device */
1485c51f124SMoriah Waterland int	started;
1495c51f124SMoriah Waterland char	pkgloc[PATH_MAX];
1505c51f124SMoriah Waterland char	*basedir;
1515c51f124SMoriah Waterland char	*root;
1525c51f124SMoriah Waterland char	*rootlist[NROOT];
1535c51f124SMoriah Waterland char	*t_pkgmap;
1545c51f124SMoriah Waterland char	*t_pkginfo;
1555c51f124SMoriah Waterland 
1565c51f124SMoriah Waterland static struct cfent *svept;
1575c51f124SMoriah Waterland static char	*protofile,
1585c51f124SMoriah Waterland 		*device;
1595c51f124SMoriah Waterland static fsblkcnt_t limit = 0;
1605c51f124SMoriah Waterland static fsblkcnt_t llimit = 0;
1615c51f124SMoriah Waterland static fsfilcnt_t ilimit = 0;
1625c51f124SMoriah Waterland static int	overwrite,
1635c51f124SMoriah Waterland 		nflag,
1645c51f124SMoriah Waterland 		sflag;
1655c51f124SMoriah Waterland static void	ckmissing(char *path, char type);
1665c51f124SMoriah Waterland static void	outvol(struct cfent **eptlist, unsigned int eptnum, int part,
1675c51f124SMoriah Waterland 			int nparts);
1685c51f124SMoriah Waterland static void	trap(int n);
1695c51f124SMoriah Waterland static void	usage(void);
1705c51f124SMoriah Waterland 
1715c51f124SMoriah Waterland static int	slinkf(char *from, char *to);
1725c51f124SMoriah Waterland 
1735c51f124SMoriah Waterland int
main(int argc,char * argv[])1745c51f124SMoriah Waterland main(int argc, char *argv[])
1755c51f124SMoriah Waterland {
1765c51f124SMoriah Waterland 	struct utsname utsbuf;
1775c51f124SMoriah Waterland 	struct statvfs64 svfsb;
1785c51f124SMoriah Waterland 	struct cfent	**eptlist;
1795c51f124SMoriah Waterland 	FILE	*fp;
1805c51f124SMoriah Waterland 	VFP_T	*vfp;
1815c51f124SMoriah Waterland 	int	c, n, found;
1825c51f124SMoriah Waterland 	int	part, nparts, npkgs, objects;
1835c51f124SMoriah Waterland 	char	buf[MAX_PKG_PARAM_LENGTH];
1845c51f124SMoriah Waterland 	char	temp[MAX_PKG_PARAM_LENGTH];
1855c51f124SMoriah Waterland 	char	param[MAX_PKG_PARAM_LENGTH];
1865c51f124SMoriah Waterland 	char	*pt, *value, *pkginst, *tmpdir, *abi_sym_ptr,
1875c51f124SMoriah Waterland 		**cmdparam;
1885c51f124SMoriah Waterland 	char	*pkgname;
1895c51f124SMoriah Waterland 	char	*pkgvers;
1905c51f124SMoriah Waterland 	char	*pkgarch;
1915c51f124SMoriah Waterland 	char	*pkgcat;
1925c51f124SMoriah Waterland 	void	(*func)();
1935c51f124SMoriah Waterland 	time_t	clock;
1945c51f124SMoriah Waterland 	ulong_t	bsize = 0;
1955c51f124SMoriah Waterland 	ulong_t	frsize = 0;
1965c51f124SMoriah Waterland 	struct cl_attr	**allclass = NULL;
1975c51f124SMoriah Waterland 	struct cl_attr	**order;
1985c51f124SMoriah Waterland 	unsigned int eptnum, i;
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland 	/* initialize locale environment */
2015c51f124SMoriah Waterland 
2025c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
2035c51f124SMoriah Waterland 
2045c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
2055c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
2065c51f124SMoriah Waterland #endif
2075c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
2085c51f124SMoriah Waterland 
2095c51f124SMoriah Waterland 	/* initialize program name */
2105c51f124SMoriah Waterland 
2115c51f124SMoriah Waterland 	(void) set_prog_name(argv[0]);
2125c51f124SMoriah Waterland 
2135c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
2145c51f124SMoriah Waterland 
2155c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
2165c51f124SMoriah Waterland 
2175c51f124SMoriah Waterland 	func = sigset(SIGINT, trap);
2185c51f124SMoriah Waterland 	if (func != SIG_DFL)
2195c51f124SMoriah Waterland 		func = sigset(SIGINT, func);
2205c51f124SMoriah Waterland 	func = sigset(SIGHUP, trap);
2215c51f124SMoriah Waterland 	setmapmode(MAPBUILD);	/* variable binding */
2225c51f124SMoriah Waterland 	if (func != SIG_DFL)
2235c51f124SMoriah Waterland 		func = sigset(SIGHUP, func);
2245c51f124SMoriah Waterland 
2255c51f124SMoriah Waterland 	environ = NULL;
2265c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "osnp:l:r:b:d:f:a:v:?")) != EOF) {
2275c51f124SMoriah Waterland 		switch (c) {
2285c51f124SMoriah Waterland 		    case 'n':
2295c51f124SMoriah Waterland 			nflag++;
2305c51f124SMoriah Waterland 			break;
2315c51f124SMoriah Waterland 
2325c51f124SMoriah Waterland 		    case 's':
2335c51f124SMoriah Waterland 			sflag++;
2345c51f124SMoriah Waterland 			break;
2355c51f124SMoriah Waterland 
2365c51f124SMoriah Waterland 		    case 'o':
2375c51f124SMoriah Waterland 			overwrite++;
2385c51f124SMoriah Waterland 			break;
2395c51f124SMoriah Waterland 
2405c51f124SMoriah Waterland 		    case 'p':
2415c51f124SMoriah Waterland 			putparam("PSTAMP", optarg);
2425c51f124SMoriah Waterland 			break;
2435c51f124SMoriah Waterland 
2445c51f124SMoriah Waterland 		    case 'l':
2455c51f124SMoriah Waterland 			llimit = strtoull(optarg, NULL, 10);
2465c51f124SMoriah Waterland 			break;
2475c51f124SMoriah Waterland 
2485c51f124SMoriah Waterland 		    case 'r':
2495c51f124SMoriah Waterland 			pt = strtok(optarg, " \t\n, ");
2505c51f124SMoriah Waterland 			n = 0;
2515c51f124SMoriah Waterland 			do {
2525c51f124SMoriah Waterland 				rootlist[n++] = flex_device(pt, 0);
2535c51f124SMoriah Waterland 				if (n >= NROOT) {
2545c51f124SMoriah Waterland 					progerr(gettext(ERR_NROOT), NROOT);
2555c51f124SMoriah Waterland 					quit(1);
2565c51f124SMoriah Waterland 				}
2575c51f124SMoriah Waterland 			} while (pt = strtok(NULL, " \t\n, "));
2585c51f124SMoriah Waterland 			rootlist[n] = NULL;
2595c51f124SMoriah Waterland 			break;
2605c51f124SMoriah Waterland 
2615c51f124SMoriah Waterland 		    case 'b':
2625c51f124SMoriah Waterland 			basedir = optarg;
2635c51f124SMoriah Waterland 			break;
2645c51f124SMoriah Waterland 
2655c51f124SMoriah Waterland 		    case 'f':
2665c51f124SMoriah Waterland 			protofile = optarg;
2675c51f124SMoriah Waterland 			break;
2685c51f124SMoriah Waterland 
2695c51f124SMoriah Waterland 		    case 'd':
2705c51f124SMoriah Waterland 			device = flex_device(optarg, 1);
2715c51f124SMoriah Waterland 			break;
2725c51f124SMoriah Waterland 
2735c51f124SMoriah Waterland 		    case 'a':
2745c51f124SMoriah Waterland 			putparam("ARCH", optarg);
2755c51f124SMoriah Waterland 			break;
2765c51f124SMoriah Waterland 
2775c51f124SMoriah Waterland 		    case 'v':
2785c51f124SMoriah Waterland 			putparam("VERSION", optarg);
2795c51f124SMoriah Waterland 			break;
2805c51f124SMoriah Waterland 
2815c51f124SMoriah Waterland 		    default:
2825c51f124SMoriah Waterland 			usage();
2835c51f124SMoriah Waterland 			/*NOTREACHED*/
2845c51f124SMoriah Waterland 			/*
2855c51f124SMoriah Waterland 			 * Although usage() calls a noreturn function,
2865c51f124SMoriah Waterland 			 * needed to add return (1);  so that main() would
2875c51f124SMoriah Waterland 			 * pass compilation checks. The statement below
2885c51f124SMoriah Waterland 			 * should never be executed.
2895c51f124SMoriah Waterland 			 */
2905c51f124SMoriah Waterland 			return (1);
2915c51f124SMoriah Waterland 		}
2925c51f124SMoriah Waterland 	}
2935c51f124SMoriah Waterland 
2945c51f124SMoriah Waterland 	/*
2955c51f124SMoriah Waterland 	 * Store command line variable assignments for later
2965c51f124SMoriah Waterland 	 * incorporation into the environment.
2975c51f124SMoriah Waterland 	 */
2985c51f124SMoriah Waterland 	cmdparam = &argv[optind];
2995c51f124SMoriah Waterland 
3005c51f124SMoriah Waterland 	/* Skip past equates. */
3015c51f124SMoriah Waterland 	while (argv[optind] && strchr(argv[optind], '='))
3025c51f124SMoriah Waterland 		optind++;
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland 	/* Confirm that the instance name is valid */
3055c51f124SMoriah Waterland 	if ((pkginst = argv[optind]) != NULL) {
3065c51f124SMoriah Waterland 		if (pkgnmchk(pkginst, "all", 0)) {
3075c51f124SMoriah Waterland 			progerr(gettext(ERR_PKGINST), pkginst);
3085c51f124SMoriah Waterland 			quit(1);
3095c51f124SMoriah Waterland 		}
3105c51f124SMoriah Waterland 		argv[optind++] = NULL;
3115c51f124SMoriah Waterland 	}
3125c51f124SMoriah Waterland 	if (optind != argc)
3135c51f124SMoriah Waterland 		usage();
3145c51f124SMoriah Waterland 
3155c51f124SMoriah Waterland 	tmpdir = getenv("TMPDIR");
3165c51f124SMoriah Waterland 	if (tmpdir == NULL)
3175c51f124SMoriah Waterland 		tmpdir = P_tmpdir;
3185c51f124SMoriah Waterland 
3195c51f124SMoriah Waterland 	/* bug id 4244631, not ABI compliant */
3205c51f124SMoriah Waterland 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
3215c51f124SMoriah Waterland 	if (abi_sym_ptr && (strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)) {
3225c51f124SMoriah Waterland 		set_nonABI_symlinks();
3235c51f124SMoriah Waterland 	}
3245c51f124SMoriah Waterland 
3255c51f124SMoriah Waterland 	if (device == NULL) {
3265c51f124SMoriah Waterland 		device = devattr(SPOOLDEV, "pathname");
3275c51f124SMoriah Waterland 		if (device == NULL) {
3285c51f124SMoriah Waterland 			progerr(gettext(ERR_DEVICE), SPOOLDEV);
3295c51f124SMoriah Waterland 			exit(99);
3305c51f124SMoriah Waterland 		}
3315c51f124SMoriah Waterland 	}
3325c51f124SMoriah Waterland 
3335c51f124SMoriah Waterland 	if (protofile == NULL) {
3345c51f124SMoriah Waterland 		if (access("prototype", 0) == 0)
3355c51f124SMoriah Waterland 			protofile = "prototype";
3365c51f124SMoriah Waterland 		else if (access("Prototype", 0) == 0)
3375c51f124SMoriah Waterland 			protofile = "Prototype";
3385c51f124SMoriah Waterland 		else {
3395c51f124SMoriah Waterland 			progerr(gettext(ERR_PROTOTYPE));
3405c51f124SMoriah Waterland 			quit(1);
3415c51f124SMoriah Waterland 		}
3425c51f124SMoriah Waterland 	}
3435c51f124SMoriah Waterland 
3445c51f124SMoriah Waterland 	if (devtype(device, &pkgdev)) {
3455c51f124SMoriah Waterland 		progerr(gettext(ERR_BADDEV), device);
3465c51f124SMoriah Waterland 		quit(1);
3475c51f124SMoriah Waterland 	}
3485c51f124SMoriah Waterland 	if (pkgdev.norewind) {
3495c51f124SMoriah Waterland 		/* initialize datastream */
3505c51f124SMoriah Waterland 		progerr(gettext(ERR_DSTREAM), device);
3515c51f124SMoriah Waterland 		quit(1);
3525c51f124SMoriah Waterland 	}
3535c51f124SMoriah Waterland 	if (pkgdev.mount) {
3545c51f124SMoriah Waterland 		if (n = pkgmount(&pkgdev, NULL, 0, 0, 1))
3555c51f124SMoriah Waterland 			quit(n);
3565c51f124SMoriah Waterland 	}
3575c51f124SMoriah Waterland 
3585c51f124SMoriah Waterland 	/*
3595c51f124SMoriah Waterland 	 * convert prototype file to a pkgmap, while locating
3605c51f124SMoriah Waterland 	 * package objects in the current environment
3615c51f124SMoriah Waterland 	 */
3625c51f124SMoriah Waterland 	t_pkgmap = tempnam(tmpdir, "tmpmap");
3635c51f124SMoriah Waterland 	if (t_pkgmap == NULL) {
3645c51f124SMoriah Waterland 		progerr(gettext(ERR_TEMP), errno);
3655c51f124SMoriah Waterland 		exit(99);
3665c51f124SMoriah Waterland 	}
3675c51f124SMoriah Waterland 
3685c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(MSG_PROTOTYPE));
3695c51f124SMoriah Waterland 	if (n = mkpkgmap(t_pkgmap, protofile, cmdparam)) {
3705c51f124SMoriah Waterland 		progerr(gettext(ERR_BUILD));
3715c51f124SMoriah Waterland 		quit(1);
3725c51f124SMoriah Waterland 	}
3735c51f124SMoriah Waterland 
3745c51f124SMoriah Waterland 	setmapmode(MAPNONE);	/* All appropriate variables are now bound */
3755c51f124SMoriah Waterland 
3765c51f124SMoriah Waterland 	if (vfpOpen(&vfp, t_pkgmap, "r", VFP_NEEDNOW) != 0) {
3775c51f124SMoriah Waterland 		progerr(gettext(ERR_TEMP), errno);
3785c51f124SMoriah Waterland 		quit(99);
3795c51f124SMoriah Waterland 	}
3805c51f124SMoriah Waterland 
3815c51f124SMoriah Waterland 	eptlist = procmap(vfp, 0, NULL);
3825c51f124SMoriah Waterland 
3835c51f124SMoriah Waterland 	if (eptlist == NULL) {
3845c51f124SMoriah Waterland 		quit(1);
3855c51f124SMoriah Waterland 	}
3865c51f124SMoriah Waterland 
3875c51f124SMoriah Waterland 	(void) vfpClose(&vfp);
3885c51f124SMoriah Waterland 
3895c51f124SMoriah Waterland 	/* Validate the zone attributes in pkginfo, before creation */
3905c51f124SMoriah Waterland 	if (!valid_zone_attr(eptlist)) {
3915c51f124SMoriah Waterland 		progerr(ERR_PKGINFO_INVALID_OPTION_COMB);
3925c51f124SMoriah Waterland 		quit(1);
3935c51f124SMoriah Waterland 	}
3945c51f124SMoriah Waterland 
3955c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(MSG_PKGINFO));
3965c51f124SMoriah Waterland 	pt = NULL;
3975c51f124SMoriah Waterland 	for (i = 0; eptlist[i]; i++) {
3985c51f124SMoriah Waterland 		ckmissing(eptlist[i]->path, eptlist[i]->ftype);
3995c51f124SMoriah Waterland 		if (eptlist[i]->ftype != 'i')
4005c51f124SMoriah Waterland 			continue;
4015c51f124SMoriah Waterland 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
4025c51f124SMoriah Waterland 			svept = eptlist[i];
4035c51f124SMoriah Waterland 	}
4045c51f124SMoriah Waterland 	if (svept == NULL) {
4055c51f124SMoriah Waterland 		progerr(gettext(ERR_NOPKGINFO));
4065c51f124SMoriah Waterland 		quit(99);
4075c51f124SMoriah Waterland 	}
4085c51f124SMoriah Waterland 	eptnum = i;
4095c51f124SMoriah Waterland 
4105c51f124SMoriah Waterland 	/*
4115c51f124SMoriah Waterland 	 * process all parameters from the pkginfo file
4125c51f124SMoriah Waterland 	 * and place them in the execution environment
4135c51f124SMoriah Waterland 	 */
4145c51f124SMoriah Waterland 
4155c51f124SMoriah Waterland 	if ((fp = fopen(svept->ainfo.local, "r")) == NULL) {
4165c51f124SMoriah Waterland 		progerr(gettext(ERR_RDPKGINFO), svept->ainfo.local);
4175c51f124SMoriah Waterland 		quit(99);
4185c51f124SMoriah Waterland 	}
4195c51f124SMoriah Waterland 	param[0] = '\0';
4205c51f124SMoriah Waterland 	while (value = fpkgparam(fp, param)) {
4215c51f124SMoriah Waterland 		if (getenv(param) == NULL)
4225c51f124SMoriah Waterland 			putparam(param, value);
4235c51f124SMoriah Waterland 		free((void *)value);
4245c51f124SMoriah Waterland 		param[0] = '\0';
4255c51f124SMoriah Waterland 	}
4265c51f124SMoriah Waterland 	(void) fclose(fp);
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 	/* add command line variables */
4295c51f124SMoriah Waterland 	while (*cmdparam && (value = strchr(*cmdparam, '=')) != NULL) {
430*c57b7750SToomas Soome 		*value = '\0';	/* terminate the parameter */
4315c51f124SMoriah Waterland 		value++;	/* value is now the value (not '=') */
4325c51f124SMoriah Waterland 		putparam(*cmdparam++, value);  /* store it in environ */
4335c51f124SMoriah Waterland 	}
4345c51f124SMoriah Waterland 
4355c51f124SMoriah Waterland 	/* make sure parameters are valid */
4365c51f124SMoriah Waterland 	(void) time(&clock);
4375c51f124SMoriah Waterland 	if (pt = getenv("PKG")) {
4385c51f124SMoriah Waterland 		if (pkgnmchk(pt, NULL, 0) || strchr(pt, '.')) {
4395c51f124SMoriah Waterland 			progerr(gettext(ERR_PKGABRV), pt);
4405c51f124SMoriah Waterland 			quit(1);
4415c51f124SMoriah Waterland 		}
4425c51f124SMoriah Waterland 		if (pkginst == NULL)
4435c51f124SMoriah Waterland 			pkginst = pt;
4445c51f124SMoriah Waterland 	} else {
4455c51f124SMoriah Waterland 		progerr(gettext(ERR_NOPARAM), "PKG", svept->path);
4465c51f124SMoriah Waterland 		quit(1);
4475c51f124SMoriah Waterland 	}
4485c51f124SMoriah Waterland 	/*
4495c51f124SMoriah Waterland 	 * verify consistency between PKG parameter and pkginst
4505c51f124SMoriah Waterland 	 */
4515c51f124SMoriah Waterland 	(void) snprintf(param, sizeof (param), "%s.*", pt);
4525c51f124SMoriah Waterland 	if (pkgnmchk(pkginst, param, 0)) {
4535c51f124SMoriah Waterland 		progerr(gettext(ERR_PKGMTCH), pt, pkginst);
4545c51f124SMoriah Waterland 		quit(1);
4555c51f124SMoriah Waterland 	}
4565c51f124SMoriah Waterland 
4575c51f124SMoriah Waterland 	if ((pkgname = getenv("NAME")) == NULL) {
4585c51f124SMoriah Waterland 		progerr(gettext(ERR_NOPARAM), "NAME", svept->path);
4595c51f124SMoriah Waterland 		quit(1);
4605c51f124SMoriah Waterland 	}
4615c51f124SMoriah Waterland 	if (ckparam("NAME", pkgname))
4625c51f124SMoriah Waterland 		quit(1);
4635c51f124SMoriah Waterland 	if ((pkgvers = getenv("VERSION")) == NULL) {
4645c51f124SMoriah Waterland 		/* XXX - I18n */
4655c51f124SMoriah Waterland 		/* LINTED do not use cftime(); use strftime instead */
4665c51f124SMoriah Waterland 		(void) cftime(buf, "\045m/\045d/\045Y", &clock);
4675c51f124SMoriah Waterland 		(void) snprintf(temp, sizeof (temp),
4685c51f124SMoriah Waterland 			gettext("Dev Release %s"), buf);
4695c51f124SMoriah Waterland 		putparam("VERSION", temp);
4705c51f124SMoriah Waterland 		pkgvers = getenv("VERSION");
4715c51f124SMoriah Waterland 		logerr(gettext(WRN_SETPARAM), "VERSION", temp);
4725c51f124SMoriah Waterland 	}
4735c51f124SMoriah Waterland 	if (ckparam("VERSION", pkgvers))
4745c51f124SMoriah Waterland 		quit(1);
4755c51f124SMoriah Waterland 	if ((pkgarch = getenv("ARCH")) == NULL) {
4765c51f124SMoriah Waterland 		(void) uname(&utsbuf);
4775c51f124SMoriah Waterland 		putparam("ARCH", utsbuf.machine);
4785c51f124SMoriah Waterland 		pkgarch = getenv("ARCH");
4795c51f124SMoriah Waterland 		logerr(gettext(WRN_SETPARAM), "ARCH", utsbuf.machine);
4805c51f124SMoriah Waterland 	}
4815c51f124SMoriah Waterland 	if (ckparam("ARCH", pkgarch))
4825c51f124SMoriah Waterland 		quit(1);
4835c51f124SMoriah Waterland 	if (getenv("PSTAMP") == NULL) {
4845c51f124SMoriah Waterland 		/* use octal value of '%' to fight sccs expansion */
4855c51f124SMoriah Waterland 		/* XXX - I18n */
4865c51f124SMoriah Waterland 		/* LINTED do not use cftime(); use strftime instead */
4875c51f124SMoriah Waterland 		(void) cftime(buf, "\045Y\045m\045d\045H\045M\045S", &clock);
4885c51f124SMoriah Waterland 		(void) uname(&utsbuf);
4895c51f124SMoriah Waterland 		(void) snprintf(temp, sizeof (temp), "%s%s",
4905c51f124SMoriah Waterland 			utsbuf.nodename, buf);
4915c51f124SMoriah Waterland 		putparam("PSTAMP", temp);
4925c51f124SMoriah Waterland 		logerr(gettext(WRN_SETPARAM), "PSTAMP", temp);
4935c51f124SMoriah Waterland 	}
4945c51f124SMoriah Waterland 	if ((pkgcat = getenv("CATEGORY")) == NULL) {
4955c51f124SMoriah Waterland 		progerr(gettext(ERR_NOPARAM), "CATEGORY", svept->path);
4965c51f124SMoriah Waterland 		quit(1);
4975c51f124SMoriah Waterland 	}
4985c51f124SMoriah Waterland 	if (ckparam("CATEGORY", pkgcat))
4995c51f124SMoriah Waterland 		quit(1);
5005c51f124SMoriah Waterland 
5015c51f124SMoriah Waterland 	/*
5025c51f124SMoriah Waterland 	 * warn user of classes listed in package which do
5035c51f124SMoriah Waterland 	 * not appear in CLASSES variable in pkginfo file
5045c51f124SMoriah Waterland 	 */
5055c51f124SMoriah Waterland 	objects = 0;
5065c51f124SMoriah Waterland 	for (i = 0; eptlist[i]; i++) {
5075c51f124SMoriah Waterland 		if (eptlist[i]->ftype != 'i') {
5085c51f124SMoriah Waterland 			objects++;
5095c51f124SMoriah Waterland 			addlist(&allclass, eptlist[i]->pkg_class);
5105c51f124SMoriah Waterland 		}
5115c51f124SMoriah Waterland 	}
5125c51f124SMoriah Waterland 
5135c51f124SMoriah Waterland 	if ((pt = getenv("CLASSES")) == NULL) {
5145c51f124SMoriah Waterland 		if (allclass && *allclass) {
5155c51f124SMoriah Waterland 			cl_setl(allclass);
5165c51f124SMoriah Waterland 			cl_putl("CLASSES", allclass);
5175c51f124SMoriah Waterland 			logerr(gettext(WRN_SETPARAM), "CLASSES",
5185c51f124SMoriah Waterland 			    getenv("CLASSES"));
5195c51f124SMoriah Waterland 		}
5205c51f124SMoriah Waterland 	} else {
5215c51f124SMoriah Waterland 		cl_sets(qstrdup(pt));
5225c51f124SMoriah Waterland 		if (allclass && *allclass) {
5235c51f124SMoriah Waterland 			for (i = 0; allclass[i]; i++) {
5245c51f124SMoriah Waterland 				found = 0;
5255c51f124SMoriah Waterland 				if (cl_idx(allclass[i]->name) != -1) {
5265c51f124SMoriah Waterland 					found++;
5275c51f124SMoriah Waterland 					break;
5285c51f124SMoriah Waterland 				}
5295c51f124SMoriah Waterland 				if (!found) {
5305c51f124SMoriah Waterland 					logerr(gettext(WRN_CLASSES),
5315c51f124SMoriah Waterland 					    (char *)allclass[i]);
5325c51f124SMoriah Waterland 				}
5335c51f124SMoriah Waterland 			}
5345c51f124SMoriah Waterland 		}
5355c51f124SMoriah Waterland 	}
5365c51f124SMoriah Waterland 
5375c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(MSG_VOLUMIZE), objects);
5385c51f124SMoriah Waterland 	order = (struct cl_attr **)0;
5395c51f124SMoriah Waterland 	if (pt = getenv("ORDER")) {
5405c51f124SMoriah Waterland 		pt = qstrdup(pt);
5415c51f124SMoriah Waterland 		(void) setlist(&order, pt);
5425c51f124SMoriah Waterland 		cl_putl("ORDER", order);
5435c51f124SMoriah Waterland 	}
5445c51f124SMoriah Waterland 
5455c51f124SMoriah Waterland 	/* stat the intended output filesystem to get blocking information */
5465c51f124SMoriah Waterland 	if (pkgdev.dirname == NULL) {
5475c51f124SMoriah Waterland 		progerr(gettext(ERR_WHATVFS), device);
5485c51f124SMoriah Waterland 		quit(99);
5495c51f124SMoriah Waterland 	}
5505c51f124SMoriah Waterland 	if (statvfs64(pkgdev.dirname, &svfsb)) {
5515c51f124SMoriah Waterland 		progerr(gettext(ERR_STATVFS), pkgdev.dirname);
5525c51f124SMoriah Waterland 		quit(99);
5535c51f124SMoriah Waterland 	}
5545c51f124SMoriah Waterland 
5555c51f124SMoriah Waterland 	if (bsize == 0) {
5565c51f124SMoriah Waterland 		bsize = svfsb.f_bsize;
5575c51f124SMoriah Waterland 	}
5585c51f124SMoriah Waterland 	if (frsize == 0) {
5595c51f124SMoriah Waterland 		frsize = svfsb.f_frsize;
5605c51f124SMoriah Waterland 	}
5615c51f124SMoriah Waterland 
5625c51f124SMoriah Waterland 	if (limit == 0)
5635c51f124SMoriah Waterland 		/*
5645c51f124SMoriah Waterland 		 * bavail is in terms of fragment size blocks - change
5655c51f124SMoriah Waterland 		 * to 512 byte blocks
5665c51f124SMoriah Waterland 		 */
5675c51f124SMoriah Waterland 		limit = (fsblkcnt_t)(((fsblkcnt_t)frsize > 0) ?
5685c51f124SMoriah Waterland 			howmany(frsize, DEV_BSIZE) :
5695c51f124SMoriah Waterland 			howmany(bsize, DEV_BSIZE)) * svfsb.f_bavail;
5705c51f124SMoriah Waterland 
5715c51f124SMoriah Waterland 	if (ilimit == 0) {
5725c51f124SMoriah Waterland 		ilimit = (svfsb.f_favail > 0) ?
5735c51f124SMoriah Waterland 		    svfsb.f_favail : svfsb.f_ffree;
5745c51f124SMoriah Waterland 	}
5755c51f124SMoriah Waterland 
5765c51f124SMoriah Waterland 	nparts = splpkgmap(eptlist, eptnum, (char **)order, bsize, frsize,
5775c51f124SMoriah Waterland 	    &limit, &ilimit, &llimit);
5785c51f124SMoriah Waterland 
5795c51f124SMoriah Waterland 	if (nparts <= 0) {
5805c51f124SMoriah Waterland 		progerr(gettext(ERR_SPLIT));
5815c51f124SMoriah Waterland 		quit(1);
5825c51f124SMoriah Waterland 	}
5835c51f124SMoriah Waterland 
5845c51f124SMoriah Waterland 	if (nflag) {
5855c51f124SMoriah Waterland 		for (i = 0; eptlist[i]; i++)
5865c51f124SMoriah Waterland 			(void) ppkgmap(eptlist[i], stdout);
5875c51f124SMoriah Waterland 		exit(0);
5885c51f124SMoriah Waterland 		/*NOTREACHED*/
5895c51f124SMoriah Waterland 	}
5905c51f124SMoriah Waterland 
5915c51f124SMoriah Waterland 	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s",
5925c51f124SMoriah Waterland 			pkgdev.dirname, pkginst);
5935c51f124SMoriah Waterland 	if (!isdir(pkgloc) && !overwrite) {
5945c51f124SMoriah Waterland 		progerr(gettext(ERR_OVERWRITE), pkgloc);
5955c51f124SMoriah Waterland 		quit(1);
5965c51f124SMoriah Waterland 	}
5975c51f124SMoriah Waterland 
5985c51f124SMoriah Waterland 	/* output all environment install parameters */
5995c51f124SMoriah Waterland 	t_pkginfo = tempnam(tmpdir, "pkginfo");
6005c51f124SMoriah Waterland 	if ((fp = fopen(t_pkginfo, "w")) == NULL) {
6015c51f124SMoriah Waterland 		progerr(gettext(ERR_TEMP), errno);
6025c51f124SMoriah Waterland 		exit(99);
6035c51f124SMoriah Waterland 	}
6045c51f124SMoriah Waterland 	for (i = 0; environ[i]; i++) {
6055c51f124SMoriah Waterland 		if (isupper(*environ[i])) {
6065c51f124SMoriah Waterland 			(void) fputs(environ[i], fp);
6075c51f124SMoriah Waterland 			(void) fputc('\n', fp);
6085c51f124SMoriah Waterland 		}
6095c51f124SMoriah Waterland 	}
6105c51f124SMoriah Waterland 	(void) fclose(fp);
6115c51f124SMoriah Waterland 
6125c51f124SMoriah Waterland 	started++;
6135c51f124SMoriah Waterland 	(void) rrmdir(pkgloc);
6145c51f124SMoriah Waterland 	if (mkdir(pkgloc, 0755)) {
6155c51f124SMoriah Waterland 		progerr(gettext(ERR_MKDIR), pkgloc);
6165c51f124SMoriah Waterland 		quit(1);
6175c51f124SMoriah Waterland 	}
6185c51f124SMoriah Waterland 
6195c51f124SMoriah Waterland 	/* determine how many packages already reside on the medium */
6205c51f124SMoriah Waterland 	pkgdir = pkgdev.dirname;
6215c51f124SMoriah Waterland 	npkgs = 0;
6225c51f124SMoriah Waterland 	while (pt = fpkginst("all", NULL, NULL))
6235c51f124SMoriah Waterland 		npkgs++;
6245c51f124SMoriah Waterland 	(void) fpkginst(NULL); /* free resource usage */
6255c51f124SMoriah Waterland 
6265c51f124SMoriah Waterland 	if (nparts > 1) {
6275c51f124SMoriah Waterland 		if (pkgdev.mount && npkgs) {
6285c51f124SMoriah Waterland 			progerr(gettext(ERR_ONEVOL));
6295c51f124SMoriah Waterland 			quit(1);
6305c51f124SMoriah Waterland 		}
6315c51f124SMoriah Waterland 	}
6325c51f124SMoriah Waterland 
6335c51f124SMoriah Waterland 	/*
6345c51f124SMoriah Waterland 	 *  update pkgmap entry for pkginfo file, since it may
6355c51f124SMoriah Waterland 	 *  have changed due to command line or failure to
6365c51f124SMoriah Waterland 	 *  specify all neccessary parameters
6375c51f124SMoriah Waterland 	 */
6385c51f124SMoriah Waterland 	for (i = 0; eptlist[i]; i++) {
6395c51f124SMoriah Waterland 		if (eptlist[i]->ftype != 'i')
6405c51f124SMoriah Waterland 			continue;
6415c51f124SMoriah Waterland 		if (strcmp(eptlist[i]->path, "pkginfo") == 0) {
6425c51f124SMoriah Waterland 			svept = eptlist[i];
6435c51f124SMoriah Waterland 			svept->ftype = '?';
6445c51f124SMoriah Waterland 			svept->ainfo.local = t_pkginfo;
6455c51f124SMoriah Waterland 			(void) cverify(0, &svept->ftype, t_pkginfo,
6465c51f124SMoriah Waterland 				&svept->cinfo, 1);
6475c51f124SMoriah Waterland 			svept->ftype = 'i';
6485c51f124SMoriah Waterland 			break;
6495c51f124SMoriah Waterland 		}
6505c51f124SMoriah Waterland 	}
6515c51f124SMoriah Waterland 
6525c51f124SMoriah Waterland 	if (nparts > 1)
6535c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext(MSG_PACKAGEM), nparts);
6545c51f124SMoriah Waterland 	else
6555c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext(MSG_PACKAGE1));
6565c51f124SMoriah Waterland 
6575c51f124SMoriah Waterland 	for (part = 1; part <= nparts; part++) {
6585c51f124SMoriah Waterland 		if ((part > 1) && pkgdev.mount) {
6595c51f124SMoriah Waterland 			if (pkgumount(&pkgdev)) {
6605c51f124SMoriah Waterland 				progerr(gettext(ERR_UMOUNT), pkgdev.mount);
6615c51f124SMoriah Waterland 				quit(99);
6625c51f124SMoriah Waterland 			}
6635c51f124SMoriah Waterland 			if (n = pkgmount(&pkgdev, NULL, part, nparts, 1))
6645c51f124SMoriah Waterland 				quit(n);
6655c51f124SMoriah Waterland 			(void) rrmdir(pkgloc);
6665c51f124SMoriah Waterland 			if (mkdir(pkgloc, 0555)) {
6675c51f124SMoriah Waterland 				progerr(gettext(ERR_MKDIR), pkgloc);
6685c51f124SMoriah Waterland 				quit(99);
6695c51f124SMoriah Waterland 			}
6705c51f124SMoriah Waterland 		}
6715c51f124SMoriah Waterland 		outvol(eptlist, eptnum, part, nparts);
6725c51f124SMoriah Waterland 
6735c51f124SMoriah Waterland 		/* Validate (as much as possible) the control scripts. */
6745c51f124SMoriah Waterland 		if (part == 1) {
6755c51f124SMoriah Waterland 			char inst_path[PATH_MAX];
6765c51f124SMoriah Waterland 
6775c51f124SMoriah Waterland 			(void) fprintf(stderr, gettext(MSG_VALSCRIPTS));
6785c51f124SMoriah Waterland 			(void) snprintf(inst_path, sizeof (inst_path),
6795c51f124SMoriah Waterland 					"%s/install", pkgloc);
6805c51f124SMoriah Waterland 			checkscripts(inst_path, 0);
6815c51f124SMoriah Waterland 		}
6825c51f124SMoriah Waterland 	}
6835c51f124SMoriah Waterland 
6845c51f124SMoriah Waterland 	quit(0);
6855c51f124SMoriah Waterland 	/* LINTED: no return */
6865c51f124SMoriah Waterland }
6875c51f124SMoriah Waterland 
6885c51f124SMoriah Waterland static void
trap(int n)6895c51f124SMoriah Waterland trap(int n)
6905c51f124SMoriah Waterland {
6915c51f124SMoriah Waterland 	(void) signal(SIGINT, SIG_IGN);
6925c51f124SMoriah Waterland 	(void) signal(SIGHUP, SIG_IGN);
6935c51f124SMoriah Waterland 
6945c51f124SMoriah Waterland 	if (n == SIGINT)
6955c51f124SMoriah Waterland 		quit(3);
6965c51f124SMoriah Waterland 	else {
6975c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext("%s terminated (signal %d).\n"),
6985c51f124SMoriah Waterland 				get_prog_name(), n);
6995c51f124SMoriah Waterland 		quit(99);
7005c51f124SMoriah Waterland 	}
7015c51f124SMoriah Waterland }
7025c51f124SMoriah Waterland 
7035c51f124SMoriah Waterland static void
outvol(struct cfent ** eptlist,unsigned int eptnum,int part,int nparts)7045c51f124SMoriah Waterland outvol(struct cfent **eptlist, unsigned int eptnum, int part, int nparts)
7055c51f124SMoriah Waterland {
7065c51f124SMoriah Waterland 	FILE	*fp;
7075c51f124SMoriah Waterland 	char	*svpt, *path, temp[PATH_MAX];
7085c51f124SMoriah Waterland 	unsigned int	i;
7095c51f124SMoriah Waterland 
7105c51f124SMoriah Waterland 
7115c51f124SMoriah Waterland 	if (nparts > 1)
7125c51f124SMoriah Waterland 		(void) fprintf(stderr, gettext(" -- part %2d:\n"), part);
7135c51f124SMoriah Waterland 	if (part == 1) {
7145c51f124SMoriah Waterland 		/* re-write pkgmap, but exclude local pathnames */
7155c51f124SMoriah Waterland 		(void) snprintf(temp, sizeof (temp), "%s/pkgmap", pkgloc);
7165c51f124SMoriah Waterland 		if ((fp = fopen(temp, "w")) == NULL) {
7175c51f124SMoriah Waterland 			progerr(gettext(ERR_TEMP), errno);
7185c51f124SMoriah Waterland 			quit(99);
7195c51f124SMoriah Waterland 		}
720c89503b9S"Nagaraj Yedathore - Sun Microsystems - Bangalore India" 		(void) fprintf(fp, ": %d %llu\n", nparts, limit);
7215c51f124SMoriah Waterland 		for (i = 0; eptlist[i]; i++) {
7225c51f124SMoriah Waterland 			svpt = eptlist[i]->ainfo.local;
7235c51f124SMoriah Waterland 			if (!strchr("sl", eptlist[i]->ftype))
7245c51f124SMoriah Waterland 				eptlist[i]->ainfo.local = NULL;
7255c51f124SMoriah Waterland 			if (ppkgmap(eptlist[i], fp)) {
7265c51f124SMoriah Waterland 				progerr(gettext(ERR_TEMP), errno);
7275c51f124SMoriah Waterland 				quit(99);
7285c51f124SMoriah Waterland 			}
7295c51f124SMoriah Waterland 			eptlist[i]->ainfo.local = svpt;
7305c51f124SMoriah Waterland 		}
7315c51f124SMoriah Waterland 		(void) fclose(fp);
7325c51f124SMoriah Waterland 		(void) fprintf(stderr, "%s\n", temp);
7335c51f124SMoriah Waterland 	}
7345c51f124SMoriah Waterland 
7355c51f124SMoriah Waterland 	(void) snprintf(temp, sizeof (temp), "%s/pkginfo", pkgloc);
7365c51f124SMoriah Waterland 	if (copyf(svept->ainfo.local, temp, svept->cinfo.modtime))
7375c51f124SMoriah Waterland 		quit(1);
7385c51f124SMoriah Waterland 	(void) fprintf(stderr, "%s\n", temp);
7395c51f124SMoriah Waterland 
7405c51f124SMoriah Waterland 	for (i = 0; i < eptnum; i++) {
7415c51f124SMoriah Waterland 		if (eptlist[i]->volno != part)
7425c51f124SMoriah Waterland 			continue;
7435c51f124SMoriah Waterland 		if (strchr("dxslcbp", eptlist[i]->ftype))
7445c51f124SMoriah Waterland 			continue;
7455c51f124SMoriah Waterland 		if (eptlist[i]->ftype == 'i') {
7465c51f124SMoriah Waterland 			if (eptlist[i] == svept)
7475c51f124SMoriah Waterland 				continue; /* don't copy pkginfo file */
7485c51f124SMoriah Waterland 			(void) snprintf(temp, sizeof (temp),
7495c51f124SMoriah Waterland 				"%s/install/%s", pkgloc,
7505c51f124SMoriah Waterland 				eptlist[i]->path);
7515c51f124SMoriah Waterland 			path = temp;
7525c51f124SMoriah Waterland 		} else
7535c51f124SMoriah Waterland 			path = srcpath(pkgloc, eptlist[i]->path, part, nparts);
7545c51f124SMoriah Waterland 		if (sflag) {
7555c51f124SMoriah Waterland 			if (slinkf(eptlist[i]->ainfo.local, path))
7565c51f124SMoriah Waterland 				quit(1);
7575c51f124SMoriah Waterland 		} else if (copyf(eptlist[i]->ainfo.local, path,
7585c51f124SMoriah Waterland 				eptlist[i]->cinfo.modtime)) {
7595c51f124SMoriah Waterland 			quit(1);
7605c51f124SMoriah Waterland 		}
7615c51f124SMoriah Waterland 
7625c51f124SMoriah Waterland 		/*
7635c51f124SMoriah Waterland 		 * If the package file attributes can be sync'd up with
7645c51f124SMoriah Waterland 		 * the pkgmap, we fix the attributes here.
7655c51f124SMoriah Waterland 		 */
7665c51f124SMoriah Waterland 		if (*(eptlist[i]->ainfo.owner) != '$' &&
767fbde34edSNorm Jacobs 		    *(eptlist[i]->ainfo.group) != '$') {
7685c51f124SMoriah Waterland 			/* Clear dangerous bits. */
7695c51f124SMoriah Waterland 			eptlist[i]->ainfo.mode=
7705c51f124SMoriah Waterland 			    (eptlist[i]->ainfo.mode & S_IAMB);
7715c51f124SMoriah Waterland 			/*
7725c51f124SMoriah Waterland 			 * Make sure it can be read by the world and written
773fbde34edSNorm Jacobs 			 * by the owner.
7745c51f124SMoriah Waterland 			 */
7755c51f124SMoriah Waterland 			eptlist[i]->ainfo.mode |= 0644;
7765c51f124SMoriah Waterland 			if (!strchr("in", eptlist[i]->ftype)) {
7775c51f124SMoriah Waterland 				/* Set the safe attributes. */
7785c51f124SMoriah Waterland 				averify(1, &(eptlist[i]->ftype),
7795c51f124SMoriah Waterland 				    path, &(eptlist[i]->ainfo));
7805c51f124SMoriah Waterland 			}
7815c51f124SMoriah Waterland 		}
7825c51f124SMoriah Waterland 
7835c51f124SMoriah Waterland 		(void) fprintf(stderr, "%s\n", path);
7845c51f124SMoriah Waterland 	}
7855c51f124SMoriah Waterland }
7865c51f124SMoriah Waterland 
7875c51f124SMoriah Waterland static void
ckmissing(char * path,char type)7885c51f124SMoriah Waterland ckmissing(char *path, char type)
7895c51f124SMoriah Waterland {
7905c51f124SMoriah Waterland 	static char	**dir;
7915c51f124SMoriah Waterland 	static int	ndir;
7925c51f124SMoriah Waterland 	char	*pt;
7935c51f124SMoriah Waterland 	int	i, found;
7945c51f124SMoriah Waterland 
7955c51f124SMoriah Waterland 	if (dir == NULL) {
7965c51f124SMoriah Waterland 		dir = (char **)calloc(MALSIZ, sizeof (char *));
7975c51f124SMoriah Waterland 		if (dir == NULL) {
7985c51f124SMoriah Waterland 			progerr(gettext(ERR_MEMORY), errno);
7995c51f124SMoriah Waterland 			quit(99);
8005c51f124SMoriah Waterland 		}
8015c51f124SMoriah Waterland 	}
8025c51f124SMoriah Waterland 
8035c51f124SMoriah Waterland 	if (strchr("dx", type)) {
8045c51f124SMoriah Waterland 		dir[ndir] = path;
8055c51f124SMoriah Waterland 		if ((++ndir % MALSIZ) == 0) {
8065c51f124SMoriah Waterland 			dir = (char **)realloc((void *)dir,
8075c51f124SMoriah Waterland 				(ndir+MALSIZ)*sizeof (char *));
8085c51f124SMoriah Waterland 			if (dir == NULL) {
8095c51f124SMoriah Waterland 				progerr(gettext(ERR_MEMORY), errno);
8105c51f124SMoriah Waterland 				quit(99);
8115c51f124SMoriah Waterland 			}
8125c51f124SMoriah Waterland 		}
8135c51f124SMoriah Waterland 		dir[ndir] = (char *)NULL;
8145c51f124SMoriah Waterland 	}
8155c51f124SMoriah Waterland 
8165c51f124SMoriah Waterland 	pt = path;
8175c51f124SMoriah Waterland 	if (*pt == '/')
8185c51f124SMoriah Waterland 		pt++;
8195c51f124SMoriah Waterland 	while (pt = strchr(pt, '/')) {
8205c51f124SMoriah Waterland 		*pt = '\0';
8215c51f124SMoriah Waterland 		found = 0;
8225c51f124SMoriah Waterland 		for (i = 0; i < ndir; i++) {
8235c51f124SMoriah Waterland 			if (strcmp(path, dir[i]) == 0) {
8245c51f124SMoriah Waterland 				found++;
8255c51f124SMoriah Waterland 				break;
8265c51f124SMoriah Waterland 			}
8275c51f124SMoriah Waterland 		}
8285c51f124SMoriah Waterland 		if (!found) {
8295c51f124SMoriah Waterland 			logerr(gettext(WRN_MISSINGDIR), path);
8305c51f124SMoriah Waterland 			ckmissing(qstrdup(path), 'd');
8315c51f124SMoriah Waterland 		}
8325c51f124SMoriah Waterland 		*pt++ = '/';
8335c51f124SMoriah Waterland 	}
8345c51f124SMoriah Waterland }
8355c51f124SMoriah Waterland 
8365c51f124SMoriah Waterland static int
slinkf(char * from,char * to)8375c51f124SMoriah Waterland slinkf(char *from, char *to)
8385c51f124SMoriah Waterland {
8395c51f124SMoriah Waterland 	char	*pt;
8405c51f124SMoriah Waterland 
8415c51f124SMoriah Waterland 	pt = to;
8425c51f124SMoriah Waterland 	while (pt = strchr(pt+1, '/')) {
8435c51f124SMoriah Waterland 		*pt = '\0';
8445c51f124SMoriah Waterland 		if (isdir(to) && mkdir(to, 0755)) {
8455c51f124SMoriah Waterland 			progerr(gettext(ERR_MKDIR), to);
8465c51f124SMoriah Waterland 			*pt = '/';
8475c51f124SMoriah Waterland 			return (-1);
8485c51f124SMoriah Waterland 		}
8495c51f124SMoriah Waterland 		*pt = '/';
8505c51f124SMoriah Waterland 	}
8515c51f124SMoriah Waterland 	if (symlink(from, to)) {
8525c51f124SMoriah Waterland 		progerr(gettext(ERR_SYMLINK), to);
8535c51f124SMoriah Waterland 		return (-1);
8545c51f124SMoriah Waterland 	}
8555c51f124SMoriah Waterland 	return (0);
8565c51f124SMoriah Waterland }
8575c51f124SMoriah Waterland 
8585c51f124SMoriah Waterland static void
usage(void)8595c51f124SMoriah Waterland usage(void)
8605c51f124SMoriah Waterland {
8615c51f124SMoriah Waterland 	(void) fprintf(stderr, gettext(ERR_USAGE), get_prog_name());
8625c51f124SMoriah Waterland 	exit(1);
8635c51f124SMoriah Waterland 	/*NOTREACHED*/
8645c51f124SMoriah Waterland }
8655c51f124SMoriah Waterland 
8665c51f124SMoriah Waterland /*
8675c51f124SMoriah Waterland  * valid_zone_attr:	Validates the zone attributes specified in
8685c51f124SMoriah Waterland  *			pkginfo file for this package. The package
8695c51f124SMoriah Waterland  *			can not be created with certain combinations
8705c51f124SMoriah Waterland  *			of the attributes.
8715c51f124SMoriah Waterland  */
8725c51f124SMoriah Waterland static boolean_t
valid_zone_attr(struct cfent ** eptlist)8735c51f124SMoriah Waterland valid_zone_attr(struct cfent **eptlist)
8745c51f124SMoriah Waterland {
8755c51f124SMoriah Waterland 	FILE		*pkginfoFP;
8765c51f124SMoriah Waterland 	boolean_t	all_zones;	/* pkg is "all zones" only */
8775c51f124SMoriah Waterland 	boolean_t	is_hollow;	/* pkg is "hollow" */
8785c51f124SMoriah Waterland 	boolean_t	this_zone;	/* pkg is "this zone" only */
8795c51f124SMoriah Waterland 	char 		pkginfoPath[PATH_MAX];	/* pkginfo file path */
8805c51f124SMoriah Waterland 	char		*pkgInst;
8815c51f124SMoriah Waterland 	int i;
8825c51f124SMoriah Waterland 
8835c51f124SMoriah Waterland 	/* Path to pkginfo file within the package to be installed */
8845c51f124SMoriah Waterland 
8855c51f124SMoriah Waterland 	this_zone = B_FALSE;
8865c51f124SMoriah Waterland 	for (i = 0; eptlist[i]; i++) {
8875c51f124SMoriah Waterland 		if (eptlist[i]->ftype != 'i')
8885c51f124SMoriah Waterland 			continue;
8895c51f124SMoriah Waterland 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
8905c51f124SMoriah Waterland 			(void) strcpy(pkginfoPath, eptlist[i]->ainfo.local);
8915c51f124SMoriah Waterland 
8925c51f124SMoriah Waterland 		/*
8935c51f124SMoriah Waterland 		 * Check to see if this package has a request script. If this
8945c51f124SMoriah Waterland 		 * package does have a request script, then mark the package
8955c51f124SMoriah Waterland 		 * for installation in this zone only. Any package with a
8965c51f124SMoriah Waterland 		 * request script cannot be installed outside of the zone the
8975c51f124SMoriah Waterland 		 * pkgadd command is being run in, nor can such a package be
8985c51f124SMoriah Waterland 		 * installed as part of a new zone install. A new zone install
8995c51f124SMoriah Waterland 		 * must be non-interactive, which is required by all packages
9005c51f124SMoriah Waterland 		 * integrated into the Solaris WOS.
9015c51f124SMoriah Waterland 		 * If request file is set in prototype, then this_zone is TRUE.
9025c51f124SMoriah Waterland 		 */
9035c51f124SMoriah Waterland 		if (strcmp(eptlist[i]->path, "request") == 0)
9045c51f124SMoriah Waterland 			this_zone = B_TRUE;
9055c51f124SMoriah Waterland 	}
9065c51f124SMoriah Waterland 
9075c51f124SMoriah Waterland 	/* Gather information from the pkginfo file */
9085c51f124SMoriah Waterland 
9095c51f124SMoriah Waterland 	pkginfoFP = fopen(pkginfoPath, "r");
9105c51f124SMoriah Waterland 
9115c51f124SMoriah Waterland 	if (pkginfoFP == NULL) {
9125c51f124SMoriah Waterland 		progerr(ERR_NO_PKG_INFOFILE, pkginfoPath, strerror(errno));
9135c51f124SMoriah Waterland 		return (B_FALSE);
9145c51f124SMoriah Waterland 	}
9155c51f124SMoriah Waterland 
9165c51f124SMoriah Waterland 	if ((pkgInst = fpkgparam(pkginfoFP, "PKG")) == NULL) {
9175c51f124SMoriah Waterland 		progerr(gettext(ERR_NOPARAM), "PKG", pkginfoPath);
9185c51f124SMoriah Waterland 		return (B_FALSE);
9195c51f124SMoriah Waterland 	}
9205c51f124SMoriah Waterland 
9215c51f124SMoriah Waterland 
9225c51f124SMoriah Waterland 	/* Determine "HOLLOW" setting for this package */
9235c51f124SMoriah Waterland 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
9245c51f124SMoriah Waterland 			"true", B_FALSE);
9255c51f124SMoriah Waterland 
9265c51f124SMoriah Waterland 	/* Determine "ALLZONES" setting for this package */
9275c51f124SMoriah Waterland 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
9285c51f124SMoriah Waterland 			"true", B_FALSE);
9295c51f124SMoriah Waterland 
9305c51f124SMoriah Waterland 	/* Determine "THISZONE" setting for this package, if no request file */
9315c51f124SMoriah Waterland 	if (!this_zone)
9325c51f124SMoriah Waterland 		this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
9335c51f124SMoriah Waterland 			"true", B_FALSE);
9345c51f124SMoriah Waterland 
9355c51f124SMoriah Waterland 	/* Close pkginfo file */
9365c51f124SMoriah Waterland 	(void) fclose(pkginfoFP);
9375c51f124SMoriah Waterland 
9385c51f124SMoriah Waterland 	/*
9395c51f124SMoriah Waterland 	 * Validate zone attributes based on information gathered,
9405c51f124SMoriah Waterland 	 * and validate the three SUNW_PKG_ options:
9415c51f124SMoriah Waterland 	 *
9425c51f124SMoriah Waterland 	 * -----------------------------|---------------|
9435c51f124SMoriah Waterland 	 * <ALLZONES><HOLLOW><THISZONE> |  If Allowed   |
9445c51f124SMoriah Waterland 	 * ----1------------------------|---------------|
9455c51f124SMoriah Waterland 	 *		F F F		|	OK	|
9465c51f124SMoriah Waterland 	 *		F F T		|	OK	|
9475c51f124SMoriah Waterland 	 *		F T *		|	NO	|
9485c51f124SMoriah Waterland 	 * ----2------------------------|---------------|
9495c51f124SMoriah Waterland 	 *		T F F		|	OK	|
9505c51f124SMoriah Waterland 	 *		T T F		|	OK	|
9515c51f124SMoriah Waterland 	 *		T * T		|	NO	|
9525c51f124SMoriah Waterland 	 * -----------------------------|---------------|
9535c51f124SMoriah Waterland 	 */
9545c51f124SMoriah Waterland 
9555c51f124SMoriah Waterland 	/* pkg "all zones" && "this zone" (#2) */
9565c51f124SMoriah Waterland 
9575c51f124SMoriah Waterland 	if (all_zones && this_zone) {
9585c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_THISZONE, pkgInst,
9595c51f124SMoriah Waterland 		    PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
9605c51f124SMoriah Waterland 		return (B_FALSE);
9615c51f124SMoriah Waterland 	}
9625c51f124SMoriah Waterland 
9635c51f124SMoriah Waterland 	/* pkg "!all zones" && "hollow" (#1) */
9645c51f124SMoriah Waterland 
9655c51f124SMoriah Waterland 	if ((!all_zones) && is_hollow) {
9665c51f124SMoriah Waterland 		progerr(ERR_NO_ALLZONES_AND_HOLLOW, pkgInst,
9675c51f124SMoriah Waterland 		    PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
9685c51f124SMoriah Waterland 		return (B_FALSE);
9695c51f124SMoriah Waterland 	}
9705c51f124SMoriah Waterland 
9715c51f124SMoriah Waterland 	return (B_TRUE);
9725c51f124SMoriah Waterland }
973