xref: /titanic_41/usr/src/cmd/svr4pkg/pkgcond/main.c (revision 4656d4747c8743290bfbe910c64cd75eb4e4af8d)
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 /*
236e1ae2a3SGary Pennington  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
245c51f124SMoriah Waterland  */
255c51f124SMoriah Waterland 
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland /*
285c51f124SMoriah Waterland  * Program:	pkgcond
295c51f124SMoriah Waterland  *
305c51f124SMoriah Waterland  * Function:	Implements the package command suite public utility pkgcond(1M)
315c51f124SMoriah Waterland  *
325c51f124SMoriah Waterland  * Usage:	pkgcond [-nv] [-O debug] condition [ argument ]
335c51f124SMoriah Waterland  *
345c51f124SMoriah Waterland  *		command options:
355c51f124SMoriah Waterland  *			-n - negate results of condition test
365c51f124SMoriah Waterland  *			-v - verbose output of condition testing
375c51f124SMoriah Waterland  *
385c51f124SMoriah Waterland  *		<condition> may be any one of:
395c51f124SMoriah Waterland  *			can_add_driver [path]
405c51f124SMoriah Waterland  *			can_remove_driver [path]
415c51f124SMoriah Waterland  *			can_update_driver [path]
425c51f124SMoriah Waterland  *			is_alternative_root [path]
435c51f124SMoriah Waterland  *			is_boot_environment [path]
445c51f124SMoriah Waterland  *			is_diskless_client [path]
455c51f124SMoriah Waterland  *			is_global_zone [path]
465c51f124SMoriah Waterland  *			is_mounted_miniroot [path]
475c51f124SMoriah Waterland  *			is_netinstall_image [path]
485c51f124SMoriah Waterland  *			is_nonglobal_zone [path]
495c51f124SMoriah Waterland  *			is_path_writable path
505c51f124SMoriah Waterland  *			is_running_system [path]
515c51f124SMoriah Waterland  *			is_what [path]
525c51f124SMoriah Waterland  *			is_whole_root_nonglobal_zone [path]
535c51f124SMoriah Waterland  *
545c51f124SMoriah Waterland  *		<option(s)> are specific to the condition used
555c51f124SMoriah Waterland  *
565c51f124SMoriah Waterland  * Input:	depends on command
575c51f124SMoriah Waterland  *
585c51f124SMoriah Waterland  * Output:	depends on command
595c51f124SMoriah Waterland  *
605c51f124SMoriah Waterland  * Exit status:	If the -n option is not specified:
615c51f124SMoriah Waterland  *		== 0 - the specified condition is true (or exists).
625c51f124SMoriah Waterland  *		== 1 - the specified condition is false (or does not exist).
635c51f124SMoriah Waterland  *		== 2 - command line usage errors (including bad keywords)
645c51f124SMoriah Waterland  *		== 3 - command failed to perform the test due to a fatal error
655c51f124SMoriah Waterland  *
665c51f124SMoriah Waterland  *		If the -n option is specified:
675c51f124SMoriah Waterland  *		== 0 - the specified condition is false (or does not exist).
685c51f124SMoriah Waterland  *		== 1 - the specified condition is true (or exists).
695c51f124SMoriah Waterland  *		== 2 - command line usage errors (including bad keywords)
705c51f124SMoriah Waterland  *		== 3 - command failed to perform the test due to a fatal error
715c51f124SMoriah Waterland  */
725c51f124SMoriah Waterland 
735c51f124SMoriah Waterland #include <stdio.h>
745c51f124SMoriah Waterland #include <sys/mnttab.h>
755c51f124SMoriah Waterland #include <sys/mntent.h>
765c51f124SMoriah Waterland #include <stdarg.h>
775c51f124SMoriah Waterland #include <stdlib.h>
785c51f124SMoriah Waterland #include <string.h>
795c51f124SMoriah Waterland #include <strings.h>
805c51f124SMoriah Waterland #include <fcntl.h>
815c51f124SMoriah Waterland #include <ctype.h>
825c51f124SMoriah Waterland #include <sys/types.h>
835c51f124SMoriah Waterland #include <sys/stat.h>
845c51f124SMoriah Waterland #include <unistd.h>
855c51f124SMoriah Waterland #include <locale.h>
865c51f124SMoriah Waterland #include <errno.h>
875c51f124SMoriah Waterland #include <sys/param.h>
885c51f124SMoriah Waterland #include <assert.h>
895c51f124SMoriah Waterland 
905c51f124SMoriah Waterland #include <instzones_api.h>
915c51f124SMoriah Waterland #include <pkglib.h>
925c51f124SMoriah Waterland #include <install.h>
935c51f124SMoriah Waterland #include <libinst.h>
945c51f124SMoriah Waterland #include <libadm.h>
955c51f124SMoriah Waterland #include <messages.h>
965c51f124SMoriah Waterland #include "pkgcond.h"
975c51f124SMoriah Waterland #include "pkgcond_msgs.h"
985c51f124SMoriah Waterland 
995c51f124SMoriah Waterland /* Should be defined by cc -D */
1005c51f124SMoriah Waterland 
1015c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)
1025c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
1035c51f124SMoriah Waterland #endif
1045c51f124SMoriah Waterland 
1055c51f124SMoriah Waterland /* commands to execute */
1065c51f124SMoriah Waterland 
1075c51f124SMoriah Waterland #define	LS_CMD		"/usr/bin/ls"
1085c51f124SMoriah Waterland 
1095c51f124SMoriah Waterland /*
1105c51f124SMoriah Waterland  * type definition and "types" for testPath()
1115c51f124SMoriah Waterland  */
1125c51f124SMoriah Waterland 
1135c51f124SMoriah Waterland typedef enum {
1145c51f124SMoriah Waterland 	TEST_EXISTS = 0x01,
1155c51f124SMoriah Waterland 	TEST_NOT_EXISTS = 0x02,
1165c51f124SMoriah Waterland 	TEST_IS_DIRECTORY = 0x04,
1175c51f124SMoriah Waterland 	TEST_IS_FILE = 0x08,
1185c51f124SMoriah Waterland 	TEST_NOT_DIRECTORY = 0x10,
1195c51f124SMoriah Waterland 	TEST_NOT_FILE = 0x20,
1205c51f124SMoriah Waterland 	TEST_IS_SYMBOLIC_LINK = 0x40,
1215c51f124SMoriah Waterland 	TEST_NOT_SYMBOLIC_LINK = 0x80,
1225c51f124SMoriah Waterland 	TEST_GLOBAL_TOKEN_IN_FILE = 0x100
1235c51f124SMoriah Waterland } TEST_TYPES;
1245c51f124SMoriah Waterland 
1255c51f124SMoriah Waterland /* holds file system info */
1265c51f124SMoriah Waterland 
1275c51f124SMoriah Waterland struct fsi_t {
1285c51f124SMoriah Waterland 	char	*fsi_mntOptions;
1295c51f124SMoriah Waterland 	char	*fsi_fsType;
1305c51f124SMoriah Waterland 	char	*fsi_mntPoint;
1315c51f124SMoriah Waterland };
1325c51f124SMoriah Waterland typedef struct fsi_t	FSI_T;
1335c51f124SMoriah Waterland 
1345c51f124SMoriah Waterland /* holds parsed global data */
1355c51f124SMoriah Waterland 
1365c51f124SMoriah Waterland struct globalData_t {
1375c51f124SMoriah Waterland 		/* initial install: PKG_INIT_INSTALL=true */
1385c51f124SMoriah Waterland 	boolean_t gd_initialInstall;
1395c51f124SMoriah Waterland 		/* global zone install: SUNW_PKG_INSTALL_ZONENAME=global */
1405c51f124SMoriah Waterland 	boolean_t gd_globalZoneInstall;
1415c51f124SMoriah Waterland 		/* non-global zone install: SUNW_PKG_INSTALL_ZONENAME!=global */
1425c51f124SMoriah Waterland 	boolean_t gd_nonglobalZoneInstall;
1435c51f124SMoriah Waterland 		/* non-global zone is in a mounted state */
1445c51f124SMoriah Waterland 	boolean_t inMountedState;
1455c51f124SMoriah Waterland 		/* sorted list of all mounted file systems */
1465c51f124SMoriah Waterland 	FSI_T	*gd_fileSystemConfig;
1475c51f124SMoriah Waterland 		/* number of mounted file systems in list */
1485c51f124SMoriah Waterland 	long	gd_fileSystemConfigLen;
1495c51f124SMoriah Waterland 		/* current zone name */
1505c51f124SMoriah Waterland 	char	*gd_zoneName;
1515c51f124SMoriah Waterland 		/* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneName */
1525c51f124SMoriah Waterland 	char	*gd_parentZoneName;
1535c51f124SMoriah Waterland 		/* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneType */
1545c51f124SMoriah Waterland 	char	*gd_parentZoneType;
1555c51f124SMoriah Waterland 		/* root path to target: PKG_INSTALL_ROOT */
1565c51f124SMoriah Waterland 	char	*gd_installRoot;
1575c51f124SMoriah Waterland 		/* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneName */
1585c51f124SMoriah Waterland 	char	*gd_currentZoneName;
1595c51f124SMoriah Waterland 		/* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneType */
1605c51f124SMoriah Waterland 	char	*gd_currentZoneType;
1615c51f124SMoriah Waterland 		/* path provided on command line */
1625c51f124SMoriah Waterland 	char	*gd_cmdline_path;
1635c51f124SMoriah Waterland };
1645c51f124SMoriah Waterland typedef struct globalData_t	GLOBALDATA_T;
1655c51f124SMoriah Waterland 
1665c51f124SMoriah Waterland /* holds subcommands and their definitions */
1675c51f124SMoriah Waterland 
1685c51f124SMoriah Waterland struct cmd_t {
1695c51f124SMoriah Waterland 	char		*c_name;
1705c51f124SMoriah Waterland 	char		*c_args;
1715c51f124SMoriah Waterland 	int		(*c_func)(int argc, char **argv, GLOBALDATA_T *a_gdt);
1725c51f124SMoriah Waterland };
1735c51f124SMoriah Waterland typedef struct cmd_t	CMD_T;
1745c51f124SMoriah Waterland 
1755c51f124SMoriah Waterland /* Command function prototypes */
1765c51f124SMoriah Waterland 
1775c51f124SMoriah Waterland static int		cmd_can_add_driver(int argc, char **argv,
1785c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1795c51f124SMoriah Waterland static int		cmd_can_remove_driver(int argc, char **argv,
1805c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1815c51f124SMoriah Waterland static int		cmd_can_update_driver(int argc, char **argv,
1825c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1835c51f124SMoriah Waterland static int		cmd_is_alternative_root(int argc, char **argv,
1845c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1855c51f124SMoriah Waterland static int		cmd_is_boot_environment(int argc, char **argv,
1865c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1875c51f124SMoriah Waterland static int		cmd_is_diskless_client(int argc, char **argv,
1885c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1895c51f124SMoriah Waterland static int		cmd_is_global_zone(int argc, char **argv,
1905c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1915c51f124SMoriah Waterland static int		cmd_is_mounted_miniroot(int argc, char **argv,
1925c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1935c51f124SMoriah Waterland static int		cmd_is_netinstall_image(int argc, char **argv,
1945c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1955c51f124SMoriah Waterland static int		cmd_is_nonglobal_zone(int argc, char **argv,
1965c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1975c51f124SMoriah Waterland static int		cmd_is_path_writable(int argc, char **argv,
1985c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
1995c51f124SMoriah Waterland static int		cmd_is_running_system(int argc, char **argv,
2005c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
2015c51f124SMoriah Waterland static int		cmd_is_what(int argc, char **argv,
2025c51f124SMoriah Waterland 				GLOBALDATA_T *a_gdt);
2035c51f124SMoriah Waterland 
2045c51f124SMoriah Waterland /* Utility function Prototypes */
2055c51f124SMoriah Waterland 
2065c51f124SMoriah Waterland static boolean_t	getNegateResults(void);
2075c51f124SMoriah Waterland static boolean_t	recursionCheck(int *r_recursion, char *a_function);
2085c51f124SMoriah Waterland static int		adjustResults(int a_result);
2095c51f124SMoriah Waterland static int		calculateFileSystemConfig(GLOBALDATA_T *a_gdt);
2105c51f124SMoriah Waterland static int		getRootPath(char **r_rootPath);
2115c51f124SMoriah Waterland static int		getZoneName(char **r_zoneName);
2125c51f124SMoriah Waterland static int		mountOptionPresent(char *a_mntOptions, char *a_opt);
2135c51f124SMoriah Waterland static int		parseGlobalData(char *a_envVar, GLOBALDATA_T **a_gdt);
2145c51f124SMoriah Waterland static int		resolvePath(char **r_path);
2155c51f124SMoriah Waterland static int		setRootPath(char *a_path, char *a_envVar,
2165c51f124SMoriah Waterland     boolean_t a_mustExist);
2175c51f124SMoriah Waterland static int		testPath(TEST_TYPES a_tt, char *format, ...);
2185c51f124SMoriah Waterland static int		usage(char *a_format, ...);
2195c51f124SMoriah Waterland static int		findToken(char *path, char *token);
2205c51f124SMoriah Waterland static char		*getMountOption(char **p);
2215c51f124SMoriah Waterland static void		dumpGlobalData(GLOBALDATA_T *a_gdt);
2225c51f124SMoriah Waterland static void		removeLeadingWhitespace(char **a_str);
2235c51f124SMoriah Waterland static void		setNegateResults(boolean_t setting);
2245c51f124SMoriah Waterland static void		setVerbose(boolean_t);
2255c51f124SMoriah Waterland static void		sortedInsert(FSI_T **r_list, long *a_listSize,
2265c51f124SMoriah Waterland     char *a_mntPoint, char *a_fsType, char *a_mntOptions);
2275c51f124SMoriah Waterland static void		setCmdLinePath(char **a_path, char **args,
2285c51f124SMoriah Waterland     int num_args);
2295c51f124SMoriah Waterland 
2305c51f124SMoriah Waterland /* local static data */
2315c51f124SMoriah Waterland 
2325c51f124SMoriah Waterland static boolean_t	_negateResults = B_FALSE;
2335c51f124SMoriah Waterland static char		*_rootPath = "/";
2345c51f124SMoriah Waterland 
2355c51f124SMoriah Waterland /* define subcommand data structure */
2365c51f124SMoriah Waterland 
2375c51f124SMoriah Waterland static CMD_T cmds[] = {
2385c51f124SMoriah Waterland 	{ "can_add_driver",		" [path]",
2395c51f124SMoriah Waterland 		cmd_can_add_driver },
2405c51f124SMoriah Waterland 	{ "can_remove_driver",		" [path]",
2415c51f124SMoriah Waterland 		cmd_can_remove_driver },
2425c51f124SMoriah Waterland 	{ "can_update_driver",		" [path]",
2435c51f124SMoriah Waterland 		cmd_can_update_driver },
2445c51f124SMoriah Waterland 	{ "is_alternative_root",	" [path]",
2455c51f124SMoriah Waterland 		cmd_is_alternative_root },
2465c51f124SMoriah Waterland 	{ "is_boot_environment",	" [path]",
2475c51f124SMoriah Waterland 		cmd_is_boot_environment },
2485c51f124SMoriah Waterland 	{ "is_diskless_client",		" [path]",
2495c51f124SMoriah Waterland 		cmd_is_diskless_client },
2505c51f124SMoriah Waterland 	{ "is_global_zone",		" [path]",
2515c51f124SMoriah Waterland 		cmd_is_global_zone },
2525c51f124SMoriah Waterland 	{ "is_mounted_miniroot",	" [path]",
2535c51f124SMoriah Waterland 		cmd_is_mounted_miniroot },
2545c51f124SMoriah Waterland 	{ "is_netinstall_image",	" [path]",
2555c51f124SMoriah Waterland 		cmd_is_netinstall_image },
2565c51f124SMoriah Waterland 	{ "is_nonglobal_zone",		" [path]",
2575c51f124SMoriah Waterland 		cmd_is_nonglobal_zone },
2585c51f124SMoriah Waterland 	{ "is_path_writable",		" path",
2595c51f124SMoriah Waterland 		cmd_is_path_writable },
2605c51f124SMoriah Waterland 	{ "is_running_system",		" [path]",
2615c51f124SMoriah Waterland 		cmd_is_running_system },
2625c51f124SMoriah Waterland 	{ "is_what", " [path]",
2635c51f124SMoriah Waterland 		cmd_is_what },
2645c51f124SMoriah Waterland 	/* last one must be all NULLs */
2656e1ae2a3SGary Pennington 	{ NULL, NULL, NULL }
2665c51f124SMoriah Waterland };
2675c51f124SMoriah Waterland 
2685c51f124SMoriah Waterland /*
2695c51f124SMoriah Waterland  * *****************************************************************************
2705c51f124SMoriah Waterland  * main
2715c51f124SMoriah Waterland  * *****************************************************************************
2725c51f124SMoriah Waterland  */
2735c51f124SMoriah Waterland 
2745c51f124SMoriah Waterland /*
2755c51f124SMoriah Waterland  * Name:	main
2765c51f124SMoriah Waterland  * Description:	main processing loop for pkgcond *
2775c51f124SMoriah Waterland  * Return:	0 - condition is satisfied (true)
2785c51f124SMoriah Waterland  *		1 - condition is not satisfied (false)
2795c51f124SMoriah Waterland  *		2 - command line usage errors
2805c51f124SMoriah Waterland  *		3 - failure to determine condition
2815c51f124SMoriah Waterland  */
2825c51f124SMoriah Waterland 
2835c51f124SMoriah Waterland int
main(int argc,char ** argv)2845c51f124SMoriah Waterland main(int argc, char **argv)
2855c51f124SMoriah Waterland {
2865c51f124SMoriah Waterland 	GLOBALDATA_T	*gdt = NULL;
2875c51f124SMoriah Waterland 	char		**newargv;
2885c51f124SMoriah Waterland 	char		*p;
2895c51f124SMoriah Waterland 	int		cur_cmd;
2905c51f124SMoriah Waterland 	int		i;
2915c51f124SMoriah Waterland 	int		newargc;
2925c51f124SMoriah Waterland 
2935c51f124SMoriah Waterland 	/* make standard output non-buffered */
2945c51f124SMoriah Waterland 
2955c51f124SMoriah Waterland 	setbuf(stdout, NULL);
2965c51f124SMoriah Waterland 
2975c51f124SMoriah Waterland 	/* set the default text domain for messaging */
2985c51f124SMoriah Waterland 
2995c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
3005c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
3015c51f124SMoriah Waterland 
3025c51f124SMoriah Waterland 	/* remember command name */
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland 	set_prog_name(argv[0]);
3055c51f124SMoriah Waterland 
3065c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
3075c51f124SMoriah Waterland 
3085c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
3095c51f124SMoriah Waterland 
3105c51f124SMoriah Waterland 	/* set verbose mode if appropriate environment variable is set */
3115c51f124SMoriah Waterland 
3125c51f124SMoriah Waterland 	if (getenv(ENV_VAR_VERBOSE)) {
3135c51f124SMoriah Waterland 		/* same as -v */
3145c51f124SMoriah Waterland 		setVerbose(B_TRUE);
3155c51f124SMoriah Waterland 	}
3165c51f124SMoriah Waterland 
3175c51f124SMoriah Waterland 	/* set debug mode if appropriate environment variable is set */
3185c51f124SMoriah Waterland 
3195c51f124SMoriah Waterland 	if (getenv(ENV_VAR_DEBUG)) {
3205c51f124SMoriah Waterland 		/* same as -O debug */
3215c51f124SMoriah Waterland 
3225c51f124SMoriah Waterland 		/* set sml tracing (sml.c) */
3235c51f124SMoriah Waterland 		smlSetVerbose(B_TRUE);
3245c51f124SMoriah Waterland 
3255c51f124SMoriah Waterland 		/* set log and echo (interactive) message tracing */
3265c51f124SMoriah Waterland 		setVerbose(B_TRUE);
3275c51f124SMoriah Waterland 
3285c51f124SMoriah Waterland 		/* enable echoDebug debugging messages */
3295c51f124SMoriah Waterland 		echoDebugSetFlag(B_TRUE);
3305c51f124SMoriah Waterland 	}
3315c51f124SMoriah Waterland 
3325c51f124SMoriah Waterland 	/* generate usage if no options or arguments specified */
3335c51f124SMoriah Waterland 
3345c51f124SMoriah Waterland 	if (argc <= 1) {
3355c51f124SMoriah Waterland 		(void) usage(MSG_NO_ARGUMENTS_SPECIFIED);
3365c51f124SMoriah Waterland 		return (R_USAGE);
3375c51f124SMoriah Waterland 	}
3385c51f124SMoriah Waterland 
3395c51f124SMoriah Waterland 	/*
3405c51f124SMoriah Waterland 	 * process any arguments that can appear before the subcommand
3415c51f124SMoriah Waterland 	 */
3425c51f124SMoriah Waterland 
3435c51f124SMoriah Waterland 	while ((i = getopt(argc, argv, ":O:vn?")) != EOF) {
3445c51f124SMoriah Waterland 		switch (i) {
3455c51f124SMoriah Waterland 		/*
3465c51f124SMoriah Waterland 		 * Not a public interface: the -O option allows the behavior
3475c51f124SMoriah Waterland 		 * of the package tools to be modified. Recognized options:
3485c51f124SMoriah Waterland 		 * -> debug
3495c51f124SMoriah Waterland 		 * ---> enable debugging output
3505c51f124SMoriah Waterland 		 */
3515c51f124SMoriah Waterland 
3525c51f124SMoriah Waterland 		case 'O':
3535c51f124SMoriah Waterland 			for (p = strtok(optarg, ","); p != NULL;
3545c51f124SMoriah Waterland 				p = strtok(NULL, ",")) {
3555c51f124SMoriah Waterland 
3565c51f124SMoriah Waterland 				/* debug - enable all tracing */
3575c51f124SMoriah Waterland 
3585c51f124SMoriah Waterland 				if (strcmp(p, "debug") == 0) {
3595c51f124SMoriah Waterland 					/* set sml tracing */
3605c51f124SMoriah Waterland 					smlSetVerbose(B_TRUE);
3615c51f124SMoriah Waterland 					/* set log/echo tracing */
3625c51f124SMoriah Waterland 					setVerbose(B_TRUE);
3635c51f124SMoriah Waterland 					/* enable debugging messages */
3645c51f124SMoriah Waterland 					echoDebugSetFlag(B_TRUE);
3655c51f124SMoriah Waterland 					continue;
3665c51f124SMoriah Waterland 				}
3675c51f124SMoriah Waterland 
3685c51f124SMoriah Waterland 				progerr(ERR_INVALID_O_OPTION, p);
3695c51f124SMoriah Waterland 				return (adjustResults(R_USAGE));
3705c51f124SMoriah Waterland 			}
3715c51f124SMoriah Waterland 			break;
3725c51f124SMoriah Waterland 
3735c51f124SMoriah Waterland 		/*
3745c51f124SMoriah Waterland 		 * Public interface: enable verbose (debug) output.
3755c51f124SMoriah Waterland 		 */
3765c51f124SMoriah Waterland 
3775c51f124SMoriah Waterland 		case 'v':	/* verbose mode enabled */
3785c51f124SMoriah Waterland 			/* set command tracing only */
3795c51f124SMoriah Waterland 			setVerbose(B_TRUE);
3805c51f124SMoriah Waterland 			break;
3815c51f124SMoriah Waterland 
3825c51f124SMoriah Waterland 		/*
3835c51f124SMoriah Waterland 		 * Public interface: negate output results.
3845c51f124SMoriah Waterland 		 */
3855c51f124SMoriah Waterland 
3865c51f124SMoriah Waterland 		case 'n':
3875c51f124SMoriah Waterland 			setNegateResults(B_TRUE);
3885c51f124SMoriah Waterland 			break;
3895c51f124SMoriah Waterland 
3905c51f124SMoriah Waterland 		/*
3915c51f124SMoriah Waterland 		 * unrecognized option
3925c51f124SMoriah Waterland 		 */
3935c51f124SMoriah Waterland 
3945c51f124SMoriah Waterland 		case '?':
3955c51f124SMoriah Waterland 		default:
3965c51f124SMoriah Waterland 			(void) usage(MSG_INVALID_OPTION_SPECIFIED, optopt);
3975c51f124SMoriah Waterland 			return (R_USAGE);
3985c51f124SMoriah Waterland 		}
3995c51f124SMoriah Waterland 	}
4005c51f124SMoriah Waterland 
4015c51f124SMoriah Waterland 	/*
4025c51f124SMoriah Waterland 	 * done processing options that can preceed subcommand
4035c51f124SMoriah Waterland 	 */
4045c51f124SMoriah Waterland 
4055c51f124SMoriah Waterland 	/* error if no subcommand specified */
4065c51f124SMoriah Waterland 
4075c51f124SMoriah Waterland 	if ((argc-optind) <= 0) {
4085c51f124SMoriah Waterland 		(void) usage(MSG_NO_ARGUMENTS_SPECIFIED);
4095c51f124SMoriah Waterland 		return (R_USAGE);
4105c51f124SMoriah Waterland 	}
4115c51f124SMoriah Waterland 
4125c51f124SMoriah Waterland 	/* parse global data if environment variable set */
4135c51f124SMoriah Waterland 
4145c51f124SMoriah Waterland 	if (parseGlobalData(PKGCOND_GLOBAL_VARIABLE, &gdt) != R_SUCCESS) {
4155c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_CANNOT_USE_GLOBAL_DATA,
4165c51f124SMoriah Waterland 			PKGCOND_GLOBAL_VARIABLE);
4175c51f124SMoriah Waterland 		return (R_ERROR);
4185c51f124SMoriah Waterland 	}
4195c51f124SMoriah Waterland 
4205c51f124SMoriah Waterland 	if (setRootPath(gdt->gd_installRoot,
4215c51f124SMoriah Waterland 	    (strcmp(gdt->gd_installRoot, "/") == 0) ? NULL :
4225c51f124SMoriah Waterland 	    ENV_VAR_SET, B_TRUE) != R_SUCCESS) {
4235c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_CANNOT_SET_ROOT_PATH,
4245c51f124SMoriah Waterland 			ENV_VAR_PKGROOT);
4255c51f124SMoriah Waterland 		return (R_ERROR);
4265c51f124SMoriah Waterland 	}
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 	/* set path provided on the command line */
4295c51f124SMoriah Waterland 
4305c51f124SMoriah Waterland 	setCmdLinePath(&(gdt->gd_cmdline_path), argv, argc);
4315c51f124SMoriah Waterland 	echoDebug(DBG_CMDLINE_PATH,
4325c51f124SMoriah Waterland 	    gdt->gd_cmdline_path == NULL ? "" : gdt->gd_cmdline_path);
4335c51f124SMoriah Waterland 
4345c51f124SMoriah Waterland 	/* determine how file systems are layered in this zone */
4355c51f124SMoriah Waterland 
4365c51f124SMoriah Waterland 	if (calculateFileSystemConfig(gdt) != R_SUCCESS) {
4375c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_CANNOT_CALC_FS_CONFIG);
4385c51f124SMoriah Waterland 		return (R_ERROR);
4395c51f124SMoriah Waterland 	}
4405c51f124SMoriah Waterland 
4415c51f124SMoriah Waterland 	/* dump global data read in (only if debugging) */
4425c51f124SMoriah Waterland 
4435c51f124SMoriah Waterland 	dumpGlobalData(gdt);
4445c51f124SMoriah Waterland 
4455c51f124SMoriah Waterland 	/* search for specified subcommand and execute if found */
4465c51f124SMoriah Waterland 
4475c51f124SMoriah Waterland 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
4485c51f124SMoriah Waterland 		if (ci_streq(argv[optind], cmds[cur_cmd].c_name)) {
4495c51f124SMoriah Waterland 			int	result;
4505c51f124SMoriah Waterland 
4515c51f124SMoriah Waterland 			/* make subcommand the first option */
4525c51f124SMoriah Waterland 
4535c51f124SMoriah Waterland 			newargc = argc - optind;
4545c51f124SMoriah Waterland 			newargv = argv + optind;
4555c51f124SMoriah Waterland 			opterr = optind = 1; optopt = 0;
4565c51f124SMoriah Waterland 
4575c51f124SMoriah Waterland 
4585c51f124SMoriah Waterland 			/* call subcommand with its own argc/argv */
4595c51f124SMoriah Waterland 
4605c51f124SMoriah Waterland 			result = cmds[cur_cmd].c_func(newargc, newargv, gdt);
4615c51f124SMoriah Waterland 
4625c51f124SMoriah Waterland 			/* process result code and exit */
4635c51f124SMoriah Waterland 
4645c51f124SMoriah Waterland 			result = adjustResults(result);
4655c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_RESULTS, result);
4665c51f124SMoriah Waterland 			return (result);
4675c51f124SMoriah Waterland 		}
4685c51f124SMoriah Waterland 	}
4695c51f124SMoriah Waterland 
4705c51f124SMoriah Waterland 	/* subcommand not found - output error message and exit with error */
4715c51f124SMoriah Waterland 
4725c51f124SMoriah Waterland 	log_msg(LOG_MSG_ERR, ERR_BAD_SUB, argv[optind]);
4735c51f124SMoriah Waterland 	(void) usage(MSG_UNRECOGNIZED_CONDITION_SPECIFIED);
4745c51f124SMoriah Waterland 	return (R_USAGE);
4755c51f124SMoriah Waterland }
4765c51f124SMoriah Waterland 
4775c51f124SMoriah Waterland /*
4785c51f124SMoriah Waterland  * *****************************************************************************
4795c51f124SMoriah Waterland  * command implementation functions
4805c51f124SMoriah Waterland  * *****************************************************************************
4815c51f124SMoriah Waterland  */
4825c51f124SMoriah Waterland 
4835c51f124SMoriah Waterland /*
4845c51f124SMoriah Waterland  * Name:	cmd_is_diskless_client
4855c51f124SMoriah Waterland  * Description:	determine if target is a diskless client
4865c51f124SMoriah Waterland  * Scope:	public
4875c51f124SMoriah Waterland  * Arguments:	argc,argv:
4885c51f124SMoriah Waterland  *		  - optional path to target to test
4895c51f124SMoriah Waterland  * Returns:	int
4905c51f124SMoriah Waterland  *			== 0 - success
4915c51f124SMoriah Waterland  *			!= 0 - failure
4925c51f124SMoriah Waterland  * IMPLEMENTATION:
4935c51f124SMoriah Waterland  *  - must not be initial installation to the install root
4945c51f124SMoriah Waterland  *  - must not be installation of a zone
4955c51f124SMoriah Waterland  *  - must not be a whole root non-global zone
4965c51f124SMoriah Waterland  *  - must not be a non-global zone
4975c51f124SMoriah Waterland  *  - must not be a mounted mini-root
4985c51f124SMoriah Waterland  *  - must not be a netinstall image
4995c51f124SMoriah Waterland  *  - must not be a boot environment
5005c51f124SMoriah Waterland  *  - The package "SUNWdclnt" must be installed at "/"
5015c51f124SMoriah Waterland  *  - The root path must not be "/"
5025c51f124SMoriah Waterland  *  - The path "/export/exec/Solaris_\*\/usr" must exist at "/"
5035c51f124SMoriah Waterland  *  - The directory "$ROOTDIR/../templates" must exist
5045c51f124SMoriah Waterland  */
5055c51f124SMoriah Waterland 
5065c51f124SMoriah Waterland static int
cmd_is_diskless_client(int argc,char ** argv,GLOBALDATA_T * a_gdt)5075c51f124SMoriah Waterland cmd_is_diskless_client(int argc, char **argv, GLOBALDATA_T *a_gdt)
5085c51f124SMoriah Waterland {
5095c51f124SMoriah Waterland 	char	*rootPath = NULL;
5105c51f124SMoriah Waterland 	char	cmd[MAXPATHLEN+1];
5115c51f124SMoriah Waterland 	int	c;
5125c51f124SMoriah Waterland 	int	r;
5135c51f124SMoriah Waterland 	int	rc;
5145c51f124SMoriah Waterland static	char	*cmdName = "is_diskless_client";
5155c51f124SMoriah Waterland static	int	recursion = 0;
5165c51f124SMoriah Waterland 
5175c51f124SMoriah Waterland 	/* process any command line options */
5185c51f124SMoriah Waterland 
5195c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
5205c51f124SMoriah Waterland 		switch (c) {
5215c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
5225c51f124SMoriah Waterland 			break;
5235c51f124SMoriah Waterland 		case '?':
5245c51f124SMoriah Waterland 		default:
5255c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
5265c51f124SMoriah Waterland 			return (R_USAGE);
5275c51f124SMoriah Waterland 		}
5285c51f124SMoriah Waterland 	}
5295c51f124SMoriah Waterland 
5305c51f124SMoriah Waterland 	/* prevent recursion */
5315c51f124SMoriah Waterland 
5325c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
5335c51f124SMoriah Waterland 
5345c51f124SMoriah Waterland 		/*
5355c51f124SMoriah Waterland 		 * a diskless client cannot be any of the following
5365c51f124SMoriah Waterland 		 */
5375c51f124SMoriah Waterland 
5386e1ae2a3SGary Pennington 		/* cannot be non-global zone */
5395c51f124SMoriah Waterland 
5405c51f124SMoriah Waterland 		r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
5415c51f124SMoriah Waterland 
5425c51f124SMoriah Waterland 		/* cannot be mounted miniroot */
5435c51f124SMoriah Waterland 
5445c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
5455c51f124SMoriah Waterland 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
5465c51f124SMoriah Waterland 		}
5475c51f124SMoriah Waterland 
5485c51f124SMoriah Waterland 		/* cannot be a netinstall image */
5495c51f124SMoriah Waterland 
5505c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
5515c51f124SMoriah Waterland 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
5525c51f124SMoriah Waterland 		}
5535c51f124SMoriah Waterland 
5545c51f124SMoriah Waterland 		/* cannot be a boot environment */
5555c51f124SMoriah Waterland 
5565c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
5575c51f124SMoriah Waterland 			r = cmd_is_boot_environment(argc, argv, a_gdt);
5585c51f124SMoriah Waterland 		}
5595c51f124SMoriah Waterland 
5605c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
5615c51f124SMoriah Waterland 
5625c51f124SMoriah Waterland 		recursion--;
5635c51f124SMoriah Waterland 
5645c51f124SMoriah Waterland 		/* return failure if any of the preceeding are true */
5655c51f124SMoriah Waterland 
5665c51f124SMoriah Waterland 		switch (r) {
5675c51f124SMoriah Waterland 			case R_SUCCESS:
5685c51f124SMoriah Waterland 				return (R_FAILURE);
5695c51f124SMoriah Waterland 			case R_FAILURE:
5705c51f124SMoriah Waterland 				break;
5715c51f124SMoriah Waterland 			case R_USAGE:
5725c51f124SMoriah Waterland 			case R_ERROR:
5735c51f124SMoriah Waterland 			default:
5745c51f124SMoriah Waterland 				return (r);
5755c51f124SMoriah Waterland 		}
5765c51f124SMoriah Waterland 	}
5775c51f124SMoriah Waterland 
5785c51f124SMoriah Waterland 	/* normalize argc/argv */
5795c51f124SMoriah Waterland 
5805c51f124SMoriah Waterland 	argc -= optind;
5815c51f124SMoriah Waterland 	argv += optind;
5825c51f124SMoriah Waterland 
5835c51f124SMoriah Waterland 	/* error if more than one argument */
5845c51f124SMoriah Waterland 
5855c51f124SMoriah Waterland 	if (argc > 1) {
5865c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
5875c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
5885c51f124SMoriah Waterland 		return (R_USAGE);
5895c51f124SMoriah Waterland 	}
5905c51f124SMoriah Waterland 
5915c51f124SMoriah Waterland 	/* process root path if first argument present */
5925c51f124SMoriah Waterland 
5935c51f124SMoriah Waterland 	if (argc == 1) {
5945c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
5955c51f124SMoriah Waterland 			return (R_ERROR);
5965c51f124SMoriah Waterland 		}
5975c51f124SMoriah Waterland 	}
5985c51f124SMoriah Waterland 
5995c51f124SMoriah Waterland 	/* get current root path */
6005c51f124SMoriah Waterland 
6015c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
6025c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
6035c51f124SMoriah Waterland 		return (r);
6045c51f124SMoriah Waterland 	}
6055c51f124SMoriah Waterland 
6065c51f124SMoriah Waterland 	/* start of command debugging information */
6075c51f124SMoriah Waterland 
6085c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
6095c51f124SMoriah Waterland 
6105c51f124SMoriah Waterland 	/* SUNWdclnt must be installed */
6115c51f124SMoriah Waterland 
6125c51f124SMoriah Waterland 	if (pkgTestInstalled("SUNWdclnt", "/") != B_TRUE) {
6135c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_PKG_NOT_INSTALLED,
6145c51f124SMoriah Waterland 			rootPath, "SUNWdclnt", "/");
6155c51f124SMoriah Waterland 		return (R_FAILURE);
6165c51f124SMoriah Waterland 	}
6175c51f124SMoriah Waterland 
6185c51f124SMoriah Waterland 	/*   - $ROOTDIR must not be "/" */
6195c51f124SMoriah Waterland 
6205c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") == 0) {
6215c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ROOTPATH_BAD, rootPath, "/");
6225c51f124SMoriah Waterland 		return (R_FAILURE);
6235c51f124SMoriah Waterland 	}
6245c51f124SMoriah Waterland 
6255c51f124SMoriah Waterland 	/*   - zone name must be global */
6265c51f124SMoriah Waterland 
6275c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
6285c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_BAD, rootPath,
6295c51f124SMoriah Waterland 			GLOBAL_ZONENAME);
6305c51f124SMoriah Waterland 		return (R_FAILURE);
6315c51f124SMoriah Waterland 	}
6325c51f124SMoriah Waterland 
6335c51f124SMoriah Waterland 	/*
6345c51f124SMoriah Waterland 	 * /export/exec/Solaris_"*"/usr must exist;
6355c51f124SMoriah Waterland 	 * create ls command to test:
6365c51f124SMoriah Waterland 	 * /usr/bin/ls /export/exec/Solaris_"*"/usr
6375c51f124SMoriah Waterland 	 */
6385c51f124SMoriah Waterland 
6395c51f124SMoriah Waterland 	(void) snprintf(cmd, sizeof (cmd), "%s %s >/dev/null 2>&1",
6405c51f124SMoriah Waterland 		LS_CMD, "/export/exec/Solaris_*/usr");
6415c51f124SMoriah Waterland 
6425c51f124SMoriah Waterland 	/* execute command */
6435c51f124SMoriah Waterland 
6445c51f124SMoriah Waterland 	rc = system(cmd);
6455c51f124SMoriah Waterland 
6465c51f124SMoriah Waterland 	/* return error if ls returns something other than "0" */
6475c51f124SMoriah Waterland 
6485c51f124SMoriah Waterland 	if (rc != 0) {
6495c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_MISSING,
6505c51f124SMoriah Waterland 			rootPath, "/export/exec/Solaris_*/usr");
6515c51f124SMoriah Waterland 		return (R_FAILURE);
6525c51f124SMoriah Waterland 	}
6535c51f124SMoriah Waterland 
6545c51f124SMoriah Waterland 	/*
6555c51f124SMoriah Waterland 	 * /usr must be empty on a diskless client:
6565c51f124SMoriah Waterland 	 * create ls command to test:
6575c51f124SMoriah Waterland 	 * /usr/bin/ls -d1 $ROOTDIR/usr/\*
6585c51f124SMoriah Waterland 	 */
6595c51f124SMoriah Waterland 	(void) snprintf(cmd, sizeof (cmd), "%s %s %s/%s >/dev/null 2>&1",
6605c51f124SMoriah Waterland 		LS_CMD, "-1d", rootPath, "usr/*");
6615c51f124SMoriah Waterland 
6625c51f124SMoriah Waterland 	/* execute command */
6635c51f124SMoriah Waterland 
6645c51f124SMoriah Waterland 	rc = system(cmd);
6655c51f124SMoriah Waterland 
6665c51f124SMoriah Waterland 	/* return error if ls returns "0" */
6675c51f124SMoriah Waterland 
6685c51f124SMoriah Waterland 	if (rc == 0) {
6695c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_USR_IS_NOT_EMPTY,
6705c51f124SMoriah Waterland 			rootPath);
6715c51f124SMoriah Waterland 		return (R_FAILURE);
6725c51f124SMoriah Waterland 	}
6735c51f124SMoriah Waterland 
6745c51f124SMoriah Waterland 	/* there must be a templates directory at ${ROOTPATH}/../templates */
6755c51f124SMoriah Waterland 
6765c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
6775c51f124SMoriah Waterland 		"%s/%s", rootPath, "../templates");
6785c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
6795c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_NO_TEMPLATES_PATH,
6805c51f124SMoriah Waterland 			rootPath, rootPath, "../templates");
6815c51f124SMoriah Waterland 		return (R_FAILURE);
6825c51f124SMoriah Waterland 	}
6835c51f124SMoriah Waterland 
6845c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
6855c51f124SMoriah Waterland 
6865c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
6875c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
6885c51f124SMoriah Waterland 		/* initial install: install root cannot be diskless client */
6895c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_INITIAL_INSTALL, rootPath);
6905c51f124SMoriah Waterland 		return (R_FAILURE);
6915c51f124SMoriah Waterland 	}
6925c51f124SMoriah Waterland 
6935c51f124SMoriah Waterland 	/* must not be installation of a zone */
6945c51f124SMoriah Waterland 
6955c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
6965c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
6975c51f124SMoriah Waterland 		/* initial zone install: no path can be diskless client */
6985c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_INSTALL, rootPath);
6995c51f124SMoriah Waterland 		return (R_FAILURE);
7005c51f124SMoriah Waterland 	}
7015c51f124SMoriah Waterland 
7025c51f124SMoriah Waterland 	/* the path is a diskless client */
7035c51f124SMoriah Waterland 
7045c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_IS_DISKLESS_CLIENT, rootPath);
7055c51f124SMoriah Waterland 
7065c51f124SMoriah Waterland 	return (R_SUCCESS);
7075c51f124SMoriah Waterland }
7085c51f124SMoriah Waterland 
7095c51f124SMoriah Waterland /*
7105c51f124SMoriah Waterland  * Name:	cmd_is_global_zone
7115c51f124SMoriah Waterland  * Description:	determine if target is a global zone
7125c51f124SMoriah Waterland  * Scope:	public
7135c51f124SMoriah Waterland  * Arguments:	argc,argv:
7145c51f124SMoriah Waterland  *		  - optional path to target to test
7155c51f124SMoriah Waterland  * Returns:	int
7165c51f124SMoriah Waterland  *			== 0 - success
7175c51f124SMoriah Waterland  *			!= 0 - failure
7185c51f124SMoriah Waterland  * IMPLEMENTATION:
7195c51f124SMoriah Waterland  *  - must not be initial installation to the install root
7205c51f124SMoriah Waterland  *  - must not be installation of a non-global zone
7215c51f124SMoriah Waterland  *  - must not be a non-global zone
7225c51f124SMoriah Waterland  *  - must not be a mounted mini-root
7235c51f124SMoriah Waterland  *  - must not be a netinstall image
7245c51f124SMoriah Waterland  *  - must not be a diskless client
7255c51f124SMoriah Waterland  *  - if $ROOTDIR is "/":
7265c51f124SMoriah Waterland  *  -- if zone name is "GLOBAL", then is a global zone;
7275c51f124SMoriah Waterland  *  -- else not a global zone.
7285c51f124SMoriah Waterland  *  - $ROOTDIR/etc/zones must exist and be a directory
7295c51f124SMoriah Waterland  *  - $ROOTDIR/.tmp_proto must not exist
7305c51f124SMoriah Waterland  *  - $ROOTDIR/var must exist and must not be a symbolic link
7315c51f124SMoriah Waterland  */
7325c51f124SMoriah Waterland 
7335c51f124SMoriah Waterland static int
cmd_is_global_zone(int argc,char ** argv,GLOBALDATA_T * a_gdt)7345c51f124SMoriah Waterland cmd_is_global_zone(int argc, char **argv, GLOBALDATA_T *a_gdt)
7355c51f124SMoriah Waterland {
7365c51f124SMoriah Waterland 	char	*rootPath = NULL;
7375c51f124SMoriah Waterland 	int	c;
7385c51f124SMoriah Waterland 	int	r;
7395c51f124SMoriah Waterland static	char	*cmdName = "is_global_zone";
7405c51f124SMoriah Waterland static	int	recursion = 0;
7415c51f124SMoriah Waterland 
7425c51f124SMoriah Waterland 	/* process any command line options */
7435c51f124SMoriah Waterland 
7445c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
7455c51f124SMoriah Waterland 		switch (c) {
7465c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
7475c51f124SMoriah Waterland 			break;
7485c51f124SMoriah Waterland 		case '?':
7495c51f124SMoriah Waterland 		default:
7505c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
7515c51f124SMoriah Waterland 			return (R_USAGE);
7525c51f124SMoriah Waterland 		}
7535c51f124SMoriah Waterland 	}
7545c51f124SMoriah Waterland 
7555c51f124SMoriah Waterland 	/* prevent recursion */
7565c51f124SMoriah Waterland 
7575c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
7585c51f124SMoriah Waterland 
7595c51f124SMoriah Waterland 		/*
7605c51f124SMoriah Waterland 		 * a global zone cannot be any of the following
7615c51f124SMoriah Waterland 		 */
7625c51f124SMoriah Waterland 
7635c51f124SMoriah Waterland 		/* cannot be a non-global zone */
7645c51f124SMoriah Waterland 
7655c51f124SMoriah Waterland 		r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
7665c51f124SMoriah Waterland 
7675c51f124SMoriah Waterland 		/* cannot be a mounted miniroot */
7685c51f124SMoriah Waterland 
7695c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
7705c51f124SMoriah Waterland 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
7715c51f124SMoriah Waterland 		}
7725c51f124SMoriah Waterland 
7735c51f124SMoriah Waterland 		/* cannot be a netinstall image */
7745c51f124SMoriah Waterland 
7755c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
7765c51f124SMoriah Waterland 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
7775c51f124SMoriah Waterland 		}
7785c51f124SMoriah Waterland 
7795c51f124SMoriah Waterland 		/* cannot be a diskless client */
7805c51f124SMoriah Waterland 
7815c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
7825c51f124SMoriah Waterland 			r = cmd_is_diskless_client(argc, argv, a_gdt);
7835c51f124SMoriah Waterland 		}
7845c51f124SMoriah Waterland 
7855c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
7865c51f124SMoriah Waterland 
7875c51f124SMoriah Waterland 		recursion--;
7885c51f124SMoriah Waterland 
7895c51f124SMoriah Waterland 		/* return failure if any of the preceeding are true */
7905c51f124SMoriah Waterland 
7915c51f124SMoriah Waterland 		switch (r) {
7925c51f124SMoriah Waterland 			case R_SUCCESS:
7935c51f124SMoriah Waterland 				return (R_FAILURE);
7945c51f124SMoriah Waterland 			case R_FAILURE:
7955c51f124SMoriah Waterland 				break;
7965c51f124SMoriah Waterland 			case R_USAGE:
7975c51f124SMoriah Waterland 			case R_ERROR:
7985c51f124SMoriah Waterland 			default:
7995c51f124SMoriah Waterland 				return (r);
8005c51f124SMoriah Waterland 		}
8015c51f124SMoriah Waterland 	}
8025c51f124SMoriah Waterland 
8035c51f124SMoriah Waterland 	/* normalize argc/argv */
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 	argc -= optind;
8065c51f124SMoriah Waterland 	argv += optind;
8075c51f124SMoriah Waterland 
8085c51f124SMoriah Waterland 	/* error if more than one argument */
8095c51f124SMoriah Waterland 
8105c51f124SMoriah Waterland 	if (argc > 1) {
8115c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
8125c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
8135c51f124SMoriah Waterland 		return (R_USAGE);
8145c51f124SMoriah Waterland 	}
8155c51f124SMoriah Waterland 
8165c51f124SMoriah Waterland 	/* process root path if first argument present */
8175c51f124SMoriah Waterland 
8185c51f124SMoriah Waterland 	if (argc == 1) {
8195c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
8205c51f124SMoriah Waterland 			return (R_ERROR);
8215c51f124SMoriah Waterland 		}
8225c51f124SMoriah Waterland 	}
8235c51f124SMoriah Waterland 
8245c51f124SMoriah Waterland 	/* get current root path */
8255c51f124SMoriah Waterland 
8265c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
8275c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
8285c51f124SMoriah Waterland 		return (r);
8295c51f124SMoriah Waterland 	}
8305c51f124SMoriah Waterland 
8315c51f124SMoriah Waterland 	/* start of command debugging information */
8325c51f124SMoriah Waterland 
8335c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
8345c51f124SMoriah Waterland 
8355c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
8365c51f124SMoriah Waterland 
8375c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
8385c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
8395c51f124SMoriah Waterland 		/* initial install: install root cannot be global zone */
8405c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_INITIAL_INSTALL, rootPath);
8415c51f124SMoriah Waterland 		return (R_FAILURE);
8425c51f124SMoriah Waterland 	}
8435c51f124SMoriah Waterland 
8445c51f124SMoriah Waterland 	/* must not be installation of a non-global zone */
8455c51f124SMoriah Waterland 
8465c51f124SMoriah Waterland 	if (a_gdt->gd_nonglobalZoneInstall == B_TRUE) {
8475c51f124SMoriah Waterland 		/* initial nonglobal zone install: no path can be global zone */
8485c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_NGZ_ZONE_INSTALL, rootPath);
8495c51f124SMoriah Waterland 		return (R_FAILURE);
8505c51f124SMoriah Waterland 	}
8515c51f124SMoriah Waterland 
8525c51f124SMoriah Waterland 	/* handle if global zone installation to the install root */
8535c51f124SMoriah Waterland 
8545c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) &&
8555c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
8565c51f124SMoriah Waterland 			/* the path is a global zone */
8575c51f124SMoriah Waterland 
8585c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE,
8595c51f124SMoriah Waterland 				rootPath);
8605c51f124SMoriah Waterland 
8615c51f124SMoriah Waterland 			return (R_SUCCESS);
8625c51f124SMoriah Waterland 	}
8635c51f124SMoriah Waterland 
8645c51f124SMoriah Waterland 	/* true if current root is "/" and zone name is GLOBAL_ZONENAME */
8655c51f124SMoriah Waterland 
8665c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") == 0) {
8675c51f124SMoriah Waterland 		if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
8685c51f124SMoriah Waterland 			/* the path is a global zone */
8695c51f124SMoriah Waterland 
8705c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE,
8715c51f124SMoriah Waterland 				rootPath);
8725c51f124SMoriah Waterland 
8735c51f124SMoriah Waterland 			return (R_SUCCESS);
8745c51f124SMoriah Waterland 		}
8755c51f124SMoriah Waterland 
8765c51f124SMoriah Waterland 		/* inside a non-global zone */
8775c51f124SMoriah Waterland 
8785c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_ZONENAME_ISNT_GLOBAL,
8795c51f124SMoriah Waterland 			rootPath, a_gdt->gd_zoneName);
8805c51f124SMoriah Waterland 
8815c51f124SMoriah Waterland 		return (R_FAILURE);
8825c51f124SMoriah Waterland 	}
8835c51f124SMoriah Waterland 
8845c51f124SMoriah Waterland 	/*
8855c51f124SMoriah Waterland 	 * current root is not "/" - see if target looks like a global zone
8865c51f124SMoriah Waterland 	 *
8875c51f124SMoriah Waterland 	 * - rootpath is not "/"
8885c51f124SMoriah Waterland 	 * - and $ROOTDIR/etc/zones exists
8895c51f124SMoriah Waterland 	 * - and $ROOTDIR/.tmp_proto does not exist
8905c51f124SMoriah Waterland 	 * - and $ROOTDIR/var is not a symbolic link
8915c51f124SMoriah Waterland 	 */
8925c51f124SMoriah Waterland 
8935c51f124SMoriah Waterland 	/* not global zone if /etc/zones does not exist */
8945c51f124SMoriah Waterland 
8955c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
8965c51f124SMoriah Waterland 		"%s/%s", rootPath, "/etc/zones");
8975c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
8985c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_ISNT_DIRECTORY,
8995c51f124SMoriah Waterland 			rootPath, "/etc/zones");
9005c51f124SMoriah Waterland 		return (R_FAILURE);
9015c51f124SMoriah Waterland 	}
9025c51f124SMoriah Waterland 
9035c51f124SMoriah Waterland 	/* .tmp_proto must not exist */
9045c51f124SMoriah Waterland 
9055c51f124SMoriah Waterland 	r = testPath(TEST_NOT_EXISTS,
9065c51f124SMoriah Waterland 		"%s/%s", rootPath, ".tmp_proto");
9075c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
9085c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_EXISTS,
9095c51f124SMoriah Waterland 			rootPath, "/.tmp_proto");
9105c51f124SMoriah Waterland 		return (R_FAILURE);
9115c51f124SMoriah Waterland 	}
9125c51f124SMoriah Waterland 
9135c51f124SMoriah Waterland 	/* /var must not be a symbolic link */
9145c51f124SMoriah Waterland 
9155c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
9165c51f124SMoriah Waterland 		"%s/%s", rootPath, "/var");
9175c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
9185c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_SYMLINK,
9195c51f124SMoriah Waterland 			rootPath, "/var");
9205c51f124SMoriah Waterland 		return (R_FAILURE);
9215c51f124SMoriah Waterland 	}
9225c51f124SMoriah Waterland 
9235c51f124SMoriah Waterland 	/* the path is a global zone */
9245c51f124SMoriah Waterland 
9255c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, rootPath);
9265c51f124SMoriah Waterland 
9275c51f124SMoriah Waterland 	return (R_SUCCESS);
9285c51f124SMoriah Waterland }
9295c51f124SMoriah Waterland 
9305c51f124SMoriah Waterland /*
9315c51f124SMoriah Waterland  * Name:	cmd_is_netinstall_image
9325c51f124SMoriah Waterland  * Description:	determine if target is a net install image
9335c51f124SMoriah Waterland  * Scope:	public
9345c51f124SMoriah Waterland  * Arguments:	argc,argv:
9355c51f124SMoriah Waterland  *		  - optional path to target to test
9365c51f124SMoriah Waterland  * Returns:	int
9375c51f124SMoriah Waterland  *			== 0 - success
9385c51f124SMoriah Waterland  *			!= 0 - failure
9395c51f124SMoriah Waterland  * IMPLEMENTATION:
9405c51f124SMoriah Waterland  *  - must not be initial installation to the install root
9415c51f124SMoriah Waterland  *  - must not be installation of a zone
9425c51f124SMoriah Waterland  *  - must not be a global zone
9435c51f124SMoriah Waterland  *  - must not be a mounted mini-root
9445c51f124SMoriah Waterland  *  - zone name must be "global"
9455c51f124SMoriah Waterland  *  - $ROOTDIR/.tmp_proto must exist and must be a directory
9465c51f124SMoriah Waterland  *  - $ROOTDIR/var must exist and must be a symbolic link
9475c51f124SMoriah Waterland  *  - $ROOTDIR/tmp/kernel must exist and must be a directory
9485c51f124SMoriah Waterland  *  - $ROOTDIR/.tmp_proto/kernel must exist and must be a symbolic link
9495c51f124SMoriah Waterland  */
9505c51f124SMoriah Waterland 
9515c51f124SMoriah Waterland static int
cmd_is_netinstall_image(int argc,char ** argv,GLOBALDATA_T * a_gdt)9525c51f124SMoriah Waterland cmd_is_netinstall_image(int argc, char **argv, GLOBALDATA_T *a_gdt)
9535c51f124SMoriah Waterland {
9545c51f124SMoriah Waterland 	char	*rootPath = NULL;
9555c51f124SMoriah Waterland 	int	c;
9565c51f124SMoriah Waterland 	int	r;
9575c51f124SMoriah Waterland static	char	*cmdName = "is_netinstall_image";
9585c51f124SMoriah Waterland static	int	recursion = 0;
9595c51f124SMoriah Waterland 
9605c51f124SMoriah Waterland 	/* process any command line options */
9615c51f124SMoriah Waterland 
9625c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
9635c51f124SMoriah Waterland 		switch (c) {
9645c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
9655c51f124SMoriah Waterland 			break;
9665c51f124SMoriah Waterland 		case '?':
9675c51f124SMoriah Waterland 		default:
9685c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
9695c51f124SMoriah Waterland 			return (R_USAGE);
9705c51f124SMoriah Waterland 		}
9715c51f124SMoriah Waterland 	}
9725c51f124SMoriah Waterland 
9735c51f124SMoriah Waterland 	/* prevent recursion */
9745c51f124SMoriah Waterland 
9755c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
9765c51f124SMoriah Waterland 
9775c51f124SMoriah Waterland 		/* a netinstall image cannot be a global zone */
9785c51f124SMoriah Waterland 
9795c51f124SMoriah Waterland 		r = cmd_is_global_zone(argc, argv, a_gdt);
9805c51f124SMoriah Waterland 
9815c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
9825c51f124SMoriah Waterland 
9835c51f124SMoriah Waterland 		recursion--;
9845c51f124SMoriah Waterland 
9855c51f124SMoriah Waterland 		switch (r) {
9865c51f124SMoriah Waterland 			case R_SUCCESS:
9875c51f124SMoriah Waterland 				return (R_FAILURE);
9885c51f124SMoriah Waterland 			case R_FAILURE:
9895c51f124SMoriah Waterland 				break;
9905c51f124SMoriah Waterland 			case R_USAGE:
9915c51f124SMoriah Waterland 			case R_ERROR:
9925c51f124SMoriah Waterland 			default:
9935c51f124SMoriah Waterland 				return (r);
9945c51f124SMoriah Waterland 		}
9955c51f124SMoriah Waterland 	}
9965c51f124SMoriah Waterland 
9975c51f124SMoriah Waterland 	/* normalize argc/argv */
9985c51f124SMoriah Waterland 
9995c51f124SMoriah Waterland 	argc -= optind;
10005c51f124SMoriah Waterland 	argv += optind;
10015c51f124SMoriah Waterland 
10025c51f124SMoriah Waterland 	/* error if more than one argument */
10035c51f124SMoriah Waterland 
10045c51f124SMoriah Waterland 	if (argc > 1) {
10055c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
10065c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
10075c51f124SMoriah Waterland 		return (R_USAGE);
10085c51f124SMoriah Waterland 	}
10095c51f124SMoriah Waterland 
10105c51f124SMoriah Waterland 	/* process root path if first argument present */
10115c51f124SMoriah Waterland 
10125c51f124SMoriah Waterland 	if (argc == 1) {
10135c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
10145c51f124SMoriah Waterland 			return (R_ERROR);
10155c51f124SMoriah Waterland 		}
10165c51f124SMoriah Waterland 	}
10175c51f124SMoriah Waterland 
10185c51f124SMoriah Waterland 	/* get current root path */
10195c51f124SMoriah Waterland 
10205c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
10215c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
10225c51f124SMoriah Waterland 		return (r);
10235c51f124SMoriah Waterland 	}
10245c51f124SMoriah Waterland 
10255c51f124SMoriah Waterland 	/* start of command debugging information */
10265c51f124SMoriah Waterland 
10275c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
10285c51f124SMoriah Waterland 
10295c51f124SMoriah Waterland 	/* current zone name must be "global" */
10305c51f124SMoriah Waterland 
10315c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
10325c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_BAD_CURRENT_ZONE,
10335c51f124SMoriah Waterland 			rootPath, GLOBAL_ZONENAME);
10345c51f124SMoriah Waterland 		return (R_FAILURE);
10355c51f124SMoriah Waterland 	}
10365c51f124SMoriah Waterland 
10375c51f124SMoriah Waterland 	/* cannot be a mounted_miniroot */
10385c51f124SMoriah Waterland 
10395c51f124SMoriah Waterland 	if (cmd_is_mounted_miniroot(argc, argv, a_gdt) == R_SUCCESS) {
10405c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT,
10415c51f124SMoriah Waterland 			rootPath);
10425c51f124SMoriah Waterland 		return (R_FAILURE);
10435c51f124SMoriah Waterland 	}
10445c51f124SMoriah Waterland 
10455c51f124SMoriah Waterland 	/* $ROOTDIR/.tmp_proto exists */
10465c51f124SMoriah Waterland 
10475c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
10485c51f124SMoriah Waterland 		"%s/%s", rootPath, ".tmp_proto");
10495c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
10505c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY,
10515c51f124SMoriah Waterland 			rootPath, "/.tmp_proto");
10525c51f124SMoriah Waterland 		return (R_FAILURE);
10535c51f124SMoriah Waterland 	}
10545c51f124SMoriah Waterland 
10555c51f124SMoriah Waterland 	/* $ROOTDIR/var is a symbolic link */
10565c51f124SMoriah Waterland 
10575c51f124SMoriah Waterland 	r = testPath(TEST_IS_SYMBOLIC_LINK,
10585c51f124SMoriah Waterland 		"%s/%s", rootPath, "/var");
10595c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
10605c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK,
10615c51f124SMoriah Waterland 			rootPath, "/var");
10625c51f124SMoriah Waterland 		return (R_FAILURE);
10635c51f124SMoriah Waterland 	}
10645c51f124SMoriah Waterland 
10655c51f124SMoriah Waterland 	/* $ROOTDIR/tmp/kernel does exist */
10665c51f124SMoriah Waterland 
10675c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
10685c51f124SMoriah Waterland 		"%s/%s", rootPath, "/tmp/kernel");
10695c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
10705c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY,
10715c51f124SMoriah Waterland 			rootPath, "/tmp/kernel");
10725c51f124SMoriah Waterland 		return (R_FAILURE);
10735c51f124SMoriah Waterland 	}
10745c51f124SMoriah Waterland 
10755c51f124SMoriah Waterland 	/* $ROOTDIR/.tmp_proto/kernel is a symbolic link */
10765c51f124SMoriah Waterland 
10775c51f124SMoriah Waterland 	r = testPath(TEST_IS_SYMBOLIC_LINK,
10785c51f124SMoriah Waterland 		"%s/%s", rootPath, "/.tmp_proto/kernel");
10795c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
10805c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK,
10815c51f124SMoriah Waterland 			rootPath, "/.tmp_proto/kernel");
10825c51f124SMoriah Waterland 		return (R_FAILURE);
10835c51f124SMoriah Waterland 	}
10845c51f124SMoriah Waterland 
10855c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
10865c51f124SMoriah Waterland 
10875c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
10885c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
10895c51f124SMoriah Waterland 		/* initial install: install root cannot be netinstall image */
10905c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_INITIAL_INSTALL, rootPath);
10915c51f124SMoriah Waterland 		return (R_FAILURE);
10925c51f124SMoriah Waterland 	}
10935c51f124SMoriah Waterland 
10945c51f124SMoriah Waterland 	/* must not be installation of a zone */
10955c51f124SMoriah Waterland 
10965c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
10975c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
10985c51f124SMoriah Waterland 		/* initial zone install: no path can be netinstall image */
10995c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_INIM_ZONE_INSTALL, rootPath);
11005c51f124SMoriah Waterland 		return (R_FAILURE);
11015c51f124SMoriah Waterland 	}
11025c51f124SMoriah Waterland 
11035c51f124SMoriah Waterland 	/* target is a netinstall image */
11045c51f124SMoriah Waterland 
11055c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_IS_NETINSTALL_IMAGE, rootPath);
11065c51f124SMoriah Waterland 
11075c51f124SMoriah Waterland 	return (R_SUCCESS);
11085c51f124SMoriah Waterland }
11095c51f124SMoriah Waterland 
11105c51f124SMoriah Waterland /*
11115c51f124SMoriah Waterland  * Name:	cmd_is_mounted_miniroot
11125c51f124SMoriah Waterland  * Description:	determine if target is a mounted miniroot image
11135c51f124SMoriah Waterland  * Scope:	public
11145c51f124SMoriah Waterland  * Arguments:	argc,argv:
11155c51f124SMoriah Waterland  *		  - optional path to target to test
11165c51f124SMoriah Waterland  * Returns:	int
11175c51f124SMoriah Waterland  *			== 0 - success
11185c51f124SMoriah Waterland  *			!= 0 - failure
11195c51f124SMoriah Waterland  * IMPLEMENTATION:
11205c51f124SMoriah Waterland  *  - must not be initial installation to the install root
11215c51f124SMoriah Waterland  *  - must not be installation of a zone
11225c51f124SMoriah Waterland  *  - zone name must be "global"
11235c51f124SMoriah Waterland  *  - $ROOTDIR/tmp/kernel must exist and must be a symbolic link
11245c51f124SMoriah Waterland  *  - $ROOTDIR/tmp/root/kernel must exist and must be a directory
11255c51f124SMoriah Waterland  */
11265c51f124SMoriah Waterland 
11275c51f124SMoriah Waterland static int
cmd_is_mounted_miniroot(int argc,char ** argv,GLOBALDATA_T * a_gdt)11285c51f124SMoriah Waterland cmd_is_mounted_miniroot(int argc, char **argv, GLOBALDATA_T *a_gdt)
11295c51f124SMoriah Waterland {
11305c51f124SMoriah Waterland 	char	*rootPath = NULL;
11315c51f124SMoriah Waterland 	int	c;
11325c51f124SMoriah Waterland 	int	r;
11335c51f124SMoriah Waterland static	char	*cmdName = "is_mounted_miniroot";
11345c51f124SMoriah Waterland static	int	recursion = 0;
11355c51f124SMoriah Waterland 
11365c51f124SMoriah Waterland 	/* process any command line options */
11375c51f124SMoriah Waterland 
11385c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
11395c51f124SMoriah Waterland 		switch (c) {
11405c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
11415c51f124SMoriah Waterland 			break;
11425c51f124SMoriah Waterland 		case '?':
11435c51f124SMoriah Waterland 		default:
11445c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
11455c51f124SMoriah Waterland 			return (R_USAGE);
11465c51f124SMoriah Waterland 		}
11475c51f124SMoriah Waterland 	}
11485c51f124SMoriah Waterland 
11495c51f124SMoriah Waterland 	/* prevent recursion */
11505c51f124SMoriah Waterland 
11515c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
11525c51f124SMoriah Waterland 		recursion--;
11535c51f124SMoriah Waterland 	}
11545c51f124SMoriah Waterland 
11555c51f124SMoriah Waterland 	/* normalize argc/argv */
11565c51f124SMoriah Waterland 
11575c51f124SMoriah Waterland 	argc -= optind;
11585c51f124SMoriah Waterland 	argv += optind;
11595c51f124SMoriah Waterland 
11605c51f124SMoriah Waterland 	/* error if more than one argument */
11615c51f124SMoriah Waterland 
11625c51f124SMoriah Waterland 	if (argc > 1) {
11635c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
11645c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
11655c51f124SMoriah Waterland 		return (R_USAGE);
11665c51f124SMoriah Waterland 	}
11675c51f124SMoriah Waterland 
11685c51f124SMoriah Waterland 	/* process root path if first argument present */
11695c51f124SMoriah Waterland 
11705c51f124SMoriah Waterland 	if (argc == 1) {
11715c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
11725c51f124SMoriah Waterland 			return (R_ERROR);
11735c51f124SMoriah Waterland 		}
11745c51f124SMoriah Waterland 	}
11755c51f124SMoriah Waterland 
11765c51f124SMoriah Waterland 	/* get current root path */
11775c51f124SMoriah Waterland 
11785c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
11795c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
11805c51f124SMoriah Waterland 		return (r);
11815c51f124SMoriah Waterland 	}
11825c51f124SMoriah Waterland 
11835c51f124SMoriah Waterland 	/* start of command debugging information */
11845c51f124SMoriah Waterland 
11855c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
11865c51f124SMoriah Waterland 
11875c51f124SMoriah Waterland 	/* current zone name must be "global" */
11885c51f124SMoriah Waterland 
11895c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
11905c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_BAD_CURRENT_ZONE,
11915c51f124SMoriah Waterland 			rootPath, GLOBAL_ZONENAME);
11925c51f124SMoriah Waterland 		return (R_FAILURE);
11935c51f124SMoriah Waterland 	}
11945c51f124SMoriah Waterland 
11955c51f124SMoriah Waterland 	/* $ROOTDIR/tmp/kernel is a symbolic link */
11965c51f124SMoriah Waterland 
11975c51f124SMoriah Waterland 	r = testPath(TEST_IS_SYMBOLIC_LINK,
11985c51f124SMoriah Waterland 		"%s/%s", rootPath, "/tmp/kernel");
11995c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
12005c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_SYMLINK,
12015c51f124SMoriah Waterland 			rootPath, "/tmp/kernel");
12025c51f124SMoriah Waterland 		return (R_FAILURE);
12035c51f124SMoriah Waterland 	}
12045c51f124SMoriah Waterland 
12055c51f124SMoriah Waterland 	/* $ROOTDIR/tmp/root/kernel is a directory */
12065c51f124SMoriah Waterland 
12075c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
12085c51f124SMoriah Waterland 		"%s/%s", rootPath, "/tmp/root/kernel");
12095c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
12105c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_DIRECTORY,
12115c51f124SMoriah Waterland 			rootPath, "/tmp/root/kernel");
12125c51f124SMoriah Waterland 		return (R_FAILURE);
12135c51f124SMoriah Waterland 	}
12145c51f124SMoriah Waterland 
12155c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
12165c51f124SMoriah Waterland 
12175c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
12185c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
12195c51f124SMoriah Waterland 		/* initial install: install root cannot be mounted miniroot */
12205c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_INITIAL_INSTALL, rootPath);
12215c51f124SMoriah Waterland 		return (R_FAILURE);
12225c51f124SMoriah Waterland 	}
12235c51f124SMoriah Waterland 
12245c51f124SMoriah Waterland 	/* must not be installation of a zone */
12255c51f124SMoriah Waterland 
12265c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
12275c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
12285c51f124SMoriah Waterland 		/* initial zone install: no path can be mounted miniroot */
12295c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_ZONE_INSTALL, rootPath);
12305c51f124SMoriah Waterland 		return (R_FAILURE);
12315c51f124SMoriah Waterland 	}
12325c51f124SMoriah Waterland 
12335c51f124SMoriah Waterland 	/* target is a mounted miniroot */
12345c51f124SMoriah Waterland 
12355c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT, rootPath);
12365c51f124SMoriah Waterland 
12375c51f124SMoriah Waterland 	return (R_SUCCESS);
12385c51f124SMoriah Waterland }
12395c51f124SMoriah Waterland 
12405c51f124SMoriah Waterland /*
12415c51f124SMoriah Waterland  * Name:	cmd_is_nonglobal_zone
12425c51f124SMoriah Waterland  * Description:	determine if target is a global zone
12435c51f124SMoriah Waterland  * Scope:	public
12445c51f124SMoriah Waterland  * Arguments:	argc,argv:
12455c51f124SMoriah Waterland  *		  - optional path to target to test
12465c51f124SMoriah Waterland  * Returns:	int
12475c51f124SMoriah Waterland  *			== 0 - success
12485c51f124SMoriah Waterland  *			!= 0 - failure
12495c51f124SMoriah Waterland  *  - must not be initial installation to the install root
12505c51f124SMoriah Waterland  *  - must not be installation of a global zone
12515c51f124SMoriah Waterland  *  - success if installation of a non-global zone
12525c51f124SMoriah Waterland  */
12535c51f124SMoriah Waterland 
12545c51f124SMoriah Waterland static int
cmd_is_nonglobal_zone(int argc,char ** argv,GLOBALDATA_T * a_gdt)12555c51f124SMoriah Waterland cmd_is_nonglobal_zone(int argc, char **argv, GLOBALDATA_T *a_gdt)
12565c51f124SMoriah Waterland {
12575c51f124SMoriah Waterland 	char	*rootPath = NULL;
12585c51f124SMoriah Waterland 	int	c;
12595c51f124SMoriah Waterland 	int	r;
12605c51f124SMoriah Waterland static	char	*cmdName = "is_nonglobal_zone";
12615c51f124SMoriah Waterland static	int	recursion = 0;
12625c51f124SMoriah Waterland 
12635c51f124SMoriah Waterland 	/* process any command line options */
12645c51f124SMoriah Waterland 
12655c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
12665c51f124SMoriah Waterland 		switch (c) {
12675c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
12685c51f124SMoriah Waterland 			break;
12695c51f124SMoriah Waterland 		case '?':
12705c51f124SMoriah Waterland 		default:
12715c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
12725c51f124SMoriah Waterland 			return (R_USAGE);
12735c51f124SMoriah Waterland 		}
12745c51f124SMoriah Waterland 	}
12755c51f124SMoriah Waterland 
12765c51f124SMoriah Waterland 	/* prevent recursion */
12775c51f124SMoriah Waterland 
12785c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
12795c51f124SMoriah Waterland 		recursion--;
12805c51f124SMoriah Waterland 	}
12815c51f124SMoriah Waterland 
12825c51f124SMoriah Waterland 	/* normalize argc/argv */
12835c51f124SMoriah Waterland 
12845c51f124SMoriah Waterland 	argc -= optind;
12855c51f124SMoriah Waterland 	argv += optind;
12865c51f124SMoriah Waterland 
12875c51f124SMoriah Waterland 	/* error if more than one argument */
12885c51f124SMoriah Waterland 
12895c51f124SMoriah Waterland 	if (argc > 1) {
12905c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
12915c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
12925c51f124SMoriah Waterland 		return (R_USAGE);
12935c51f124SMoriah Waterland 	}
12945c51f124SMoriah Waterland 
12955c51f124SMoriah Waterland 	/* process root path if first argument present */
12965c51f124SMoriah Waterland 
12975c51f124SMoriah Waterland 	if (argc == 1) {
12985c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
12995c51f124SMoriah Waterland 			return (R_ERROR);
13005c51f124SMoriah Waterland 		}
13015c51f124SMoriah Waterland 	}
13025c51f124SMoriah Waterland 
13035c51f124SMoriah Waterland 	/* get current root path */
13045c51f124SMoriah Waterland 
13055c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
13065c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
13075c51f124SMoriah Waterland 		return (r);
13085c51f124SMoriah Waterland 	}
13095c51f124SMoriah Waterland 
13105c51f124SMoriah Waterland 	/* start of command debugging information */
13115c51f124SMoriah Waterland 
13125c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
13135c51f124SMoriah Waterland 
13145c51f124SMoriah Waterland 	/* handle if non-global zone installation to the install root */
13155c51f124SMoriah Waterland 
13165c51f124SMoriah Waterland 	if ((a_gdt->gd_nonglobalZoneInstall == B_TRUE) &&
13175c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
13185c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_INSTALL_ZONENAME_IS_NGZ,
13195c51f124SMoriah Waterland 			rootPath, a_gdt->gd_zoneName);
13205c51f124SMoriah Waterland 		return (R_SUCCESS);
13215c51f124SMoriah Waterland 	}
13225c51f124SMoriah Waterland 
13235c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
13245c51f124SMoriah Waterland 
13255c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
13265c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
13275c51f124SMoriah Waterland 		/* initial install: install root cannot be non-global zone */
13285c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_INITIAL_INSTALL, rootPath);
13295c51f124SMoriah Waterland 		return (R_FAILURE);
13305c51f124SMoriah Waterland 	}
13315c51f124SMoriah Waterland 
13325c51f124SMoriah Waterland 	/* must not be installation of a global zone */
13335c51f124SMoriah Waterland 
13345c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
13355c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
13365c51f124SMoriah Waterland 		/* initial global zone install: no path can be nonglobal zone */
13375c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_GLOBAL_ZONE_INSTALL, rootPath);
13385c51f124SMoriah Waterland 		return (R_FAILURE);
13395c51f124SMoriah Waterland 	}
13405c51f124SMoriah Waterland 
13415c51f124SMoriah Waterland 	/*
13425c51f124SMoriah Waterland 	 * *********************************************************************
13435c51f124SMoriah Waterland 	 * if root directory is "/" then the only thing that needs to be done is
13445c51f124SMoriah Waterland 	 * to test the zone name directly - if the zone name is "global" then
13455c51f124SMoriah Waterland 	 * the target is not a non-global zone; otherwise if the zone name is
13465c51f124SMoriah Waterland 	 * not "global" then the target IS a non-global zone.
13475c51f124SMoriah Waterland 	 * *********************************************************************
13485c51f124SMoriah Waterland 	 */
13495c51f124SMoriah Waterland 
13505c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") == 0) {
13515c51f124SMoriah Waterland 		/* target is current running root */
13525c51f124SMoriah Waterland 		if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
13535c51f124SMoriah Waterland 			/* in the global zone */
13545c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ,
13555c51f124SMoriah Waterland 				rootPath, a_gdt->gd_zoneName);
13565c51f124SMoriah Waterland 			return (R_FAILURE);
13575c51f124SMoriah Waterland 		}
13585c51f124SMoriah Waterland 		/* in a non-global zone */
13595c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_IS_NGZ,
13605c51f124SMoriah Waterland 			rootPath, a_gdt->gd_zoneName);
13615c51f124SMoriah Waterland 		return (R_SUCCESS);
13625c51f124SMoriah Waterland 	}
13635c51f124SMoriah Waterland 
13645c51f124SMoriah Waterland 	/*
13655c51f124SMoriah Waterland 	 * $ROOTDIR/etc/zones/index must exist in a global zone. It also
13665c51f124SMoriah Waterland 	 * exists in a non-global zone after s10u4 but we can't check that
13675c51f124SMoriah Waterland 	 * since it is undeterministic for all releases so we only check
13685c51f124SMoriah Waterland 	 * for the global zone here.
13695c51f124SMoriah Waterland 	 */
13705c51f124SMoriah Waterland 
13715c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/zones/index");
13725c51f124SMoriah Waterland 	if (r == R_SUCCESS) {
13735c51f124SMoriah Waterland 
13745c51f124SMoriah Waterland 		/* See if "global" exists in .../etc/zones/index */
13755c51f124SMoriah Waterland 
13765c51f124SMoriah Waterland 		if (testPath(TEST_GLOBAL_TOKEN_IN_FILE, "%s/%s", rootPath,
13775c51f124SMoriah Waterland 		    "/etc/zones/index") != R_SUCCESS) {
13785c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ,
13795c51f124SMoriah Waterland 			    rootPath, GLOBAL_ZONENAME);
13805c51f124SMoriah Waterland 			return (R_FAILURE);
13815c51f124SMoriah Waterland 		}
13825c51f124SMoriah Waterland 	}
13835c51f124SMoriah Waterland 
13845c51f124SMoriah Waterland 	/*
13855c51f124SMoriah Waterland 	 * *********************************************************************
13865c51f124SMoriah Waterland 	 * If the root directory is "/" then you can use only the zone
13875c51f124SMoriah Waterland 	 * name to determine if the zone is non-global or not since the
13885c51f124SMoriah Waterland 	 * package is being installed or removed to the current "zone".
13895c51f124SMoriah Waterland 	 *
13905c51f124SMoriah Waterland 	 * Since the root directory being tested is not "/" then you have to
13915c51f124SMoriah Waterland 	 * look into the target to try and infer zone type using means other
13925c51f124SMoriah Waterland 	 * than the zone name only.
13935c51f124SMoriah Waterland 	 * *********************************************************************
13945c51f124SMoriah Waterland 	 */
13955c51f124SMoriah Waterland 
13965c51f124SMoriah Waterland 	/* reject if any items found that cannot be in a non-global zone */
13975c51f124SMoriah Waterland 
13985c51f124SMoriah Waterland 	/* .tmp_proto must not exist */
13995c51f124SMoriah Waterland 
14005c51f124SMoriah Waterland 	r = testPath(TEST_NOT_EXISTS, "%s/%s", rootPath, ".tmp_proto");
14015c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
14025c51f124SMoriah Waterland 		/* $R/.tmp_proto cannot exist in a non-global zone */
14035c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS,
14045c51f124SMoriah Waterland 			rootPath, "/.tmp_proto");
14055c51f124SMoriah Waterland 		return (R_FAILURE);
14065c51f124SMoriah Waterland 	}
14075c51f124SMoriah Waterland 
14085c51f124SMoriah Waterland 	/* /var must not be a symbolic link */
14095c51f124SMoriah Waterland 
14105c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
14115c51f124SMoriah Waterland 		"%s/%s", rootPath, "/var");
14125c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
14135c51f124SMoriah Waterland 		/* $R/var cannot be a symbolic link in a non-global zone */
14145c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_DOES_NOT_EXIST,
14155c51f124SMoriah Waterland 			rootPath, "/var");
14165c51f124SMoriah Waterland 		return (R_FAILURE);
14175c51f124SMoriah Waterland 	}
14185c51f124SMoriah Waterland 
14195c51f124SMoriah Waterland 	/* $ROOTDIR/tmp/root/kernel must not exist */
14205c51f124SMoriah Waterland 
14215c51f124SMoriah Waterland 	r = testPath(TEST_NOT_EXISTS,
14225c51f124SMoriah Waterland 		"%s/%s", rootPath, "/tmp/root/kernel");
14235c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
14245c51f124SMoriah Waterland 		/* $R/tmp/root/kernel cannot exist in a non-global zone */
14255c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS,
14265c51f124SMoriah Waterland 			rootPath, "/tmp/root/kernel");
14275c51f124SMoriah Waterland 		return (R_FAILURE);
14285c51f124SMoriah Waterland 	}
14295c51f124SMoriah Waterland 
14305c51f124SMoriah Waterland 	/*
14315c51f124SMoriah Waterland 	 * *********************************************************************
14325c51f124SMoriah Waterland 	 * no items exist in $ROOTDIR that identify something other than
14335c51f124SMoriah Waterland 	 * a non-global zone.
14345c51f124SMoriah Waterland 	 *
14355c51f124SMoriah Waterland 	 * if in global zone no more tests possible: is a non-global zone
14365c51f124SMoriah Waterland 	 * *********************************************************************
14375c51f124SMoriah Waterland 	 */
14385c51f124SMoriah Waterland 
14395c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
14405c51f124SMoriah Waterland 		/* in the global zone */
14415c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_IN_GZ_IS_NONGLOBAL_ZONE,
14425c51f124SMoriah Waterland 			rootPath);
14435c51f124SMoriah Waterland 		return (R_SUCCESS);
14445c51f124SMoriah Waterland 	}
14455c51f124SMoriah Waterland 
14465c51f124SMoriah Waterland 	/*
14475c51f124SMoriah Waterland 	 * *********************************************************************
14485c51f124SMoriah Waterland 	 * In non-global zone: interrogate zone name and type.
14495c51f124SMoriah Waterland 	 *
14505c51f124SMoriah Waterland 	 * The parent zone is the zone that the "pkgadd" or "pkgrm" command was
14515c51f124SMoriah Waterland 	 * run in. The child zone is the zone that the "pkginstall" or
14525c51f124SMoriah Waterland 	 * "pkgremove" command was run in.
14535c51f124SMoriah Waterland 	 * *********************************************************************
14545c51f124SMoriah Waterland 	 */
14555c51f124SMoriah Waterland 
14565c51f124SMoriah Waterland 	/*
14575c51f124SMoriah Waterland 	 * If parent zone name and current zone name defined, and
14585c51f124SMoriah Waterland 	 * both zone names are the same, since pkgcond is running
14595c51f124SMoriah Waterland 	 * inside of a non-global zone, this is how the scratch
14605c51f124SMoriah Waterland 	 * zone is implemented, so target is a non-global zone
14615c51f124SMoriah Waterland 	 */
14625c51f124SMoriah Waterland 
14635c51f124SMoriah Waterland 	if ((a_gdt->gd_parentZoneName != NULL) &&
14645c51f124SMoriah Waterland 		(a_gdt->gd_currentZoneName != NULL) &&
14655c51f124SMoriah Waterland 		(strcmp(a_gdt->gd_parentZoneName,
14665c51f124SMoriah Waterland 					a_gdt->gd_currentZoneName) == 0)) {
14675c51f124SMoriah Waterland 			/* parent and current zone name identical: non-gz */
14685c51f124SMoriah Waterland 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_PARENT_CHILD_SAMEZONE,
14695c51f124SMoriah Waterland 				rootPath, a_gdt->gd_parentZoneName);
14705c51f124SMoriah Waterland 			return (R_SUCCESS);
14715c51f124SMoriah Waterland 	}
14725c51f124SMoriah Waterland 
14735c51f124SMoriah Waterland 	/*
14746e1ae2a3SGary Pennington 	 * In non-global zone if zone specific read only FS's exist
14755c51f124SMoriah Waterland 	 * or it is in a mounted state.
14765c51f124SMoriah Waterland 	 */
14775c51f124SMoriah Waterland 
14786e1ae2a3SGary Pennington 	if (a_gdt->inMountedState) {
14795c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath);
14805c51f124SMoriah Waterland 		return (R_SUCCESS);
14815c51f124SMoriah Waterland 	}
14825c51f124SMoriah Waterland 
14835c51f124SMoriah Waterland 	/*
14845c51f124SMoriah Waterland 	 * the parent and current zone name are not the same;
14855c51f124SMoriah Waterland 	 * interrogate the zone types: the parent must be global
14865c51f124SMoriah Waterland 	 * and the current must be non-global, which would be set
14875c51f124SMoriah Waterland 	 * when a package command is run in the global zone that in
14885c51f124SMoriah Waterland 	 * turn runs a package command within the non-global zone.
14895c51f124SMoriah Waterland 	 */
14905c51f124SMoriah Waterland 
14915c51f124SMoriah Waterland 	/* if defined, parent zone type must be "global" */
14925c51f124SMoriah Waterland 
14935c51f124SMoriah Waterland 	if ((a_gdt->gd_parentZoneType != NULL) &&
14945c51f124SMoriah Waterland 		(strcmp(a_gdt->gd_parentZoneType, "nonglobal") == 0)) {
14955c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_PARENT_ZONETYPE,
14965c51f124SMoriah Waterland 			rootPath, "nonglobal");
14975c51f124SMoriah Waterland 		return (R_FAILURE);
14985c51f124SMoriah Waterland 	}
14995c51f124SMoriah Waterland 
15005c51f124SMoriah Waterland 	/* if defined, current zone type must be "nonglobal" */
15015c51f124SMoriah Waterland 
15025c51f124SMoriah Waterland 	if ((a_gdt->gd_currentZoneType != NULL) &&
15035c51f124SMoriah Waterland 		(strcmp(a_gdt->gd_currentZoneType, GLOBAL_ZONENAME) == 0)) {
15045c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_CURRENT_ZONETYPE,
15055c51f124SMoriah Waterland 			rootPath, GLOBAL_ZONENAME);
15065c51f124SMoriah Waterland 		return (R_FAILURE);
15075c51f124SMoriah Waterland 	}
15085c51f124SMoriah Waterland 
15095c51f124SMoriah Waterland 	/*
15105c51f124SMoriah Waterland 	 * *********************************************************************
15115c51f124SMoriah Waterland 	 * no other tests possible: target is a non-global zone
15125c51f124SMoriah Waterland 	 * *********************************************************************
15135c51f124SMoriah Waterland 	 */
15145c51f124SMoriah Waterland 
15155c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath);
15165c51f124SMoriah Waterland 
15175c51f124SMoriah Waterland 	return (R_SUCCESS);
15185c51f124SMoriah Waterland }
15195c51f124SMoriah Waterland 
15205c51f124SMoriah Waterland /*
15215c51f124SMoriah Waterland  * Name:	cmd_is_running_system
15225c51f124SMoriah Waterland  * Description:	determine if target is a global zone
15235c51f124SMoriah Waterland  * Scope:	public
15245c51f124SMoriah Waterland  * Arguments:	argc,argv:
15255c51f124SMoriah Waterland  *		  - optional path to target to test
15265c51f124SMoriah Waterland  * Returns:	int
15275c51f124SMoriah Waterland  *			== 0 - success
15285c51f124SMoriah Waterland  *			!= 0 - failure
15295c51f124SMoriah Waterland  * IMPLEMENTATION:
15305c51f124SMoriah Waterland  *  - must not be initial installation to the install root
15315c51f124SMoriah Waterland  *  - must not be installation of a zone
15325c51f124SMoriah Waterland  *  - must not be a diskless client
15335c51f124SMoriah Waterland  *  - $ROOTDIR must be "/"
15345c51f124SMoriah Waterland  *  - zone name must be "global"
15355c51f124SMoriah Waterland  */
15365c51f124SMoriah Waterland 
15375c51f124SMoriah Waterland static int
cmd_is_running_system(int argc,char ** argv,GLOBALDATA_T * a_gdt)15385c51f124SMoriah Waterland cmd_is_running_system(int argc, char **argv, GLOBALDATA_T *a_gdt)
15395c51f124SMoriah Waterland {
15405c51f124SMoriah Waterland 	char	*rootPath = NULL;
15415c51f124SMoriah Waterland 	int	c;
15425c51f124SMoriah Waterland 	int	r;
15435c51f124SMoriah Waterland static	char	*cmdName = "is_running_system";
15445c51f124SMoriah Waterland static	int	recursion = 0;
15455c51f124SMoriah Waterland 
15465c51f124SMoriah Waterland 	/* process any command line options */
15475c51f124SMoriah Waterland 
15485c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
15495c51f124SMoriah Waterland 		switch (c) {
15505c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
15515c51f124SMoriah Waterland 			break;
15525c51f124SMoriah Waterland 		case '?':
15535c51f124SMoriah Waterland 		default:
15545c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
15555c51f124SMoriah Waterland 			return (R_USAGE);
15565c51f124SMoriah Waterland 		}
15575c51f124SMoriah Waterland 	}
15585c51f124SMoriah Waterland 
15595c51f124SMoriah Waterland 	/* prevent recursion */
15605c51f124SMoriah Waterland 
15615c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
15625c51f124SMoriah Waterland 
15635c51f124SMoriah Waterland 		/* a running system cannot be a diskless client */
15645c51f124SMoriah Waterland 
15655c51f124SMoriah Waterland 		r = cmd_is_diskless_client(argc, argv, a_gdt);
15665c51f124SMoriah Waterland 
15675c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
15685c51f124SMoriah Waterland 
15695c51f124SMoriah Waterland 		recursion--;
15705c51f124SMoriah Waterland 
15715c51f124SMoriah Waterland 		switch (r) {
15725c51f124SMoriah Waterland 			case R_SUCCESS:
15735c51f124SMoriah Waterland 				return (R_FAILURE);
15745c51f124SMoriah Waterland 			case R_FAILURE:
15755c51f124SMoriah Waterland 				break;
15765c51f124SMoriah Waterland 			case R_USAGE:
15775c51f124SMoriah Waterland 			case R_ERROR:
15785c51f124SMoriah Waterland 			default:
15795c51f124SMoriah Waterland 				return (r);
15805c51f124SMoriah Waterland 		}
15815c51f124SMoriah Waterland 	}
15825c51f124SMoriah Waterland 
15835c51f124SMoriah Waterland 	/* normalize argc/argv */
15845c51f124SMoriah Waterland 
15855c51f124SMoriah Waterland 	argc -= optind;
15865c51f124SMoriah Waterland 	argv += optind;
15875c51f124SMoriah Waterland 
15885c51f124SMoriah Waterland 	/* error if more than one argument */
15895c51f124SMoriah Waterland 
15905c51f124SMoriah Waterland 	if (argc > 1) {
15915c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
15925c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
15935c51f124SMoriah Waterland 		return (R_USAGE);
15945c51f124SMoriah Waterland 	}
15955c51f124SMoriah Waterland 
15965c51f124SMoriah Waterland 	/* process root path if first argument present */
15975c51f124SMoriah Waterland 
15985c51f124SMoriah Waterland 	if (argc == 1) {
15995c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
16005c51f124SMoriah Waterland 			return (R_ERROR);
16015c51f124SMoriah Waterland 		}
16025c51f124SMoriah Waterland 	}
16035c51f124SMoriah Waterland 
16045c51f124SMoriah Waterland 	/* get current root path */
16055c51f124SMoriah Waterland 
16065c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
16075c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
16085c51f124SMoriah Waterland 		return (r);
16095c51f124SMoriah Waterland 	}
16105c51f124SMoriah Waterland 
16115c51f124SMoriah Waterland 	/* start of command debugging information */
16125c51f124SMoriah Waterland 
16135c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
16145c51f124SMoriah Waterland 
16155c51f124SMoriah Waterland 	/* if root path is "/" then check zone name */
16165c51f124SMoriah Waterland 
16175c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") != 0) {
16185c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ROOTPATH_BAD, rootPath, "/");
16195c51f124SMoriah Waterland 		return (R_FAILURE);
16205c51f124SMoriah Waterland 	}
16215c51f124SMoriah Waterland 
16225c51f124SMoriah Waterland 	/* zone name must be global */
16235c51f124SMoriah Waterland 
16245c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
16255c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_BAD, rootPath,
16265c51f124SMoriah Waterland 			GLOBAL_ZONENAME);
16275c51f124SMoriah Waterland 		return (R_FAILURE);
16285c51f124SMoriah Waterland 	}
16295c51f124SMoriah Waterland 
16305c51f124SMoriah Waterland 	/* must not be initial installation to the install root */
16315c51f124SMoriah Waterland 
16325c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
16335c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
16345c51f124SMoriah Waterland 		/* initial install: install root cannot be the running system */
16355c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IRST_INITIAL_INSTALL, rootPath);
16365c51f124SMoriah Waterland 		return (R_FAILURE);
16375c51f124SMoriah Waterland 	}
16385c51f124SMoriah Waterland 
16395c51f124SMoriah Waterland 	/* must not be installation of a zone */
16405c51f124SMoriah Waterland 
16415c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
16425c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
16435c51f124SMoriah Waterland 		/* initial zone install: no path can be running system */
16445c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_INSTALL, rootPath);
16455c51f124SMoriah Waterland 		return (R_FAILURE);
16465c51f124SMoriah Waterland 	}
16475c51f124SMoriah Waterland 
16485c51f124SMoriah Waterland 	/* target is a running system */
16495c51f124SMoriah Waterland 
16505c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_IRST_PATH_IS_RUNNING_SYSTEM, rootPath);
16515c51f124SMoriah Waterland 
16525c51f124SMoriah Waterland 	return (R_SUCCESS);
16535c51f124SMoriah Waterland }
16545c51f124SMoriah Waterland 
16555c51f124SMoriah Waterland /*
16565c51f124SMoriah Waterland  * Name:	cmd_can_add_driver
16575c51f124SMoriah Waterland  * Description:	determine if target is a global zone
16585c51f124SMoriah Waterland  * Scope:	public
16595c51f124SMoriah Waterland  * Arguments:	argc,argv:
16605c51f124SMoriah Waterland  *		  - optional path to target to test
16615c51f124SMoriah Waterland  * Returns:	int
16625c51f124SMoriah Waterland  *			== 0 - success
16635c51f124SMoriah Waterland  *			!= 0 - failure
16645c51f124SMoriah Waterland  * Implementation:
16655c51f124SMoriah Waterland  * A driver can be added to the system if the components of a Solaris
16665c51f124SMoriah Waterland  * instance capable of loading drivers is present and it is not the
16675c51f124SMoriah Waterland  * currently running system.
16685c51f124SMoriah Waterland  */
16695c51f124SMoriah Waterland 
16705c51f124SMoriah Waterland static int
cmd_can_add_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)16715c51f124SMoriah Waterland cmd_can_add_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
16725c51f124SMoriah Waterland {
16735c51f124SMoriah Waterland 	char	*rootPath = NULL;
16745c51f124SMoriah Waterland 	int	c;
16755c51f124SMoriah Waterland 	int	r;
16765c51f124SMoriah Waterland static	char	*cmdName = "can_add_driver";
16775c51f124SMoriah Waterland static	int	recursion = 0;
16785c51f124SMoriah Waterland 
16795c51f124SMoriah Waterland 	/* process any command line options */
16805c51f124SMoriah Waterland 
16815c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
16825c51f124SMoriah Waterland 		switch (c) {
16835c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
16845c51f124SMoriah Waterland 			break;
16855c51f124SMoriah Waterland 		case '?':
16865c51f124SMoriah Waterland 		default:
16875c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
16885c51f124SMoriah Waterland 			return (R_USAGE);
16895c51f124SMoriah Waterland 		}
16905c51f124SMoriah Waterland 	}
16915c51f124SMoriah Waterland 
16925c51f124SMoriah Waterland 	/* prevent recursion */
16935c51f124SMoriah Waterland 
16945c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
16955c51f124SMoriah Waterland 
16965c51f124SMoriah Waterland 		/* see if this is the current running system */
16975c51f124SMoriah Waterland 
16985c51f124SMoriah Waterland 		r = cmd_is_running_system(argc, argv, a_gdt);
16995c51f124SMoriah Waterland 
17005c51f124SMoriah Waterland 		/* cannot be a diskless client */
17015c51f124SMoriah Waterland 
17025c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
17035c51f124SMoriah Waterland 			r = cmd_is_diskless_client(argc, argv, a_gdt);
17045c51f124SMoriah Waterland 		}
17055c51f124SMoriah Waterland 
17065c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
17075c51f124SMoriah Waterland 
17085c51f124SMoriah Waterland 		recursion--;
17095c51f124SMoriah Waterland 
17105c51f124SMoriah Waterland 		switch (r) {
17115c51f124SMoriah Waterland 			case R_SUCCESS:
17125c51f124SMoriah Waterland 				/* is a running system */
17135c51f124SMoriah Waterland 				return (R_FAILURE);
17145c51f124SMoriah Waterland 			case R_FAILURE:
17155c51f124SMoriah Waterland 				/* not a running syste */
17165c51f124SMoriah Waterland 				break;
17175c51f124SMoriah Waterland 			case R_USAGE:
17185c51f124SMoriah Waterland 			case R_ERROR:
17195c51f124SMoriah Waterland 			default:
17205c51f124SMoriah Waterland 				/* cannot determine if is a running system */
17215c51f124SMoriah Waterland 				return (r);
17225c51f124SMoriah Waterland 		}
17235c51f124SMoriah Waterland 	}
17245c51f124SMoriah Waterland 
17255c51f124SMoriah Waterland 	/* normalize argc/argv */
17265c51f124SMoriah Waterland 
17275c51f124SMoriah Waterland 	argc -= optind;
17285c51f124SMoriah Waterland 	argv += optind;
17295c51f124SMoriah Waterland 
17305c51f124SMoriah Waterland 	/* error if more than one argument */
17315c51f124SMoriah Waterland 
17325c51f124SMoriah Waterland 	if (argc > 1) {
17335c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
17345c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
17355c51f124SMoriah Waterland 		return (R_USAGE);
17365c51f124SMoriah Waterland 	}
17375c51f124SMoriah Waterland 
17385c51f124SMoriah Waterland 	/* process root path if first argument present */
17395c51f124SMoriah Waterland 
17405c51f124SMoriah Waterland 	if (argc == 1) {
17415c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
17425c51f124SMoriah Waterland 			return (R_ERROR);
17435c51f124SMoriah Waterland 		}
17445c51f124SMoriah Waterland 	}
17455c51f124SMoriah Waterland 
17465c51f124SMoriah Waterland 	/* get current root path */
17475c51f124SMoriah Waterland 
17485c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
17495c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
17505c51f124SMoriah Waterland 		return (r);
17515c51f124SMoriah Waterland 	}
17525c51f124SMoriah Waterland 
17535c51f124SMoriah Waterland 	/* start of command debugging information */
17545c51f124SMoriah Waterland 
17555c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
17565c51f124SMoriah Waterland 
17575c51f124SMoriah Waterland 	/* /etc must exist and must not be a symbolic link */
17585c51f124SMoriah Waterland 
17595c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17605c51f124SMoriah Waterland 		"%s/%s", rootPath, "/etc");
17615c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
17625c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17635c51f124SMoriah Waterland 			rootPath, "/etc");
17645c51f124SMoriah Waterland 		return (R_FAILURE);
17655c51f124SMoriah Waterland 	}
17665c51f124SMoriah Waterland 
17675c51f124SMoriah Waterland 	/* /platform must exist and must not be a symbolic link */
17685c51f124SMoriah Waterland 
17695c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17705c51f124SMoriah Waterland 		"%s/%s", rootPath, "/platform");
17715c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
17725c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17735c51f124SMoriah Waterland 			rootPath, "/platform");
17745c51f124SMoriah Waterland 		return (R_FAILURE);
17755c51f124SMoriah Waterland 	}
17765c51f124SMoriah Waterland 
17775c51f124SMoriah Waterland 	/* /kernel must exist and must not be a symbolic link */
17785c51f124SMoriah Waterland 
17795c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17805c51f124SMoriah Waterland 		"%s/%s", rootPath, "/kernel");
17815c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
17825c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17835c51f124SMoriah Waterland 			rootPath, "/kernel");
17845c51f124SMoriah Waterland 		return (R_FAILURE);
17855c51f124SMoriah Waterland 	}
17865c51f124SMoriah Waterland 
17875c51f124SMoriah Waterland 	/* can add a driver */
17885c51f124SMoriah Waterland 
17895c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_ADDV_YES, rootPath);
17905c51f124SMoriah Waterland 
17915c51f124SMoriah Waterland 	return (R_SUCCESS);
17925c51f124SMoriah Waterland }
17935c51f124SMoriah Waterland 
17945c51f124SMoriah Waterland /*
17955c51f124SMoriah Waterland  * Name:	cmd_can_update_driver
17965c51f124SMoriah Waterland  * Description:	determine if target is a global zone
17975c51f124SMoriah Waterland  * Scope:	public
17985c51f124SMoriah Waterland  * Arguments:	argc,argv:
17995c51f124SMoriah Waterland  *		  - optional path to target to test
18005c51f124SMoriah Waterland  * Returns:	int
18015c51f124SMoriah Waterland  *			== 0 - success
18025c51f124SMoriah Waterland  *			!= 0 - failure
18035c51f124SMoriah Waterland  * Implementation:
18045c51f124SMoriah Waterland  * A driver can be added to the system if the components of a Solaris
18055c51f124SMoriah Waterland  * instance capable of loading drivers is present and it is not the
18065c51f124SMoriah Waterland  * currently running system.
18075c51f124SMoriah Waterland  */
18085c51f124SMoriah Waterland 
18095c51f124SMoriah Waterland static int
cmd_can_update_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)18105c51f124SMoriah Waterland cmd_can_update_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
18115c51f124SMoriah Waterland {
18125c51f124SMoriah Waterland 	char	*rootPath = NULL;
18135c51f124SMoriah Waterland 	int	c;
18145c51f124SMoriah Waterland 	int	r;
18155c51f124SMoriah Waterland static	char	*cmdName = "can_update_driver";
18165c51f124SMoriah Waterland static	int	recursion = 0;
18175c51f124SMoriah Waterland 
18185c51f124SMoriah Waterland 	/* process any command line options */
18195c51f124SMoriah Waterland 
18205c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
18215c51f124SMoriah Waterland 		switch (c) {
18225c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
18235c51f124SMoriah Waterland 			break;
18245c51f124SMoriah Waterland 		case '?':
18255c51f124SMoriah Waterland 		default:
18265c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
18275c51f124SMoriah Waterland 			return (R_USAGE);
18285c51f124SMoriah Waterland 		}
18295c51f124SMoriah Waterland 	}
18305c51f124SMoriah Waterland 
18315c51f124SMoriah Waterland 	/* prevent recursion */
18325c51f124SMoriah Waterland 
18335c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
18345c51f124SMoriah Waterland 
18355c51f124SMoriah Waterland 		/* see if this is the current running system */
18365c51f124SMoriah Waterland 
18375c51f124SMoriah Waterland 		r = cmd_is_running_system(argc, argv, a_gdt);
18385c51f124SMoriah Waterland 
18395c51f124SMoriah Waterland 		/* cannot be a diskless client */
18405c51f124SMoriah Waterland 
18415c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
18425c51f124SMoriah Waterland 			r = cmd_is_diskless_client(argc, argv, a_gdt);
18435c51f124SMoriah Waterland 		}
18445c51f124SMoriah Waterland 
18455c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
18465c51f124SMoriah Waterland 
18475c51f124SMoriah Waterland 		recursion--;
18485c51f124SMoriah Waterland 
18495c51f124SMoriah Waterland 		switch (r) {
18505c51f124SMoriah Waterland 			case R_SUCCESS:
18515c51f124SMoriah Waterland 				/* is a running system */
18525c51f124SMoriah Waterland 				return (R_FAILURE);
18535c51f124SMoriah Waterland 			case R_FAILURE:
18545c51f124SMoriah Waterland 				/* not a running syste */
18555c51f124SMoriah Waterland 				break;
18565c51f124SMoriah Waterland 			case R_USAGE:
18575c51f124SMoriah Waterland 			case R_ERROR:
18585c51f124SMoriah Waterland 			default:
18595c51f124SMoriah Waterland 				/* cannot determine if is a running system */
18605c51f124SMoriah Waterland 				return (r);
18615c51f124SMoriah Waterland 		}
18625c51f124SMoriah Waterland 	}
18635c51f124SMoriah Waterland 
18645c51f124SMoriah Waterland 	/* normalize argc/argv */
18655c51f124SMoriah Waterland 
18665c51f124SMoriah Waterland 	argc -= optind;
18675c51f124SMoriah Waterland 	argv += optind;
18685c51f124SMoriah Waterland 
18695c51f124SMoriah Waterland 	/* error if more than one argument */
18705c51f124SMoriah Waterland 
18715c51f124SMoriah Waterland 	if (argc > 1) {
18725c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
18735c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
18745c51f124SMoriah Waterland 		return (R_USAGE);
18755c51f124SMoriah Waterland 	}
18765c51f124SMoriah Waterland 
18775c51f124SMoriah Waterland 	/* process root path if first argument present */
18785c51f124SMoriah Waterland 
18795c51f124SMoriah Waterland 	if (argc == 1) {
18805c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
18815c51f124SMoriah Waterland 			return (R_ERROR);
18825c51f124SMoriah Waterland 		}
18835c51f124SMoriah Waterland 	}
18845c51f124SMoriah Waterland 
18855c51f124SMoriah Waterland 	/* get current root path */
18865c51f124SMoriah Waterland 
18875c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
18885c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
18895c51f124SMoriah Waterland 		return (r);
18905c51f124SMoriah Waterland 	}
18915c51f124SMoriah Waterland 
18925c51f124SMoriah Waterland 	/* start of command debugging information */
18935c51f124SMoriah Waterland 
18945c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
18955c51f124SMoriah Waterland 
18965c51f124SMoriah Waterland 	/* /etc must exist and must not be a symbolic link */
18975c51f124SMoriah Waterland 
18985c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
18995c51f124SMoriah Waterland 		"%s/%s", rootPath, "/etc");
19005c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
19015c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19025c51f124SMoriah Waterland 			rootPath, "/etc");
19035c51f124SMoriah Waterland 		return (R_FAILURE);
19045c51f124SMoriah Waterland 	}
19055c51f124SMoriah Waterland 
19065c51f124SMoriah Waterland 	/* /platform must exist and must not be a symbolic link */
19075c51f124SMoriah Waterland 
19085c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
19095c51f124SMoriah Waterland 		"%s/%s", rootPath, "/platform");
19105c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
19115c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19125c51f124SMoriah Waterland 			rootPath, "/platform");
19135c51f124SMoriah Waterland 		return (R_FAILURE);
19145c51f124SMoriah Waterland 	}
19155c51f124SMoriah Waterland 
19165c51f124SMoriah Waterland 	/* /kernel must exist and must not be a symbolic link */
19175c51f124SMoriah Waterland 
19185c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
19195c51f124SMoriah Waterland 		"%s/%s", rootPath, "/kernel");
19205c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
19215c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19225c51f124SMoriah Waterland 			rootPath, "/kernel");
19235c51f124SMoriah Waterland 		return (R_FAILURE);
19245c51f124SMoriah Waterland 	}
19255c51f124SMoriah Waterland 
19265c51f124SMoriah Waterland 	/* can update driver */
19275c51f124SMoriah Waterland 
19285c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_UPDV_YES, rootPath);
19295c51f124SMoriah Waterland 
19305c51f124SMoriah Waterland 	return (R_SUCCESS);
19315c51f124SMoriah Waterland }
19325c51f124SMoriah Waterland 
19335c51f124SMoriah Waterland /*
19345c51f124SMoriah Waterland  * Name:	cmd_can_remove_driver
19355c51f124SMoriah Waterland  * Description:	determine if target is a global zone
19365c51f124SMoriah Waterland  * Scope:	public
19375c51f124SMoriah Waterland  * Arguments:	argc,argv:
19385c51f124SMoriah Waterland  *		  - optional path to target to test
19395c51f124SMoriah Waterland  * Returns:	int
19405c51f124SMoriah Waterland  *			== 0 - success
19415c51f124SMoriah Waterland  *			!= 0 - failure
19425c51f124SMoriah Waterland  * Implementation:
19435c51f124SMoriah Waterland  * A driver can be added to the system if the components of a Solaris
19445c51f124SMoriah Waterland  * instance capable of loading drivers is present and it is not the
19455c51f124SMoriah Waterland  * currently running system.
19465c51f124SMoriah Waterland  */
19475c51f124SMoriah Waterland 
19485c51f124SMoriah Waterland static int
cmd_can_remove_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)19495c51f124SMoriah Waterland cmd_can_remove_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
19505c51f124SMoriah Waterland {
19515c51f124SMoriah Waterland 	char	*rootPath = NULL;
19525c51f124SMoriah Waterland 	int	c;
19535c51f124SMoriah Waterland 	int	r;
19545c51f124SMoriah Waterland static	char	*cmdName = "can_remove_driver";
19555c51f124SMoriah Waterland static	int	recursion = 0;
19565c51f124SMoriah Waterland 
19575c51f124SMoriah Waterland 	/* process any command line options */
19585c51f124SMoriah Waterland 
19595c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
19605c51f124SMoriah Waterland 		switch (c) {
19615c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
19625c51f124SMoriah Waterland 			break;
19635c51f124SMoriah Waterland 		case '?':
19645c51f124SMoriah Waterland 		default:
19655c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
19665c51f124SMoriah Waterland 			return (R_USAGE);
19675c51f124SMoriah Waterland 		}
19685c51f124SMoriah Waterland 	}
19695c51f124SMoriah Waterland 
19705c51f124SMoriah Waterland 	/* prevent recursion */
19715c51f124SMoriah Waterland 
19725c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
19735c51f124SMoriah Waterland 
19745c51f124SMoriah Waterland 		/* see if this is the current running system */
19755c51f124SMoriah Waterland 
19765c51f124SMoriah Waterland 		r = cmd_is_running_system(argc, argv, a_gdt);
19775c51f124SMoriah Waterland 
19785c51f124SMoriah Waterland 		/* cannot be a diskless client */
19795c51f124SMoriah Waterland 
19805c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
19815c51f124SMoriah Waterland 			r = cmd_is_diskless_client(argc, argv, a_gdt);
19825c51f124SMoriah Waterland 		}
19835c51f124SMoriah Waterland 
19845c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
19855c51f124SMoriah Waterland 
19865c51f124SMoriah Waterland 		recursion--;
19875c51f124SMoriah Waterland 
19885c51f124SMoriah Waterland 		switch (r) {
19895c51f124SMoriah Waterland 			case R_SUCCESS:
19905c51f124SMoriah Waterland 				/* is a running system */
19915c51f124SMoriah Waterland 				return (R_FAILURE);
19925c51f124SMoriah Waterland 			case R_FAILURE:
19935c51f124SMoriah Waterland 				/* not a running syste */
19945c51f124SMoriah Waterland 				break;
19955c51f124SMoriah Waterland 			case R_USAGE:
19965c51f124SMoriah Waterland 			case R_ERROR:
19975c51f124SMoriah Waterland 			default:
19985c51f124SMoriah Waterland 				/* cannot determine if is a running system */
19995c51f124SMoriah Waterland 				return (r);
20005c51f124SMoriah Waterland 		}
20015c51f124SMoriah Waterland 	}
20025c51f124SMoriah Waterland 
20035c51f124SMoriah Waterland 	/* normalize argc/argv */
20045c51f124SMoriah Waterland 
20055c51f124SMoriah Waterland 	argc -= optind;
20065c51f124SMoriah Waterland 	argv += optind;
20075c51f124SMoriah Waterland 
20085c51f124SMoriah Waterland 	/* error if more than one argument */
20095c51f124SMoriah Waterland 
20105c51f124SMoriah Waterland 	if (argc > 1) {
20115c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
20125c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
20135c51f124SMoriah Waterland 		return (R_USAGE);
20145c51f124SMoriah Waterland 	}
20155c51f124SMoriah Waterland 
20165c51f124SMoriah Waterland 	/* process root path if first argument present */
20175c51f124SMoriah Waterland 
20185c51f124SMoriah Waterland 	if (argc == 1) {
20195c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
20205c51f124SMoriah Waterland 			return (R_ERROR);
20215c51f124SMoriah Waterland 		}
20225c51f124SMoriah Waterland 	}
20235c51f124SMoriah Waterland 
20245c51f124SMoriah Waterland 	/* get current root path */
20255c51f124SMoriah Waterland 
20265c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
20275c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
20285c51f124SMoriah Waterland 		return (r);
20295c51f124SMoriah Waterland 	}
20305c51f124SMoriah Waterland 
20315c51f124SMoriah Waterland 	/* start of command debugging information */
20325c51f124SMoriah Waterland 
20335c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
20345c51f124SMoriah Waterland 
20355c51f124SMoriah Waterland 	/* /etc must exist and must not be a symbolic link */
20365c51f124SMoriah Waterland 
20375c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20385c51f124SMoriah Waterland 		"%s/%s", rootPath, "/etc");
20395c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
20405c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20415c51f124SMoriah Waterland 			rootPath, "/etc");
20425c51f124SMoriah Waterland 		return (R_FAILURE);
20435c51f124SMoriah Waterland 	}
20445c51f124SMoriah Waterland 
20455c51f124SMoriah Waterland 	/* /platform must exist and must not be a symbolic link */
20465c51f124SMoriah Waterland 
20475c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20485c51f124SMoriah Waterland 		"%s/%s", rootPath, "/platform");
20495c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
20505c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20515c51f124SMoriah Waterland 			rootPath, "/platform");
20525c51f124SMoriah Waterland 		return (R_FAILURE);
20535c51f124SMoriah Waterland 	}
20545c51f124SMoriah Waterland 
20555c51f124SMoriah Waterland 	/* /kernel must exist and must not be a symbolic link */
20565c51f124SMoriah Waterland 
20575c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20585c51f124SMoriah Waterland 		"%s/%s", rootPath, "/kernel");
20595c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
20605c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20615c51f124SMoriah Waterland 			rootPath, "/kernel");
20625c51f124SMoriah Waterland 		return (R_FAILURE);
20635c51f124SMoriah Waterland 	}
20645c51f124SMoriah Waterland 
20655c51f124SMoriah Waterland 	/* can remove driver */
20665c51f124SMoriah Waterland 
20675c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_RMDV_YES, rootPath);
20685c51f124SMoriah Waterland 
20695c51f124SMoriah Waterland 	return (R_SUCCESS);
20705c51f124SMoriah Waterland }
20715c51f124SMoriah Waterland 
20725c51f124SMoriah Waterland /*
20735c51f124SMoriah Waterland  * Name:	cmd_is_path_writable
20746e1ae2a3SGary Pennington  * Description:	determine if target path is writable
20755c51f124SMoriah Waterland  * Scope:	public
20765c51f124SMoriah Waterland  * Arguments:	argc,argv:
20775c51f124SMoriah Waterland  *		  - optional path to target to test
20785c51f124SMoriah Waterland  * Returns:	int
20795c51f124SMoriah Waterland  *			== 0 - success
20805c51f124SMoriah Waterland  *			!= 0 - failure
20815c51f124SMoriah Waterland  * IMPLEMENTATION:
20825c51f124SMoriah Waterland  * - path must be found in the file systems configured
20835c51f124SMoriah Waterland  * - mount options must not include "read only"
20845c51f124SMoriah Waterland  */
20855c51f124SMoriah Waterland 
20865c51f124SMoriah Waterland static int
cmd_is_path_writable(int argc,char ** argv,GLOBALDATA_T * a_gdt)20875c51f124SMoriah Waterland cmd_is_path_writable(int argc, char **argv, GLOBALDATA_T *a_gdt)
20885c51f124SMoriah Waterland {
20895c51f124SMoriah Waterland 	FSI_T	*list;
20905c51f124SMoriah Waterland 	char	*rootPath = NULL;
20915c51f124SMoriah Waterland 	int	c;
20925c51f124SMoriah Waterland 	int	n;
20935c51f124SMoriah Waterland 	int	nn;
20945c51f124SMoriah Waterland 	int	r;
20955c51f124SMoriah Waterland 	long	listSize;
20965c51f124SMoriah Waterland 	long	rootPathLen;
20975c51f124SMoriah Waterland static	char	*cmdName = "is_path_writable";
20985c51f124SMoriah Waterland static	int	recursion = 0;
20995c51f124SMoriah Waterland 
21005c51f124SMoriah Waterland 	/* process any command line options */
21015c51f124SMoriah Waterland 
21025c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
21035c51f124SMoriah Waterland 		switch (c) {
21045c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
21055c51f124SMoriah Waterland 			break;
21065c51f124SMoriah Waterland 		case '?':
21075c51f124SMoriah Waterland 		default:
21085c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
21095c51f124SMoriah Waterland 			return (R_USAGE);
21105c51f124SMoriah Waterland 		}
21115c51f124SMoriah Waterland 	}
21125c51f124SMoriah Waterland 
21135c51f124SMoriah Waterland 	/* prevent recursion */
21145c51f124SMoriah Waterland 
21155c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
21165c51f124SMoriah Waterland 		recursion--;
21175c51f124SMoriah Waterland 	}
21185c51f124SMoriah Waterland 
21195c51f124SMoriah Waterland 	/* normalize argc/argv */
21205c51f124SMoriah Waterland 
21215c51f124SMoriah Waterland 	argc -= optind;
21225c51f124SMoriah Waterland 	argv += optind;
21235c51f124SMoriah Waterland 
21245c51f124SMoriah Waterland 	/* error if more than one argument */
21255c51f124SMoriah Waterland 
21265c51f124SMoriah Waterland 	if (argc > 1) {
21275c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
21285c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
21295c51f124SMoriah Waterland 		return (R_USAGE);
21305c51f124SMoriah Waterland 	}
21315c51f124SMoriah Waterland 
21325c51f124SMoriah Waterland 	/* process root path if first argument present */
21335c51f124SMoriah Waterland 
21345c51f124SMoriah Waterland 	if (argc != 1) {
21355c51f124SMoriah Waterland 		(void) usage(ERR_REQUIRED_ROOTPATH_MISSING, cmdName);
21365c51f124SMoriah Waterland 		return (R_USAGE);
21375c51f124SMoriah Waterland 	}
21385c51f124SMoriah Waterland 
21395c51f124SMoriah Waterland 	if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
21405c51f124SMoriah Waterland 		return (R_ERROR);
21415c51f124SMoriah Waterland 	}
21425c51f124SMoriah Waterland 
21435c51f124SMoriah Waterland 	/* get current root path */
21445c51f124SMoriah Waterland 
21455c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
21465c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
21475c51f124SMoriah Waterland 		return (r);
21485c51f124SMoriah Waterland 	}
21495c51f124SMoriah Waterland 
21505c51f124SMoriah Waterland 	/* start of command debugging information */
21515c51f124SMoriah Waterland 
21525c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
21535c51f124SMoriah Waterland 
21545c51f124SMoriah Waterland 	/* search file system conf for this path */
21555c51f124SMoriah Waterland 
21565c51f124SMoriah Waterland 	rootPathLen = strlen(rootPath);
21575c51f124SMoriah Waterland 	list = a_gdt->gd_fileSystemConfig;
21585c51f124SMoriah Waterland 	listSize = a_gdt->gd_fileSystemConfigLen;
21595c51f124SMoriah Waterland 	for (nn = 0, n = 0; n < listSize; n++) {
21605c51f124SMoriah Waterland 		long	mplen = strlen(list[n].fsi_mntPoint);
21615c51f124SMoriah Waterland 		if (rootPathLen < mplen) {
21625c51f124SMoriah Waterland 			/* root path is longer than target, ignore */
21635c51f124SMoriah Waterland 			continue;
21645c51f124SMoriah Waterland 		}
21655c51f124SMoriah Waterland 		if (strncmp(rootPath, list[n].fsi_mntPoint, mplen) == 0) {
21665c51f124SMoriah Waterland 			/* remember last partial match */
21675c51f124SMoriah Waterland 			nn = n;
21685c51f124SMoriah Waterland 		}
21695c51f124SMoriah Waterland 	}
21705c51f124SMoriah Waterland 
21715c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_PWRT_INFO,
21725c51f124SMoriah Waterland 		rootPath, list[nn].fsi_mntPoint, list[nn].fsi_fsType,
21735c51f124SMoriah Waterland 		list[nn].fsi_mntOptions);
21745c51f124SMoriah Waterland 
21755c51f124SMoriah Waterland 	/*
21765c51f124SMoriah Waterland 	 * need to determine if the mount point is writeable:
21775c51f124SMoriah Waterland 	 */
21785c51f124SMoriah Waterland 
21795c51f124SMoriah Waterland 	/* see if the file system is mounted with the "read only" option */
21805c51f124SMoriah Waterland 
21815c51f124SMoriah Waterland 	r = mountOptionPresent(list[nn].fsi_mntOptions, MNTOPT_RO);
21825c51f124SMoriah Waterland 	if (r == R_SUCCESS) {
21835c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_PWRT_READONLY,
21845c51f124SMoriah Waterland 			rootPath, list[nn].fsi_mntOptions);
21855c51f124SMoriah Waterland 		return (R_FAILURE);
21865c51f124SMoriah Waterland 	}
21875c51f124SMoriah Waterland 
21885c51f124SMoriah Waterland 	/* target path is writable */
21895c51f124SMoriah Waterland 
21905c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_PWRT_IS, rootPath);
21915c51f124SMoriah Waterland 
21925c51f124SMoriah Waterland 	return (R_SUCCESS);
21935c51f124SMoriah Waterland }
21945c51f124SMoriah Waterland 
21955c51f124SMoriah Waterland /*
21965c51f124SMoriah Waterland  * Name:	cmd_is_alternative_root
21975c51f124SMoriah Waterland  * Description:	determine if target is an alternative root
21985c51f124SMoriah Waterland  * Scope:	public
21995c51f124SMoriah Waterland  * Arguments:	argc,argv:
22005c51f124SMoriah Waterland  *		  - optional path to target to test
22015c51f124SMoriah Waterland  * Returns:	int
22025c51f124SMoriah Waterland  *			== 0 - success
22035c51f124SMoriah Waterland  *			!= 0 - failure
22045c51f124SMoriah Waterland  * Implementation:
22055c51f124SMoriah Waterland  *  - success if an initial installation to the install root
22065c51f124SMoriah Waterland  *	(an initial install to $PKG_INSTALL_ROOT means that $PKG_INSTALL_ROOT
22075c51f124SMoriah Waterland  *	points to an alternative root that is under construction)
22085c51f124SMoriah Waterland  *  - must not be installation of a zone
22095c51f124SMoriah Waterland  *  - must not be a boot environment
22105c51f124SMoriah Waterland  *  - must not be a diskless client
22115c51f124SMoriah Waterland  *  - must not be a mounted miniroot
22125c51f124SMoriah Waterland  *  - must not be a netinstall image
22135c51f124SMoriah Waterland  *  - must not be a nonglobal zone
22145c51f124SMoriah Waterland  *  - must not be a running system
22155c51f124SMoriah Waterland  *  - $ROOTDIR must not be "/"
22165c51f124SMoriah Waterland  *  - $ROOTDIR/var must exist
22175c51f124SMoriah Waterland  */
22185c51f124SMoriah Waterland 
22195c51f124SMoriah Waterland static int
cmd_is_alternative_root(int argc,char ** argv,GLOBALDATA_T * a_gdt)22205c51f124SMoriah Waterland cmd_is_alternative_root(int argc, char **argv, GLOBALDATA_T *a_gdt)
22215c51f124SMoriah Waterland {
22225c51f124SMoriah Waterland 	char	*rootPath = NULL;
22235c51f124SMoriah Waterland 	int	c;
22245c51f124SMoriah Waterland 	int	r;
22255c51f124SMoriah Waterland static	char	*cmdName = "is_alternative_root";
22265c51f124SMoriah Waterland static	int	recursion = 0;
22275c51f124SMoriah Waterland 
22285c51f124SMoriah Waterland 	/* process any command line options */
22295c51f124SMoriah Waterland 
22305c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
22315c51f124SMoriah Waterland 		switch (c) {
22325c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
22335c51f124SMoriah Waterland 			break;
22345c51f124SMoriah Waterland 		case '?':
22355c51f124SMoriah Waterland 		default:
22365c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
22375c51f124SMoriah Waterland 			return (R_USAGE);
22385c51f124SMoriah Waterland 		}
22395c51f124SMoriah Waterland 	}
22405c51f124SMoriah Waterland 
22415c51f124SMoriah Waterland 	/* prevent recursion */
22425c51f124SMoriah Waterland 
22435c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
22445c51f124SMoriah Waterland 
22455c51f124SMoriah Waterland 		/*
22465c51f124SMoriah Waterland 		 * an alternative root cannot be any of the following
22475c51f124SMoriah Waterland 		 */
22485c51f124SMoriah Waterland 
22495c51f124SMoriah Waterland 		/* cannot be a boot_environment */
22505c51f124SMoriah Waterland 
22515c51f124SMoriah Waterland 		r = cmd_is_boot_environment(argc, argv, a_gdt);
22525c51f124SMoriah Waterland 
22535c51f124SMoriah Waterland 		/* cannot be a diskless_client */
22545c51f124SMoriah Waterland 
22555c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
22565c51f124SMoriah Waterland 			r = cmd_is_diskless_client(argc, argv, a_gdt);
22575c51f124SMoriah Waterland 		}
22585c51f124SMoriah Waterland 
22595c51f124SMoriah Waterland 		/* cannot be a mounted_miniroot */
22605c51f124SMoriah Waterland 
22615c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
22625c51f124SMoriah Waterland 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
22635c51f124SMoriah Waterland 		}
22645c51f124SMoriah Waterland 
22655c51f124SMoriah Waterland 		/* cannot be a netinstall_image */
22665c51f124SMoriah Waterland 
22675c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
22685c51f124SMoriah Waterland 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
22695c51f124SMoriah Waterland 		}
22705c51f124SMoriah Waterland 
22715c51f124SMoriah Waterland 		/* cannot be a nonglobal_zone */
22725c51f124SMoriah Waterland 
22735c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
22745c51f124SMoriah Waterland 			r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
22755c51f124SMoriah Waterland 		}
22765c51f124SMoriah Waterland 
22775c51f124SMoriah Waterland 		/* cannot be a running_system */
22785c51f124SMoriah Waterland 
22795c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
22805c51f124SMoriah Waterland 			r = cmd_is_running_system(argc, argv, a_gdt);
22815c51f124SMoriah Waterland 		}
22825c51f124SMoriah Waterland 
22835c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
22845c51f124SMoriah Waterland 
22855c51f124SMoriah Waterland 		recursion--;
22865c51f124SMoriah Waterland 
22875c51f124SMoriah Waterland 		/* return failure if any of the preceeding are true */
22885c51f124SMoriah Waterland 
22895c51f124SMoriah Waterland 		switch (r) {
22905c51f124SMoriah Waterland 			case R_SUCCESS:
22915c51f124SMoriah Waterland 				return (R_FAILURE);
22925c51f124SMoriah Waterland 			case R_FAILURE:
22935c51f124SMoriah Waterland 				break;
22945c51f124SMoriah Waterland 			case R_USAGE:
22955c51f124SMoriah Waterland 			case R_ERROR:
22965c51f124SMoriah Waterland 			default:
22975c51f124SMoriah Waterland 				return (r);
22985c51f124SMoriah Waterland 		}
22995c51f124SMoriah Waterland 	}
23005c51f124SMoriah Waterland 
23015c51f124SMoriah Waterland 	/* normalize argc/argv */
23025c51f124SMoriah Waterland 
23035c51f124SMoriah Waterland 	argc -= optind;
23045c51f124SMoriah Waterland 	argv += optind;
23055c51f124SMoriah Waterland 
23065c51f124SMoriah Waterland 	/* error if more than one argument */
23075c51f124SMoriah Waterland 
23085c51f124SMoriah Waterland 	if (argc > 1) {
23095c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
23105c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
23115c51f124SMoriah Waterland 		return (R_USAGE);
23125c51f124SMoriah Waterland 	}
23135c51f124SMoriah Waterland 
23145c51f124SMoriah Waterland 	/* process root path if first argument present */
23155c51f124SMoriah Waterland 
23165c51f124SMoriah Waterland 	if (argc == 1) {
23175c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
23185c51f124SMoriah Waterland 			return (R_ERROR);
23195c51f124SMoriah Waterland 		}
23205c51f124SMoriah Waterland 	}
23215c51f124SMoriah Waterland 
23225c51f124SMoriah Waterland 	/* get current root path */
23235c51f124SMoriah Waterland 
23245c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
23255c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
23265c51f124SMoriah Waterland 		return (r);
23275c51f124SMoriah Waterland 	}
23285c51f124SMoriah Waterland 
23295c51f124SMoriah Waterland 	/* start of command debugging information */
23305c51f124SMoriah Waterland 
23315c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
23325c51f124SMoriah Waterland 
23335c51f124SMoriah Waterland 	/* return success if initial installation */
23345c51f124SMoriah Waterland 
23355c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
23365c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
23375c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IALR_INITIAL_INSTALL, rootPath);
23385c51f124SMoriah Waterland 		return (R_SUCCESS);
23395c51f124SMoriah Waterland 	}
23405c51f124SMoriah Waterland 
23415c51f124SMoriah Waterland 	/* root path must not be "/" */
23425c51f124SMoriah Waterland 
23435c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") == 0) {
23445c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IALR_BAD_ROOTPATH, rootPath, "/");
23455c51f124SMoriah Waterland 		return (R_FAILURE);
23465c51f124SMoriah Waterland 	}
23475c51f124SMoriah Waterland 
23485c51f124SMoriah Waterland 	/* /var must exist */
23495c51f124SMoriah Waterland 
23505c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS,
23515c51f124SMoriah Waterland 		"%s/%s", rootPath, "/var");
23525c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
23535c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IALR_PATH_DOES_NOT_EXIST,
23545c51f124SMoriah Waterland 			rootPath, "/var");
23555c51f124SMoriah Waterland 		return (R_FAILURE);
23565c51f124SMoriah Waterland 	}
23575c51f124SMoriah Waterland 
23585c51f124SMoriah Waterland 	/* must not be installation of a zone */
23595c51f124SMoriah Waterland 
23605c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
23615c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
23625c51f124SMoriah Waterland 		/* initial zone install: no path can be alternative root */
23635c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_IALR_ZONE_INSTALL, rootPath);
23645c51f124SMoriah Waterland 		return (R_FAILURE);
23655c51f124SMoriah Waterland 	}
23665c51f124SMoriah Waterland 
23675c51f124SMoriah Waterland 	/* target is an alternative root */
23685c51f124SMoriah Waterland 
23695c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_IALR_IS, rootPath);
23705c51f124SMoriah Waterland 
23715c51f124SMoriah Waterland 	return (R_SUCCESS);
23725c51f124SMoriah Waterland }
23735c51f124SMoriah Waterland 
23745c51f124SMoriah Waterland /*
23755c51f124SMoriah Waterland  * Name:	cmd_is_boot_environment
23765c51f124SMoriah Waterland  * Description:	determine if target is an alternative, inactive boot environment
23775c51f124SMoriah Waterland  * Scope:	public
23785c51f124SMoriah Waterland  * Arguments:	argc,argv:
23795c51f124SMoriah Waterland  *		  - optional path to target to test
23805c51f124SMoriah Waterland  * Returns:	int
23815c51f124SMoriah Waterland  *			== 0 - success
23825c51f124SMoriah Waterland  *			!= 0 - failure
23835c51f124SMoriah Waterland  * IMPLEMENTATION:
23845c51f124SMoriah Waterland  *  - must not be initial installation to the install root
23855c51f124SMoriah Waterland  *  - must not be installation of a zone
23865c51f124SMoriah Waterland  *  - must not be a diskless client
23875c51f124SMoriah Waterland  *  - must not be a netinstall image
23885c51f124SMoriah Waterland  *  - must not be a mounted miniroot
23895c51f124SMoriah Waterland  *  - $ROOTDIR must not be "/"
23905c51f124SMoriah Waterland  *  - $ROOTDIR/etc/lutab must exist
23915c51f124SMoriah Waterland  *  - $ROOTDIR/etc/lu must exist and must be a directory
23925c51f124SMoriah Waterland  */
23935c51f124SMoriah Waterland 
23945c51f124SMoriah Waterland static int
cmd_is_boot_environment(int argc,char ** argv,GLOBALDATA_T * a_gdt)23955c51f124SMoriah Waterland cmd_is_boot_environment(int argc, char **argv, GLOBALDATA_T *a_gdt)
23965c51f124SMoriah Waterland {
23975c51f124SMoriah Waterland 	char	*rootPath = NULL;
23985c51f124SMoriah Waterland 	int	c;
23995c51f124SMoriah Waterland 	int	r;
24005c51f124SMoriah Waterland static	char	*cmdName = "is_boot_environment";
24015c51f124SMoriah Waterland static	int	recursion = 0;
24025c51f124SMoriah Waterland 
24035c51f124SMoriah Waterland 	/* process any command line options */
24045c51f124SMoriah Waterland 
24055c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
24065c51f124SMoriah Waterland 		switch (c) {
24075c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
24085c51f124SMoriah Waterland 			break;
24095c51f124SMoriah Waterland 		case '?':
24105c51f124SMoriah Waterland 		default:
24115c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
24125c51f124SMoriah Waterland 			return (R_USAGE);
24135c51f124SMoriah Waterland 		}
24145c51f124SMoriah Waterland 	}
24155c51f124SMoriah Waterland 
24165c51f124SMoriah Waterland 	/* prevent recursion */
24175c51f124SMoriah Waterland 
24185c51f124SMoriah Waterland 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
24195c51f124SMoriah Waterland 		/*
24205c51f124SMoriah Waterland 		 * a boot environment cannot be any of the following
24215c51f124SMoriah Waterland 		 */
24225c51f124SMoriah Waterland 
24235c51f124SMoriah Waterland 		/* cannot be a diskless client */
24245c51f124SMoriah Waterland 
24255c51f124SMoriah Waterland 		r = cmd_is_diskless_client(argc, argv, a_gdt);
24265c51f124SMoriah Waterland 
24275c51f124SMoriah Waterland 		/* cannot be a netinstall_image */
24285c51f124SMoriah Waterland 
24295c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
24305c51f124SMoriah Waterland 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
24315c51f124SMoriah Waterland 		}
24325c51f124SMoriah Waterland 
24335c51f124SMoriah Waterland 		/* cannot be a mounted_miniroot */
24345c51f124SMoriah Waterland 
24355c51f124SMoriah Waterland 		if (r != R_SUCCESS) {
24365c51f124SMoriah Waterland 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
24375c51f124SMoriah Waterland 		}
24385c51f124SMoriah Waterland 
24395c51f124SMoriah Waterland 		/* no need to guard against recursion any more */
24405c51f124SMoriah Waterland 
24415c51f124SMoriah Waterland 		recursion--;
24425c51f124SMoriah Waterland 
24435c51f124SMoriah Waterland 		/* return failure if any of the preceeding are true */
24445c51f124SMoriah Waterland 
24455c51f124SMoriah Waterland 		switch (r) {
24465c51f124SMoriah Waterland 			case R_SUCCESS:
24475c51f124SMoriah Waterland 				return (R_FAILURE);
24485c51f124SMoriah Waterland 			case R_FAILURE:
24495c51f124SMoriah Waterland 				break;
24505c51f124SMoriah Waterland 			case R_USAGE:
24515c51f124SMoriah Waterland 			case R_ERROR:
24525c51f124SMoriah Waterland 			default:
24535c51f124SMoriah Waterland 				return (r);
24545c51f124SMoriah Waterland 		}
24555c51f124SMoriah Waterland 	}
24565c51f124SMoriah Waterland 
24575c51f124SMoriah Waterland 	/* normalize argc/argv */
24585c51f124SMoriah Waterland 
24595c51f124SMoriah Waterland 	argc -= optind;
24605c51f124SMoriah Waterland 	argv += optind;
24615c51f124SMoriah Waterland 
24625c51f124SMoriah Waterland 	/* error if more than one argument */
24635c51f124SMoriah Waterland 
24645c51f124SMoriah Waterland 	if (argc > 1) {
24655c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
24665c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
24675c51f124SMoriah Waterland 		return (R_USAGE);
24685c51f124SMoriah Waterland 	}
24695c51f124SMoriah Waterland 
24705c51f124SMoriah Waterland 	/* process root path if first argument present */
24715c51f124SMoriah Waterland 
24725c51f124SMoriah Waterland 	if (argc == 1) {
24735c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
24745c51f124SMoriah Waterland 			return (R_ERROR);
24755c51f124SMoriah Waterland 		}
24765c51f124SMoriah Waterland 	}
24775c51f124SMoriah Waterland 
24785c51f124SMoriah Waterland 	/* get current root path */
24795c51f124SMoriah Waterland 
24805c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
24815c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
24825c51f124SMoriah Waterland 		return (r);
24835c51f124SMoriah Waterland 	}
24845c51f124SMoriah Waterland 
24855c51f124SMoriah Waterland 	/* start of command debugging information */
24865c51f124SMoriah Waterland 
24875c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
24885c51f124SMoriah Waterland 
24895c51f124SMoriah Waterland 	/* root path must not be "/" */
24905c51f124SMoriah Waterland 
24915c51f124SMoriah Waterland 	if (strcmp(rootPath, "/") == 0) {
24925c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ROOTPATH, rootPath, "/");
24935c51f124SMoriah Waterland 		return (R_FAILURE);
24945c51f124SMoriah Waterland 	}
24955c51f124SMoriah Waterland 
24965c51f124SMoriah Waterland 	/* zone name must be global */
24975c51f124SMoriah Waterland 
24985c51f124SMoriah Waterland 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
24995c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ZONE, rootPath,
25005c51f124SMoriah Waterland 			GLOBAL_ZONENAME);
25015c51f124SMoriah Waterland 		return (R_FAILURE);
25025c51f124SMoriah Waterland 	}
25035c51f124SMoriah Waterland 
25045c51f124SMoriah Waterland 	/* $ROOTDIR/etc/lutab must exist */
25055c51f124SMoriah Waterland 
25065c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/lutab");
25075c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
25085c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLUTAB, rootPath,
25095c51f124SMoriah Waterland 			"/etc/lutab");
25105c51f124SMoriah Waterland 		return (R_FAILURE);
25115c51f124SMoriah Waterland 	}
25125c51f124SMoriah Waterland 
25135c51f124SMoriah Waterland 	/* $ROOTDIR/etc/lu must exist */
25145c51f124SMoriah Waterland 
25155c51f124SMoriah Waterland 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
25165c51f124SMoriah Waterland 		"%s/%s", rootPath, "/etc/lu");
25175c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
25185c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLU, rootPath, "/etc/lu");
25195c51f124SMoriah Waterland 		return (R_FAILURE);
25205c51f124SMoriah Waterland 	}
25215c51f124SMoriah Waterland 
25225c51f124SMoriah Waterland 	/* must not be initial installation */
25235c51f124SMoriah Waterland 
25245c51f124SMoriah Waterland 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
25255c51f124SMoriah Waterland 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
25265c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_INITIAL_INSTALL, rootPath);
25275c51f124SMoriah Waterland 		return (R_FAILURE);
25285c51f124SMoriah Waterland 	}
25295c51f124SMoriah Waterland 
25305c51f124SMoriah Waterland 	/* must not be installation of a zone */
25315c51f124SMoriah Waterland 
25325c51f124SMoriah Waterland 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
25335c51f124SMoriah Waterland 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
25345c51f124SMoriah Waterland 		/* initial zone install: no path can be boot environment */
25355c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_BENV_ZONE_INSTALL, rootPath);
25365c51f124SMoriah Waterland 		return (R_FAILURE);
25375c51f124SMoriah Waterland 	}
25385c51f124SMoriah Waterland 
25395c51f124SMoriah Waterland 	/* target is a boot environment */
25405c51f124SMoriah Waterland 
25415c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_BENV_IS, rootPath);
25425c51f124SMoriah Waterland 
25435c51f124SMoriah Waterland 	return (R_SUCCESS);
25445c51f124SMoriah Waterland }
25455c51f124SMoriah Waterland 
25465c51f124SMoriah Waterland /*
25475c51f124SMoriah Waterland  * Name:	cmd_is_what
25485c51f124SMoriah Waterland  * Description:	determine what the target is
25495c51f124SMoriah Waterland  * Scope:	public
25505c51f124SMoriah Waterland  * Arguments:	argc,argv:
25515c51f124SMoriah Waterland  *		  - optional path to target to test
25525c51f124SMoriah Waterland  * Returns:	int
25535c51f124SMoriah Waterland  *			== 0 - success
25545c51f124SMoriah Waterland  *			!= 0 - failure
25555c51f124SMoriah Waterland  */
25565c51f124SMoriah Waterland 
25575c51f124SMoriah Waterland static int
cmd_is_what(int argc,char ** argv,GLOBALDATA_T * a_gdt)25585c51f124SMoriah Waterland cmd_is_what(int argc, char **argv, GLOBALDATA_T *a_gdt)
25595c51f124SMoriah Waterland {
25605c51f124SMoriah Waterland 	char	*rootPath = NULL;
25615c51f124SMoriah Waterland 	int	c;
25625c51f124SMoriah Waterland 	int	cur_cmd;
25635c51f124SMoriah Waterland 	int	r;
25645c51f124SMoriah Waterland static	char	*cmdName = "is_what";
25655c51f124SMoriah Waterland 
25665c51f124SMoriah Waterland 	/* process any command line options */
25675c51f124SMoriah Waterland 
25685c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, ":")) != EOF) {
25695c51f124SMoriah Waterland 		switch (c) {
25705c51f124SMoriah Waterland 		case '\0':	/* prevent end-of-loop not reached warning */
25715c51f124SMoriah Waterland 			break;
25725c51f124SMoriah Waterland 		case '?':
25735c51f124SMoriah Waterland 		default:
25745c51f124SMoriah Waterland 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
25755c51f124SMoriah Waterland 			return (R_USAGE);
25765c51f124SMoriah Waterland 		}
25775c51f124SMoriah Waterland 	}
25785c51f124SMoriah Waterland 
25795c51f124SMoriah Waterland 	/* normalize argc/argv */
25805c51f124SMoriah Waterland 
25815c51f124SMoriah Waterland 	argc -= optind;
25825c51f124SMoriah Waterland 	argv += optind;
25835c51f124SMoriah Waterland 
25845c51f124SMoriah Waterland 	/* error if more than one argument */
25855c51f124SMoriah Waterland 
25865c51f124SMoriah Waterland 	if (argc > 1) {
25875c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
25885c51f124SMoriah Waterland 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
25895c51f124SMoriah Waterland 		return (R_USAGE);
25905c51f124SMoriah Waterland 	}
25915c51f124SMoriah Waterland 
25925c51f124SMoriah Waterland 	/* process root path if first argument present */
25935c51f124SMoriah Waterland 
25945c51f124SMoriah Waterland 	if (argc == 1) {
25955c51f124SMoriah Waterland 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
25965c51f124SMoriah Waterland 			return (R_ERROR);
25975c51f124SMoriah Waterland 		}
25985c51f124SMoriah Waterland 	}
25995c51f124SMoriah Waterland 
26005c51f124SMoriah Waterland 	/* get current root path */
26015c51f124SMoriah Waterland 
26025c51f124SMoriah Waterland 	r = getRootPath(&rootPath);
26035c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
26045c51f124SMoriah Waterland 		return (r);
26055c51f124SMoriah Waterland 	}
26065c51f124SMoriah Waterland 
26075c51f124SMoriah Waterland 	/*
26085c51f124SMoriah Waterland 	 * construct the command line for all of the packages
26095c51f124SMoriah Waterland 	 */
26105c51f124SMoriah Waterland 
26115c51f124SMoriah Waterland 	argc = 0;
26125c51f124SMoriah Waterland 	argv[argc++] = strdup(get_prog_name());
26135c51f124SMoriah Waterland 	argv[argc++] = strdup(rootPath);
26145c51f124SMoriah Waterland 
26155c51f124SMoriah Waterland 	/* start of command debugging information */
26165c51f124SMoriah Waterland 
26175c51f124SMoriah Waterland 	echoDebug(DBG_ROOTPATH_IS, rootPath);
26185c51f124SMoriah Waterland 
26195c51f124SMoriah Waterland 	/* search for specified subcommand and execute if found */
26205c51f124SMoriah Waterland 
26215c51f124SMoriah Waterland 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
26225c51f124SMoriah Waterland 		int	result;
26235c51f124SMoriah Waterland 
26245c51f124SMoriah Waterland 		/* do not recursively call this function */
26255c51f124SMoriah Waterland 
26265c51f124SMoriah Waterland 		if (cmds[cur_cmd].c_func == cmd_is_what) {
26275c51f124SMoriah Waterland 			continue;
26285c51f124SMoriah Waterland 		}
26295c51f124SMoriah Waterland 
26305c51f124SMoriah Waterland 		/* call subcommand with its own argc/argv */
26315c51f124SMoriah Waterland 
26325c51f124SMoriah Waterland 		result = cmds[cur_cmd].c_func(argc, argv, a_gdt);
26335c51f124SMoriah Waterland 
26345c51f124SMoriah Waterland 		/* process result code and exit */
26355c51f124SMoriah Waterland 
26365c51f124SMoriah Waterland 		result = adjustResults(result);
26375c51f124SMoriah Waterland 		log_msg(LOG_MSG_INFO, MSG_IS_WHAT_RESULT,
26385c51f124SMoriah Waterland 			cmds[cur_cmd].c_name, result);
26395c51f124SMoriah Waterland 	}
26405c51f124SMoriah Waterland 	return (R_SUCCESS);
26415c51f124SMoriah Waterland }
26425c51f124SMoriah Waterland 
26435c51f124SMoriah Waterland /*
26445c51f124SMoriah Waterland  * *****************************************************************************
26455c51f124SMoriah Waterland  * utility support functions
26465c51f124SMoriah Waterland  * *****************************************************************************
26475c51f124SMoriah Waterland  */
26485c51f124SMoriah Waterland 
26495c51f124SMoriah Waterland /*
26505c51f124SMoriah Waterland  * Name:	getMountOption
26515c51f124SMoriah Waterland  * Description:	return next mount option in a string
26525c51f124SMoriah Waterland  * Arguments:	p - pointer to string containing mount options
26535c51f124SMoriah Waterland  * Output:	none
26545c51f124SMoriah Waterland  * Returns:	char * - pointer to next option in string "p"
26555c51f124SMoriah Waterland  * Side Effects: advances input "p" and inserts \0 in place of the
26565c51f124SMoriah Waterland  *		option separator found.
26575c51f124SMoriah Waterland  */
26585c51f124SMoriah Waterland 
26595c51f124SMoriah Waterland static char *
getMountOption(char ** p)26605c51f124SMoriah Waterland getMountOption(char **p)
26615c51f124SMoriah Waterland {
26625c51f124SMoriah Waterland 	char *cp = *p;
26635c51f124SMoriah Waterland 	char *retstr;
26645c51f124SMoriah Waterland 
26655c51f124SMoriah Waterland 	/* advance past all white space */
26665c51f124SMoriah Waterland 
26675c51f124SMoriah Waterland 	while (*cp && isspace(*cp))
26685c51f124SMoriah Waterland 		cp++;
26695c51f124SMoriah Waterland 
26705c51f124SMoriah Waterland 	/* remember start of next option */
26715c51f124SMoriah Waterland 
26725c51f124SMoriah Waterland 	retstr = cp;
26735c51f124SMoriah Waterland 
26745c51f124SMoriah Waterland 	/* advance to end of string or option separator */
26755c51f124SMoriah Waterland 
26765c51f124SMoriah Waterland 	while (*cp && *cp != ',')
26775c51f124SMoriah Waterland 		cp++;
26785c51f124SMoriah Waterland 
26795c51f124SMoriah Waterland 	/* replace separator with '\0' if not at end of string */
26805c51f124SMoriah Waterland 	if (*cp) {
26815c51f124SMoriah Waterland 		*cp = '\0';
26825c51f124SMoriah Waterland 		cp++;
26835c51f124SMoriah Waterland 	}
26845c51f124SMoriah Waterland 
26855c51f124SMoriah Waterland 	/* reset caller's pointer and return pointer to option */
26865c51f124SMoriah Waterland 
26875c51f124SMoriah Waterland 	*p = cp;
26885c51f124SMoriah Waterland 	return (retstr);
26895c51f124SMoriah Waterland }
26905c51f124SMoriah Waterland 
26915c51f124SMoriah Waterland /*
26925c51f124SMoriah Waterland  * Name:	mountOptionPresent
26935c51f124SMoriah Waterland  * Description:	determine if specified mount option is present in list
26945c51f124SMoriah Waterland  *		of mount point options
26955c51f124SMoriah Waterland  * Arguments:	a_mntOptions - pointer to string containing list of mount
26965c51f124SMoriah Waterland  *			point options to search
26975c51f124SMoriah Waterland  *		a_opt - pointer to string containing option to search for
26985c51f124SMoriah Waterland  * Output:	none
26995c51f124SMoriah Waterland  * Returns:	R_SUCCESS - option is present in list of mount point options
27005c51f124SMoriah Waterland  *		R_FAILURE - options is not present
27015c51f124SMoriah Waterland  *		R_ERROR - unable to determine if option is present or not
27025c51f124SMoriah Waterland  */
27035c51f124SMoriah Waterland 
27045c51f124SMoriah Waterland static int
mountOptionPresent(char * a_mntOptions,char * a_opt)27055c51f124SMoriah Waterland mountOptionPresent(char *a_mntOptions, char *a_opt)
27065c51f124SMoriah Waterland {
27075c51f124SMoriah Waterland 	char tmpopts[MNT_LINE_MAX];
27085c51f124SMoriah Waterland 	char *f, *opts = tmpopts;
27095c51f124SMoriah Waterland 
27105c51f124SMoriah Waterland 	/* return false if no mount options present */
27115c51f124SMoriah Waterland 
27125c51f124SMoriah Waterland 	if ((a_opt == NULL) || (*a_opt == '\0')) {
27135c51f124SMoriah Waterland 		return (R_FAILURE);
27145c51f124SMoriah Waterland 	}
27155c51f124SMoriah Waterland 
27165c51f124SMoriah Waterland 	/* return not present if no list of options to search */
27175c51f124SMoriah Waterland 
27185c51f124SMoriah Waterland 	if (a_mntOptions == NULL) {
27195c51f124SMoriah Waterland 		return (R_FAILURE);
27205c51f124SMoriah Waterland 	}
27215c51f124SMoriah Waterland 
27225c51f124SMoriah Waterland 	/* return not present if list of options to search is empty */
27235c51f124SMoriah Waterland 
27245c51f124SMoriah Waterland 	if (*a_mntOptions == '\0') {
27255c51f124SMoriah Waterland 		return (R_FAILURE);
27265c51f124SMoriah Waterland 	}
27275c51f124SMoriah Waterland 
27285c51f124SMoriah Waterland 	/* make local copy of option list to search */
27295c51f124SMoriah Waterland 
27305c51f124SMoriah Waterland 	(void) strcpy(opts, a_mntOptions);
27315c51f124SMoriah Waterland 
27325c51f124SMoriah Waterland 	/* scan each option looking for the specified option */
27335c51f124SMoriah Waterland 
27345c51f124SMoriah Waterland 	f = getMountOption(&opts);
27355c51f124SMoriah Waterland 	for (; *f; f = getMountOption(&opts)) {
27365c51f124SMoriah Waterland 		/* return success if option matches target */
27375c51f124SMoriah Waterland 		if (strncmp(a_opt, f, strlen(a_opt)) == 0) {
27385c51f124SMoriah Waterland 			return (R_SUCCESS);
27395c51f124SMoriah Waterland 		}
27405c51f124SMoriah Waterland 	}
27415c51f124SMoriah Waterland 
27425c51f124SMoriah Waterland 	/* option not found */
27435c51f124SMoriah Waterland 
27445c51f124SMoriah Waterland 	return (R_FAILURE);
27455c51f124SMoriah Waterland }
27465c51f124SMoriah Waterland 
27475c51f124SMoriah Waterland /*
27485c51f124SMoriah Waterland  * Name:	sortedInsert
27495c51f124SMoriah Waterland  * Description:	perform an alphabetical sorted insert into a list
27505c51f124SMoriah Waterland  * Arguments:	r_list - pointer to list to insert next entry into
27515c51f124SMoriah Waterland  *		a_listSize - pointer to current list size
27525c51f124SMoriah Waterland  *		a_mntPoint - mount point to insert (is sort key)
27535c51f124SMoriah Waterland  *		a_fsType - file system type for mount point
27545c51f124SMoriah Waterland  *		a_mntOptions - file syste mount options for mount point
27555c51f124SMoriah Waterland  * Output:	None
27565c51f124SMoriah Waterland  * Returns:	None
27575c51f124SMoriah Waterland  */
27585c51f124SMoriah Waterland 
27595c51f124SMoriah Waterland static void
sortedInsert(FSI_T ** r_list,long * a_listSize,char * a_mntPoint,char * a_fsType,char * a_mntOptions)27605c51f124SMoriah Waterland sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint,
27615c51f124SMoriah Waterland 	char *a_fsType, char *a_mntOptions)
27625c51f124SMoriah Waterland {
27635c51f124SMoriah Waterland 	int	listSize;
27645c51f124SMoriah Waterland 	FSI_T	*list;
27655c51f124SMoriah Waterland 	int	n;
27665c51f124SMoriah Waterland 
27675c51f124SMoriah Waterland 	/* entry assertions */
27685c51f124SMoriah Waterland 
27695c51f124SMoriah Waterland 	assert(a_listSize != (long *)NULL);
27705c51f124SMoriah Waterland 	assert(a_mntPoint != NULL);
27715c51f124SMoriah Waterland 	assert(a_fsType != NULL);
27725c51f124SMoriah Waterland 	assert(a_mntOptions != NULL);
27735c51f124SMoriah Waterland 
27745c51f124SMoriah Waterland 	/* entry debugging info */
27755c51f124SMoriah Waterland 
27765c51f124SMoriah Waterland 	echoDebug(DBG_SINS_ENTRY, a_mntPoint, a_fsType, a_mntOptions);
27775c51f124SMoriah Waterland 
27785c51f124SMoriah Waterland 	/* localize references to the list and list size */
27795c51f124SMoriah Waterland 
27805c51f124SMoriah Waterland 	listSize = *a_listSize;
27815c51f124SMoriah Waterland 	list = *r_list;
27825c51f124SMoriah Waterland 
27835c51f124SMoriah Waterland 	/*
27845c51f124SMoriah Waterland 	 * if list empty insert this entry as the first one in the list
27855c51f124SMoriah Waterland 	 */
27865c51f124SMoriah Waterland 
27875c51f124SMoriah Waterland 	if (listSize == 0) {
27885c51f124SMoriah Waterland 		/* allocate new entry for list */
27895c51f124SMoriah Waterland 		listSize++;
27905c51f124SMoriah Waterland 		list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1));
27915c51f124SMoriah Waterland 
27925c51f124SMoriah Waterland 		/* first entry is data passed to this function */
27935c51f124SMoriah Waterland 		list[0].fsi_mntPoint = strdup(a_mntPoint);
27945c51f124SMoriah Waterland 		list[0].fsi_fsType = strdup(a_fsType);
27955c51f124SMoriah Waterland 		list[0].fsi_mntOptions = strdup(a_mntOptions);
27965c51f124SMoriah Waterland 
27975c51f124SMoriah Waterland 		/* second entry is all NULL - end of entry marker */
27985c51f124SMoriah Waterland 		list[1].fsi_mntPoint = NULL;
27995c51f124SMoriah Waterland 		list[1].fsi_fsType = NULL;
28005c51f124SMoriah Waterland 		list[1].fsi_mntOptions = NULL;
28015c51f124SMoriah Waterland 
28025c51f124SMoriah Waterland 		/* restore list and list size references to caller */
28035c51f124SMoriah Waterland 		*a_listSize = listSize;
28045c51f124SMoriah Waterland 		*r_list = list;
28055c51f124SMoriah Waterland 
28065c51f124SMoriah Waterland 		return;
28075c51f124SMoriah Waterland 	}
28085c51f124SMoriah Waterland 
28095c51f124SMoriah Waterland 	/*
28105c51f124SMoriah Waterland 	 * list not empty - scan looking for largest match
28115c51f124SMoriah Waterland 	 */
28125c51f124SMoriah Waterland 
28135c51f124SMoriah Waterland 	for (n = 0; n < listSize; n++) {
28145c51f124SMoriah Waterland 		int	c;
28155c51f124SMoriah Waterland 
28165c51f124SMoriah Waterland 		/* compare target with current list entry */
28175c51f124SMoriah Waterland 
28185c51f124SMoriah Waterland 		c = strcmp(list[n].fsi_mntPoint, a_mntPoint);
28195c51f124SMoriah Waterland 
28205c51f124SMoriah Waterland 		if (c == 0) {
28215c51f124SMoriah Waterland 			char	*me;
28225c51f124SMoriah Waterland 			long	len;
28235c51f124SMoriah Waterland 
28245c51f124SMoriah Waterland 			/* entry already in list -- merge entries */
28255c51f124SMoriah Waterland 
28265c51f124SMoriah Waterland 			len = strlen(list[n].fsi_mntOptions) +
28275c51f124SMoriah Waterland 				strlen(a_mntOptions) + 2;
28285c51f124SMoriah Waterland 			me = (char *)calloc(1, len);
28295c51f124SMoriah Waterland 
28305c51f124SMoriah Waterland 			/* merge two mount options lists into one */
28315c51f124SMoriah Waterland 
28325c51f124SMoriah Waterland 			(void) strlcat(me, list[n].fsi_mntOptions, len);
28335c51f124SMoriah Waterland 			(void) strlcat(me, ",", len);
28345c51f124SMoriah Waterland 			(void) strlcat(me, a_mntOptions, len);
28355c51f124SMoriah Waterland 
28365c51f124SMoriah Waterland 			/* free old list, replace with merged one */
28375c51f124SMoriah Waterland 
28385c51f124SMoriah Waterland 			free(list[n].fsi_mntOptions);
28395c51f124SMoriah Waterland 			list[n].fsi_mntOptions = me;
28405c51f124SMoriah Waterland 
28415c51f124SMoriah Waterland 			echoDebug(DBG_SORTEDINS_SKIPPED,
28425c51f124SMoriah Waterland 				n, list[n].fsi_mntPoint, a_fsType,
28435c51f124SMoriah Waterland 				list[n].fsi_fsType, a_mntOptions,
28445c51f124SMoriah Waterland 				list[n].fsi_mntOptions);
28455c51f124SMoriah Waterland 
28465c51f124SMoriah Waterland 			continue;
28475c51f124SMoriah Waterland 		} else if (c < 0) {
28485c51f124SMoriah Waterland 			/* entry before this one - skip */
28495c51f124SMoriah Waterland 			continue;
28505c51f124SMoriah Waterland 		}
28515c51f124SMoriah Waterland 
28525c51f124SMoriah Waterland 		/*
28535c51f124SMoriah Waterland 		 * entry after this one - insert new entry
28545c51f124SMoriah Waterland 		 */
28555c51f124SMoriah Waterland 
28565c51f124SMoriah Waterland 		/* allocate one more entry and make space for new entry */
28575c51f124SMoriah Waterland 		listSize++;
28585c51f124SMoriah Waterland 		list = (FSI_T *)realloc(list,
28595c51f124SMoriah Waterland 			sizeof (FSI_T)*(listSize+1));
28605c51f124SMoriah Waterland 		(void) memmove(&(list[n+1]), &(list[n]),
28615c51f124SMoriah Waterland 			sizeof (FSI_T)*(listSize-n));
28625c51f124SMoriah Waterland 
28635c51f124SMoriah Waterland 		/* insert this entry into list */
28645c51f124SMoriah Waterland 		list[n].fsi_mntPoint = strdup(a_mntPoint);
28655c51f124SMoriah Waterland 		list[n].fsi_fsType = strdup(a_fsType);
28665c51f124SMoriah Waterland 		list[n].fsi_mntOptions = strdup(a_mntOptions);
28675c51f124SMoriah Waterland 
28685c51f124SMoriah Waterland 		/* restore list and list size references to caller */
28695c51f124SMoriah Waterland 		*a_listSize = listSize;
28705c51f124SMoriah Waterland 		*r_list = list;
28715c51f124SMoriah Waterland 
28725c51f124SMoriah Waterland 		return;
28735c51f124SMoriah Waterland 	}
28745c51f124SMoriah Waterland 
28755c51f124SMoriah Waterland 	/*
28765c51f124SMoriah Waterland 	 * all entries are before this one - append to end of list
28775c51f124SMoriah Waterland 	 */
28785c51f124SMoriah Waterland 
28795c51f124SMoriah Waterland 	/* allocate new entry at end of list */
28805c51f124SMoriah Waterland 	listSize++;
28815c51f124SMoriah Waterland 	list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1));
28825c51f124SMoriah Waterland 
28835c51f124SMoriah Waterland 	/* append this entry to the end of the list */
28845c51f124SMoriah Waterland 	list[listSize-1].fsi_mntPoint = strdup(a_mntPoint);
28855c51f124SMoriah Waterland 	list[listSize-1].fsi_fsType = strdup(a_fsType);
28865c51f124SMoriah Waterland 	list[listSize-1].fsi_mntOptions = strdup(a_mntOptions);
28875c51f124SMoriah Waterland 
28885c51f124SMoriah Waterland 	/* restore list and list size references to caller */
28895c51f124SMoriah Waterland 	*a_listSize = listSize;
28905c51f124SMoriah Waterland 	*r_list = list;
28915c51f124SMoriah Waterland }
28925c51f124SMoriah Waterland 
28935c51f124SMoriah Waterland /*
28945c51f124SMoriah Waterland  * Name:	calculateFileSystemConfig
28955c51f124SMoriah Waterland  * Description:	generate sorted list of all mounted file systems
28965c51f124SMoriah Waterland  * Arguments:	a_gdt - global data structure to place sorted entries into
28975c51f124SMoriah Waterland  * Output:	None
28985c51f124SMoriah Waterland  * Returns:	R_SUCCESS - successfully generated mounted file systems list
28995c51f124SMoriah Waterland  *		R_FAILURE - options is not present
29005c51f124SMoriah Waterland  *		R_ERROR - unable to determine if option is present or not
29015c51f124SMoriah Waterland  */
29025c51f124SMoriah Waterland 
29035c51f124SMoriah Waterland static int
calculateFileSystemConfig(GLOBALDATA_T * a_gdt)29045c51f124SMoriah Waterland calculateFileSystemConfig(GLOBALDATA_T *a_gdt)
29055c51f124SMoriah Waterland {
29065c51f124SMoriah Waterland 	FILE		*fp;
29075c51f124SMoriah Waterland 	struct mnttab	mntbuf;
29085c51f124SMoriah Waterland 	FSI_T		*list;
29095c51f124SMoriah Waterland 	long		listSize;
29105c51f124SMoriah Waterland 
29115c51f124SMoriah Waterland 	/* entry assetions */
29125c51f124SMoriah Waterland 
29135c51f124SMoriah Waterland 	assert(a_gdt != (GLOBALDATA_T *)NULL);
29145c51f124SMoriah Waterland 
29155c51f124SMoriah Waterland 	/* allocate a list that has one termination entry */
29165c51f124SMoriah Waterland 
29175c51f124SMoriah Waterland 	list = (FSI_T *)calloc(1, sizeof (FSI_T));
29185c51f124SMoriah Waterland 	list[0].fsi_mntPoint = NULL;
29195c51f124SMoriah Waterland 	list[0].fsi_fsType = NULL;
29205c51f124SMoriah Waterland 	list[0].fsi_mntOptions = NULL;
29215c51f124SMoriah Waterland 	listSize = 0;
29225c51f124SMoriah Waterland 
29235c51f124SMoriah Waterland 	/* open the mount table for reading */
29245c51f124SMoriah Waterland 
29255c51f124SMoriah Waterland 	fp = fopen(MNTTAB, "r");
29265c51f124SMoriah Waterland 	if (fp == (FILE *)NULL) {
29275c51f124SMoriah Waterland 		return (R_ERROR);
29285c51f124SMoriah Waterland 	}
29295c51f124SMoriah Waterland 
29305c51f124SMoriah Waterland 	/* debugging info */
29315c51f124SMoriah Waterland 
29325c51f124SMoriah Waterland 	echoDebug(DBG_CALCSCFG_MOUNTED);
29335c51f124SMoriah Waterland 
29345c51f124SMoriah Waterland 	/* go through all the specials looking for the device */
29355c51f124SMoriah Waterland 
29365c51f124SMoriah Waterland 	while (getmntent(fp, &mntbuf) == 0) {
29375c51f124SMoriah Waterland 		if (mntbuf.mnt_mountp[0] == '/') {
29385c51f124SMoriah Waterland 			sortedInsert(&list, &listSize,
29395c51f124SMoriah Waterland 			strdup(mntbuf.mnt_mountp),
29405c51f124SMoriah Waterland 			strdup(mntbuf.mnt_fstype),
29415c51f124SMoriah Waterland 			strdup(mntbuf.mnt_mntopts ? mntbuf.mnt_mntopts : ""));
29425c51f124SMoriah Waterland 		}
29435c51f124SMoriah Waterland 
29445c51f124SMoriah Waterland 		/*
29455c51f124SMoriah Waterland 		 * Set flag if we are in a non-global zone and it is in
29465c51f124SMoriah Waterland 		 * the mounted state.
29475c51f124SMoriah Waterland 		 */
29485c51f124SMoriah Waterland 
29495c51f124SMoriah Waterland 		if (strcmp(mntbuf.mnt_mountp, "/a") == 0 &&
29505c51f124SMoriah Waterland 			strcmp(mntbuf.mnt_special, "/a") == 0 &&
29515c51f124SMoriah Waterland 			strcmp(mntbuf.mnt_fstype, "lofs") == 0) {
29525c51f124SMoriah Waterland 			a_gdt->inMountedState = B_TRUE;
29535c51f124SMoriah Waterland 		}
29545c51f124SMoriah Waterland 
29555c51f124SMoriah Waterland 	}
29565c51f124SMoriah Waterland 
29575c51f124SMoriah Waterland 	/* close mount table file */
29585c51f124SMoriah Waterland 
29595c51f124SMoriah Waterland 	(void) fclose(fp);
29605c51f124SMoriah Waterland 
29615c51f124SMoriah Waterland 	/* store list pointers in global data structure */
29625c51f124SMoriah Waterland 
29635c51f124SMoriah Waterland 	a_gdt->gd_fileSystemConfig = list;
29645c51f124SMoriah Waterland 	a_gdt->gd_fileSystemConfigLen = listSize;
29655c51f124SMoriah Waterland 
29665c51f124SMoriah Waterland 	return (R_SUCCESS);
29675c51f124SMoriah Waterland }
29685c51f124SMoriah Waterland 
29695c51f124SMoriah Waterland /*
29705c51f124SMoriah Waterland  * Name: 	adjustResults
29715c51f124SMoriah Waterland  * Description:	adjust output result code before existing
29725c51f124SMoriah Waterland  * Arguments:	a_result - result code to adjust
29735c51f124SMoriah Waterland  * Returns:	int - adjusted result code
29745c51f124SMoriah Waterland  */
29755c51f124SMoriah Waterland 
29765c51f124SMoriah Waterland static int
adjustResults(int a_result)29775c51f124SMoriah Waterland adjustResults(int a_result)
29785c51f124SMoriah Waterland {
29795c51f124SMoriah Waterland 	boolean_t	negate = getNegateResults();
29805c51f124SMoriah Waterland 	int		realResult;
29815c51f124SMoriah Waterland 
29825c51f124SMoriah Waterland 	/* adjust code as appropriate */
29835c51f124SMoriah Waterland 
29845c51f124SMoriah Waterland 	switch (a_result) {
29855c51f124SMoriah Waterland 	case R_SUCCESS:		/* condition satisfied */
29865c51f124SMoriah Waterland 		realResult = ((negate == B_TRUE) ? 1 : 0);
29875c51f124SMoriah Waterland 		break;
29885c51f124SMoriah Waterland 	case R_FAILURE:		/* condition not satisfied */
29895c51f124SMoriah Waterland 		realResult = ((negate == B_TRUE) ? 0 : 1);
29905c51f124SMoriah Waterland 		break;
29915c51f124SMoriah Waterland 	case R_USAGE:		/* usage errors */
29925c51f124SMoriah Waterland 		realResult = 2;
29935c51f124SMoriah Waterland 		break;
29945c51f124SMoriah Waterland 	case R_ERROR:		/* condition could not be determined */
29955c51f124SMoriah Waterland 	default:
29965c51f124SMoriah Waterland 		realResult = 3;
29975c51f124SMoriah Waterland 		break;
29985c51f124SMoriah Waterland 	}
29995c51f124SMoriah Waterland 
30005c51f124SMoriah Waterland 	/* debugging output */
30015c51f124SMoriah Waterland 
30025c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_ADJUST_RESULTS, a_result, negate,
30035c51f124SMoriah Waterland 		realResult);
30045c51f124SMoriah Waterland 
30055c51f124SMoriah Waterland 	/* return results */
30065c51f124SMoriah Waterland 
30075c51f124SMoriah Waterland 	return (realResult);
30085c51f124SMoriah Waterland }
30095c51f124SMoriah Waterland 
30105c51f124SMoriah Waterland /*
30115c51f124SMoriah Waterland  * Name:        setCmdLinePath
30125c51f124SMoriah Waterland  * Description:	set global command line path
30135c51f124SMoriah Waterland  * Arguments:   path - path to set from the command line
30145c51f124SMoriah Waterland  *              args - command line args
30155c51f124SMoriah Waterland  *              num_args - number of command line args
30165c51f124SMoriah Waterland  * Returns:     R_SUCCESS - root path successfully set
30175c51f124SMoriah Waterland  *              R_FAILURE - root path could not be set
30185c51f124SMoriah Waterland  *              R_ERROR - fatal error attempting to set root path
30195c51f124SMoriah Waterland  */
30205c51f124SMoriah Waterland 
30215c51f124SMoriah Waterland static void
setCmdLinePath(char ** path,char ** args,int num_args)30225c51f124SMoriah Waterland setCmdLinePath(char **path, char **args, int num_args)
30235c51f124SMoriah Waterland {
30245c51f124SMoriah Waterland 	char   rp[PATH_MAX] = { '\0' };
30255c51f124SMoriah Waterland 	struct stat statbuf;
30265c51f124SMoriah Waterland 
30275c51f124SMoriah Waterland 	if (*path != NULL) {
30285c51f124SMoriah Waterland 		return;
30295c51f124SMoriah Waterland 	}
30305c51f124SMoriah Waterland 
30315c51f124SMoriah Waterland 	/*
30325c51f124SMoriah Waterland 	 * If a path "pkgcond is_global_zone [path]" is provided on the
30335c51f124SMoriah Waterland 	 * command line it must be the last argument.
30345c51f124SMoriah Waterland 	 */
30355c51f124SMoriah Waterland 
30365c51f124SMoriah Waterland 	if (realpath(args[num_args - 1], rp) != NULL) {
30375c51f124SMoriah Waterland 		if (stat(rp, &statbuf) == 0) {
30385c51f124SMoriah Waterland 			/* make sure the target is a directory */
30395c51f124SMoriah Waterland 			if ((statbuf.st_mode & S_IFDIR)) {
30405c51f124SMoriah Waterland 				*path = strdup(rp);
30415c51f124SMoriah Waterland 			} else {
30425c51f124SMoriah Waterland 				*path = NULL;
30435c51f124SMoriah Waterland 			}
30445c51f124SMoriah Waterland 		}
30455c51f124SMoriah Waterland 	}
30465c51f124SMoriah Waterland }
30475c51f124SMoriah Waterland 
30485c51f124SMoriah Waterland /*
30495c51f124SMoriah Waterland  * Name:	setRootPath
30505c51f124SMoriah Waterland  * Description:	set global root path returned by getRootPath
30515c51f124SMoriah Waterland  * Arguments:	a_path - root path to set
30525c51f124SMoriah Waterland  *		a_mustExist - B_TRUE if path must exist (else error)
30535c51f124SMoriah Waterland  *			- B_FALSE if path may not exist
30545c51f124SMoriah Waterland  * Returns:	R_SUCCESS - root path successfully set
30555c51f124SMoriah Waterland  *		R_FAILURE - root path could not be set
30565c51f124SMoriah Waterland  *		R_ERROR - fatal error attempting to set root path
30575c51f124SMoriah Waterland  */
30585c51f124SMoriah Waterland 
30595c51f124SMoriah Waterland static int
setRootPath(char * a_path,char * a_envVar,boolean_t a_mustExist)30605c51f124SMoriah Waterland setRootPath(char *a_path, char *a_envVar, boolean_t a_mustExist)
30615c51f124SMoriah Waterland {
30625c51f124SMoriah Waterland 	char		rp[PATH_MAX] = { '\0' };
30635c51f124SMoriah Waterland 	struct stat	statbuf;
30645c51f124SMoriah Waterland 
30655c51f124SMoriah Waterland 	/* if no data then issue warning and return success */
30665c51f124SMoriah Waterland 
30675c51f124SMoriah Waterland 	if ((a_path == NULL) || (*a_path == '\0')) {
30685c51f124SMoriah Waterland 		echoDebug(DBG_NO_DEFAULT_ROOT_PATH_SET);
30695c51f124SMoriah Waterland 		return (R_SUCCESS);
30705c51f124SMoriah Waterland 	}
30715c51f124SMoriah Waterland 
30725c51f124SMoriah Waterland 	/* path present - resolve to absolute path */
30735c51f124SMoriah Waterland 
30745c51f124SMoriah Waterland 	if (realpath(a_path, rp) == NULL) {
30755c51f124SMoriah Waterland 		if (a_mustExist == B_TRUE) {
30765c51f124SMoriah Waterland 			/* must exist ... error */
30775c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID,
30785c51f124SMoriah Waterland 				a_path, strerror(errno));
30795c51f124SMoriah Waterland 			return (R_ERROR);
30805c51f124SMoriah Waterland 		} else {
30815c51f124SMoriah Waterland 			/* may not exist - use path as specified */
30825c51f124SMoriah Waterland 			(void) strcpy(rp, a_path);
30835c51f124SMoriah Waterland 		}
30845c51f124SMoriah Waterland 	}
30855c51f124SMoriah Waterland 
30865c51f124SMoriah Waterland 	/* debugging output */
30875c51f124SMoriah Waterland 
30885c51f124SMoriah Waterland 	echoDebug(DBG_DEFAULT_ROOT_PATH_SET, rp, a_envVar ? a_envVar : "");
30895c51f124SMoriah Waterland 
30905c51f124SMoriah Waterland 	/* validate path existence if it must exist */
30915c51f124SMoriah Waterland 
30925c51f124SMoriah Waterland 	if (a_mustExist == B_TRUE) {
30935c51f124SMoriah Waterland 
30945c51f124SMoriah Waterland 		/* get node status */
30955c51f124SMoriah Waterland 
30965c51f124SMoriah Waterland 		if (stat(rp, &statbuf) != 0) {
30975c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID,
30985c51f124SMoriah Waterland 				rp, strerror(errno));
30995c51f124SMoriah Waterland 			return (R_ERROR);
31005c51f124SMoriah Waterland 		}
31015c51f124SMoriah Waterland 
31025c51f124SMoriah Waterland 		/* make sure the target is a directory */
31035c51f124SMoriah Waterland 
31045c51f124SMoriah Waterland 		if (!(statbuf.st_mode & S_IFDIR)) {
31055c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_NOT_DIR, rp);
31065c51f124SMoriah Waterland 			return (R_ERROR);
31075c51f124SMoriah Waterland 		}
31085c51f124SMoriah Waterland 	}
31095c51f124SMoriah Waterland 
31105c51f124SMoriah Waterland 	/* target exists and is a directory - set */
31115c51f124SMoriah Waterland 
31125c51f124SMoriah Waterland 	echoDebug(DBG_SET_ROOT_PATH_TO, rp);
31135c51f124SMoriah Waterland 
31145c51f124SMoriah Waterland 	/* store copy of resolved root path */
31155c51f124SMoriah Waterland 
31165c51f124SMoriah Waterland 	_rootPath = strdup(rp);
31175c51f124SMoriah Waterland 
31185c51f124SMoriah Waterland 	/* success! */
31195c51f124SMoriah Waterland 
31205c51f124SMoriah Waterland 	return (R_SUCCESS);
31215c51f124SMoriah Waterland }
31225c51f124SMoriah Waterland 
31235c51f124SMoriah Waterland /*
31245c51f124SMoriah Waterland  * Name:	testPath
31255c51f124SMoriah Waterland  * Description:	determine if a path meets the specified conditions
31265c51f124SMoriah Waterland  * Arguments:	a_tt - conditions to test path against
31275c51f124SMoriah Waterland  * 		a_format - format to use to generate path
31285c51f124SMoriah Waterland  *		arguments following a_format - as needed for a_format
31295c51f124SMoriah Waterland  * Returns:	R_SUCCESS - the path meets all of the specified conditions
31305c51f124SMoriah Waterland  *		R_FAILURE - the path does not meet all of the conditions
31315c51f124SMoriah Waterland  *		R_ERROR - error attempting to test path
31325c51f124SMoriah Waterland  */
31335c51f124SMoriah Waterland 
31345c51f124SMoriah Waterland /*PRINTFLIKE2*/
31355c51f124SMoriah Waterland static int
testPath(TEST_TYPES a_tt,char * a_format,...)31365c51f124SMoriah Waterland testPath(TEST_TYPES a_tt, char *a_format, ...)
31375c51f124SMoriah Waterland {
31385c51f124SMoriah Waterland 	char		*mbPath;	/* copy for the path to be returned */
31395c51f124SMoriah Waterland 	char		bfr[1];
31405c51f124SMoriah Waterland 	int		r;
31415c51f124SMoriah Waterland 	size_t		vres = 0;
31425c51f124SMoriah Waterland 	struct stat	statbuf;
31435c51f124SMoriah Waterland 	va_list		ap;
31445c51f124SMoriah Waterland 	int		fd;
31455c51f124SMoriah Waterland 
31465c51f124SMoriah Waterland 	/* entry assertions */
31475c51f124SMoriah Waterland 
31485c51f124SMoriah Waterland 	assert(a_format != NULL);
31495c51f124SMoriah Waterland 	assert(*a_format != '\0');
31505c51f124SMoriah Waterland 
31515c51f124SMoriah Waterland 	/* determine size of the message in bytes */
31525c51f124SMoriah Waterland 
31535c51f124SMoriah Waterland 	va_start(ap, a_format);
31545c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
31555c51f124SMoriah Waterland 	va_end(ap);
31565c51f124SMoriah Waterland 
31575c51f124SMoriah Waterland 	assert(vres > 0);
31585c51f124SMoriah Waterland 
31595c51f124SMoriah Waterland 	/* allocate storage to hold the message */
31605c51f124SMoriah Waterland 
31615c51f124SMoriah Waterland 	mbPath = (char *)calloc(1, vres+2);
31625c51f124SMoriah Waterland 	assert(mbPath != NULL);
31635c51f124SMoriah Waterland 
31645c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
31655c51f124SMoriah Waterland 
31665c51f124SMoriah Waterland 	va_start(ap, a_format);
31675c51f124SMoriah Waterland 	vres = vsnprintf(mbPath, vres+1, a_format, ap);
31685c51f124SMoriah Waterland 	va_end(ap);
31695c51f124SMoriah Waterland 
31705c51f124SMoriah Waterland 	assert(vres > 0);
31715c51f124SMoriah Waterland 
31725c51f124SMoriah Waterland 	echoDebug(DBG_TEST_PATH, mbPath, (unsigned long)a_tt);
31735c51f124SMoriah Waterland 
31745c51f124SMoriah Waterland 	/*
31755c51f124SMoriah Waterland 	 * When a path given to open(2) contains symbolic links, the
31765c51f124SMoriah Waterland 	 * open system call first resolves all symbolic links and then
31775c51f124SMoriah Waterland 	 * opens that final "resolved" path. As a result, it is not
31785c51f124SMoriah Waterland 	 * possible to check the result of an fstat(2) against the
31795c51f124SMoriah Waterland 	 * file descriptor returned by open(2) for S_IFLNK (a symbolic
31805c51f124SMoriah Waterland 	 * link) since all symbolic links are resolved before the
31815c51f124SMoriah Waterland 	 * target is opened.
31825c51f124SMoriah Waterland 	 *
31835c51f124SMoriah Waterland 	 * When testing the target as being (or not being) a symbolic
31845c51f124SMoriah Waterland 	 * link, first use lstat(2) against the target to determine
31855c51f124SMoriah Waterland 	 * whether or not the specified target itself is (or is not) a
31865c51f124SMoriah Waterland 	 * symbolic link.
31875c51f124SMoriah Waterland 	 */
31885c51f124SMoriah Waterland 
31895c51f124SMoriah Waterland 	if (a_tt & (TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)) {
31905c51f124SMoriah Waterland 		/*
31915c51f124SMoriah Waterland 		 * testing target is/is not a symbolic link; use lstat
31925c51f124SMoriah Waterland 		 * to determine the status of the target itself rather
31935c51f124SMoriah Waterland 		 * than what the target might finally address.
31945c51f124SMoriah Waterland 		 */
31955c51f124SMoriah Waterland 
31965c51f124SMoriah Waterland 		if (lstat(mbPath, &statbuf) != 0) {
31975c51f124SMoriah Waterland 			echoDebug(DBG_CANNOT_LSTAT_PATH, mbPath,
31985c51f124SMoriah Waterland 				strerror(errno));
31995c51f124SMoriah Waterland 			free(mbPath);
32005c51f124SMoriah Waterland 			return (R_FAILURE);
32015c51f124SMoriah Waterland 		}
32025c51f124SMoriah Waterland 
32035c51f124SMoriah Waterland 		/* Is the target required to be a symbolic link? */
32045c51f124SMoriah Waterland 
32055c51f124SMoriah Waterland 		if (a_tt & TEST_IS_SYMBOLIC_LINK) {
32065c51f124SMoriah Waterland 			/* target must be a symbolic link */
32075c51f124SMoriah Waterland 			if (!(statbuf.st_mode & S_IFLNK)) {
32085c51f124SMoriah Waterland 				/* failure: target is not a symbolic link */
32095c51f124SMoriah Waterland 				echoDebug(DBG_IS_NOT_A_SYMLINK, mbPath);
32105c51f124SMoriah Waterland 				free(mbPath);
32115c51f124SMoriah Waterland 				return (R_FAILURE);
32125c51f124SMoriah Waterland 			}
32135c51f124SMoriah Waterland 			/* success: target is a symbolic link */
32145c51f124SMoriah Waterland 			echoDebug(DBG_SYMLINK_IS, mbPath);
32155c51f124SMoriah Waterland 		}
32165c51f124SMoriah Waterland 
32175c51f124SMoriah Waterland 		/* Is the target required to not be a symbolic link? */
32185c51f124SMoriah Waterland 
32195c51f124SMoriah Waterland 		if (a_tt & TEST_NOT_SYMBOLIC_LINK) {
32205c51f124SMoriah Waterland 			/* target must not be a symbolic link */
32215c51f124SMoriah Waterland 			if (statbuf.st_mode & S_IFLNK) {
32225c51f124SMoriah Waterland 				/* failure: target is a symbolic link */
32235c51f124SMoriah Waterland 				echoDebug(DBG_IS_A_SYMLINK, mbPath);
32245c51f124SMoriah Waterland 				free(mbPath);
32255c51f124SMoriah Waterland 				return (R_FAILURE);
32265c51f124SMoriah Waterland 			}
32275c51f124SMoriah Waterland 			/* success: target is not a symbolic link */
32285c51f124SMoriah Waterland 			echoDebug(DBG_SYMLINK_NOT, mbPath);
32295c51f124SMoriah Waterland 		}
32305c51f124SMoriah Waterland 
32315c51f124SMoriah Waterland 		/*
32325c51f124SMoriah Waterland 		 * if only testing is/is not a symbolic link, then
32335c51f124SMoriah Waterland 		 * no need to open the target: return success.
32345c51f124SMoriah Waterland 		 */
32355c51f124SMoriah Waterland 
32365c51f124SMoriah Waterland 		if (!(a_tt &
32375c51f124SMoriah Waterland 		    (~(TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)))) {
32385c51f124SMoriah Waterland 			free(mbPath);
32395c51f124SMoriah Waterland 			return (R_SUCCESS);
32405c51f124SMoriah Waterland 		}
32415c51f124SMoriah Waterland 	}
32425c51f124SMoriah Waterland 
32435c51f124SMoriah Waterland 	/* resolve path and remove any whitespace */
32445c51f124SMoriah Waterland 
32455c51f124SMoriah Waterland 	r = resolvePath(&mbPath);
32465c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
32475c51f124SMoriah Waterland 		echoDebug(DBG_TEST_PATH_NO_RESOLVE, mbPath);
32485c51f124SMoriah Waterland 		free(mbPath);
32495c51f124SMoriah Waterland 		if (a_tt & TEST_NOT_EXISTS) {
32505c51f124SMoriah Waterland 			return (R_SUCCESS);
32515c51f124SMoriah Waterland 		}
32525c51f124SMoriah Waterland 		return (r);
32535c51f124SMoriah Waterland 	}
32545c51f124SMoriah Waterland 
32555c51f124SMoriah Waterland 	echoDebug(DBG_TEST_PATH_RESOLVE, mbPath);
32565c51f124SMoriah Waterland 
32575c51f124SMoriah Waterland 	/* open the file - this is the basic existence test */
32585c51f124SMoriah Waterland 
32595c51f124SMoriah Waterland 	fd = open(mbPath, O_RDONLY|O_LARGEFILE, 0);
32605c51f124SMoriah Waterland 
32615c51f124SMoriah Waterland 	/* existence test failed if file cannot be opened */
32625c51f124SMoriah Waterland 
32635c51f124SMoriah Waterland 	if (fd < 0) {
32645c51f124SMoriah Waterland 		/*
32655c51f124SMoriah Waterland 		 * target could not be opened - if testing for non-existence,
32665c51f124SMoriah Waterland 		 * return success, otherwise return failure
32675c51f124SMoriah Waterland 		 */
32685c51f124SMoriah Waterland 		if (a_tt & TEST_NOT_EXISTS) {
32695c51f124SMoriah Waterland 			echoDebug(DBG_CANNOT_ACCESS_PATH_OK, mbPath);
32705c51f124SMoriah Waterland 			free(mbPath);
32715c51f124SMoriah Waterland 			return (R_SUCCESS);
32725c51f124SMoriah Waterland 		}
32735c51f124SMoriah Waterland 
32745c51f124SMoriah Waterland 		echoDebug(DBG_CANNOT_ACCESS_PATH_BUT_SHOULD,
32755c51f124SMoriah Waterland 		    mbPath, strerror(errno));
32765c51f124SMoriah Waterland 		free(mbPath);
32775c51f124SMoriah Waterland 
32785c51f124SMoriah Waterland 		return (R_FAILURE);
32795c51f124SMoriah Waterland 	}
32805c51f124SMoriah Waterland 
32815c51f124SMoriah Waterland 	/*
32825c51f124SMoriah Waterland 	 * target successfully opened - if testing for non-existence,
32835c51f124SMoriah Waterland 	 * return failure, otherwise continue with specified tests
32845c51f124SMoriah Waterland 	 */
32855c51f124SMoriah Waterland 
32865c51f124SMoriah Waterland 	if (a_tt & TEST_NOT_EXISTS) {
32875c51f124SMoriah Waterland 		/* testing for non-existence: return failure */
32885c51f124SMoriah Waterland 		echoDebug(DBG_TEST_EXISTS_SHOULD_NOT, mbPath);
32895c51f124SMoriah Waterland 		free(mbPath);
32905c51f124SMoriah Waterland 		(void) close(fd);
32915c51f124SMoriah Waterland 		return (R_FAILURE);
32925c51f124SMoriah Waterland 	}
32935c51f124SMoriah Waterland 
32945c51f124SMoriah Waterland 	/* get the file status */
32955c51f124SMoriah Waterland 
32965c51f124SMoriah Waterland 	r = fstat(fd, &statbuf);
32975c51f124SMoriah Waterland 	if (r != 0) {
32985c51f124SMoriah Waterland 		echoDebug(DBG_PATH_DOES_NOT_EXIST, mbPath, strerror(errno));
32995c51f124SMoriah Waterland 		(void) close(fd);
33005c51f124SMoriah Waterland 		free(mbPath);
33015c51f124SMoriah Waterland 		return (R_FAILURE);
33025c51f124SMoriah Waterland 	}
33035c51f124SMoriah Waterland 
33045c51f124SMoriah Waterland 	/* required to be a directory? */
33055c51f124SMoriah Waterland 
33065c51f124SMoriah Waterland 	if (a_tt & TEST_IS_DIRECTORY) {
33075c51f124SMoriah Waterland 		if (!(statbuf.st_mode & S_IFDIR)) {
33085c51f124SMoriah Waterland 			/* is not a directory */
33095c51f124SMoriah Waterland 			echoDebug(DBG_IS_NOT_A_DIRECTORY, mbPath);
33105c51f124SMoriah Waterland 			free(mbPath);
33115c51f124SMoriah Waterland 			return (R_FAILURE);
33125c51f124SMoriah Waterland 		}
33135c51f124SMoriah Waterland 		/* a directory */
33145c51f124SMoriah Waterland 		echoDebug(DBG_DIRECTORY_IS, mbPath);
33155c51f124SMoriah Waterland 	}
33165c51f124SMoriah Waterland 
33175c51f124SMoriah Waterland 	/* required to not be a directory? */
33185c51f124SMoriah Waterland 
33195c51f124SMoriah Waterland 	if (a_tt & TEST_NOT_DIRECTORY) {
33205c51f124SMoriah Waterland 		if (statbuf.st_mode & S_IFDIR) {
33215c51f124SMoriah Waterland 			/* is a directory */
33225c51f124SMoriah Waterland 			echoDebug(DBG_IS_A_DIRECTORY, mbPath);
33235c51f124SMoriah Waterland 			free(mbPath);
33245c51f124SMoriah Waterland 			return (R_FAILURE);
33255c51f124SMoriah Waterland 		}
33265c51f124SMoriah Waterland 		/* not a directory */
33275c51f124SMoriah Waterland 		echoDebug(DBG_DIRECTORY_NOT, mbPath);
33285c51f124SMoriah Waterland 	}
33295c51f124SMoriah Waterland 
33305c51f124SMoriah Waterland 	/* required to be a file? */
33315c51f124SMoriah Waterland 
33325c51f124SMoriah Waterland 	if (a_tt & TEST_IS_FILE) {
33335c51f124SMoriah Waterland 		if (!(statbuf.st_mode & S_IFREG)) {
33345c51f124SMoriah Waterland 			/* is not a regular file */
33355c51f124SMoriah Waterland 			echoDebug(DBG_IS_NOT_A_FILE, mbPath);
33365c51f124SMoriah Waterland 			free(mbPath);
33375c51f124SMoriah Waterland 			return (R_FAILURE);
33385c51f124SMoriah Waterland 		}
33395c51f124SMoriah Waterland 		/* a regular file */
33405c51f124SMoriah Waterland 		echoDebug(DBG_FILE_IS, mbPath);
33415c51f124SMoriah Waterland 	}
33425c51f124SMoriah Waterland 
33435c51f124SMoriah Waterland 	/* required to not be a file? */
33445c51f124SMoriah Waterland 
33455c51f124SMoriah Waterland 	if (a_tt & TEST_NOT_FILE) {
33465c51f124SMoriah Waterland 		if (statbuf.st_mode & S_IFREG) {
33475c51f124SMoriah Waterland 			/* is a regular file */
33485c51f124SMoriah Waterland 			echoDebug(DBG_IS_A_FILE, mbPath);
33495c51f124SMoriah Waterland 			free(mbPath);
33505c51f124SMoriah Waterland 			return (R_FAILURE);
33515c51f124SMoriah Waterland 		}
33525c51f124SMoriah Waterland 		/* not a regular file */
33535c51f124SMoriah Waterland 		echoDebug(DBG_FILE_NOT, mbPath);
33545c51f124SMoriah Waterland 	}
33555c51f124SMoriah Waterland 
33565c51f124SMoriah Waterland 	/*
33575c51f124SMoriah Waterland 	 * Find token (global) in file pointed to by mbPath.
33585c51f124SMoriah Waterland 	 * token is only compared to first word in mbPath.
33595c51f124SMoriah Waterland 	 */
33605c51f124SMoriah Waterland 
33615c51f124SMoriah Waterland 	if (a_tt & TEST_GLOBAL_TOKEN_IN_FILE) {
33625c51f124SMoriah Waterland 		if (!(statbuf.st_mode & S_IFREG)) {
33635c51f124SMoriah Waterland 			/* is not a regular file */
33645c51f124SMoriah Waterland 			echoDebug(DBG_IS_NOT_A_FILE, mbPath);
33655c51f124SMoriah Waterland 			free(mbPath);
33665c51f124SMoriah Waterland 			return (R_FAILURE);
33675c51f124SMoriah Waterland 		}
33685c51f124SMoriah Waterland 		/* If global exists then we're not in a non-global zone */
33695c51f124SMoriah Waterland 		if (findToken(mbPath, GLOBAL_ZONENAME) == R_SUCCESS) {
33705c51f124SMoriah Waterland 			echoDebug(DBG_TOKEN__EXISTS, GLOBAL_ZONENAME, mbPath);
33715c51f124SMoriah Waterland 			free(mbPath);
33725c51f124SMoriah Waterland 			return (R_FAILURE);
33735c51f124SMoriah Waterland 		}
33745c51f124SMoriah Waterland 	}
33755c51f124SMoriah Waterland 
33765c51f124SMoriah Waterland 	(void) close(fd);
33775c51f124SMoriah Waterland 
33785c51f124SMoriah Waterland 	/* success! */
33795c51f124SMoriah Waterland 
33805c51f124SMoriah Waterland 	echoDebug(DBG_TESTPATH_OK, mbPath);
33815c51f124SMoriah Waterland 
33825c51f124SMoriah Waterland 	/* free up temp storage used to hold path to test */
33835c51f124SMoriah Waterland 
33845c51f124SMoriah Waterland 	free(mbPath);
33855c51f124SMoriah Waterland 
33865c51f124SMoriah Waterland 	return (R_SUCCESS);
33875c51f124SMoriah Waterland }
33885c51f124SMoriah Waterland 
33895c51f124SMoriah Waterland /*
33905c51f124SMoriah Waterland  * Name:        findToken
33915c51f124SMoriah Waterland  * Description:	Find first token in file.
33925c51f124SMoriah Waterland  * Arguments:
33935c51f124SMoriah Waterland  *              path - file to search for token
33945c51f124SMoriah Waterland  *              token - string to search for
33955c51f124SMoriah Waterland  * Returns:
33965c51f124SMoriah Waterland  *              R_SUCCESS - the token exists
33975c51f124SMoriah Waterland  *              R_FAILURE - the token does not exist
33985c51f124SMoriah Waterland  *              R_ERROR - fatal error attempting to find token
33995c51f124SMoriah Waterland  */
34005c51f124SMoriah Waterland 
34015c51f124SMoriah Waterland static int
findToken(char * path,char * token)34025c51f124SMoriah Waterland findToken(char *path, char *token)
34035c51f124SMoriah Waterland {
34045c51f124SMoriah Waterland 	FILE	*fp;
34055c51f124SMoriah Waterland 	char	*cp;
34065c51f124SMoriah Waterland 	char	line[MAXPATHLEN];
34075c51f124SMoriah Waterland 
34085c51f124SMoriah Waterland 	if (path == NULL || token == NULL) {
34095c51f124SMoriah Waterland 		return (R_ERROR);
34105c51f124SMoriah Waterland 	}
34115c51f124SMoriah Waterland 	if ((fp = fopen(path, "r")) == NULL) {
34125c51f124SMoriah Waterland 		return (R_ERROR);
34135c51f124SMoriah Waterland 	}
34145c51f124SMoriah Waterland 
34155c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), fp) != NULL) {
34165c51f124SMoriah Waterland 		for (cp = line; *cp && isspace(*cp); cp++);
34175c51f124SMoriah Waterland 		/* skip comments */
34185c51f124SMoriah Waterland 		if (*cp == '#') {
34195c51f124SMoriah Waterland 			continue;
34205c51f124SMoriah Waterland 		}
34215c51f124SMoriah Waterland 		if (pkgstrContainsToken(cp, token, ":")) {
34225c51f124SMoriah Waterland 			(void) fclose(fp);
34235c51f124SMoriah Waterland 			return (R_SUCCESS);
34245c51f124SMoriah Waterland 		}
34255c51f124SMoriah Waterland 	}
34265c51f124SMoriah Waterland 	(void) fclose(fp);
34275c51f124SMoriah Waterland 	return (R_FAILURE);
34285c51f124SMoriah Waterland }
34295c51f124SMoriah Waterland 
34305c51f124SMoriah Waterland 
34315c51f124SMoriah Waterland /*
34325c51f124SMoriah Waterland  * Name:	resolvePath
34335c51f124SMoriah Waterland  * Description:	fully resolve a path to an absolute real path
34345c51f124SMoriah Waterland  * Arguments:	r_path - pointer to pointer to malloc()ed storage containing
34355c51f124SMoriah Waterland  *			the path to resolve - this path may be reallocated
34365c51f124SMoriah Waterland  *			as necessary to hold the fully resolved path
34375c51f124SMoriah Waterland  * Output:	r_path - is realloc()ed as necessary
34385c51f124SMoriah Waterland  * Returns:	R_SUCCESS - the path is fully resolved
34395c51f124SMoriah Waterland  *		R_FAILURE - the path could not be resolved
34405c51f124SMoriah Waterland  *		R_ERROR - fatal error attempting to resolve path
34415c51f124SMoriah Waterland  */
34425c51f124SMoriah Waterland 
34435c51f124SMoriah Waterland static int
resolvePath(char ** r_path)34445c51f124SMoriah Waterland resolvePath(char **r_path)
34455c51f124SMoriah Waterland {
34465c51f124SMoriah Waterland 	int		i;
34475c51f124SMoriah Waterland 	char		resolvedPath[MAXPATHLEN+1] = {'\0'};
34485c51f124SMoriah Waterland 	size_t		mbPathlen;	/* length of multi-byte path */
34495c51f124SMoriah Waterland 	size_t		wcPathlen;	/* length of wide-character path */
34505c51f124SMoriah Waterland 	wchar_t		*wcPath;	/* wide-character version of the path */
34515c51f124SMoriah Waterland 	wchar_t		*wptr;		/* scratch pointer */
34525c51f124SMoriah Waterland 
34535c51f124SMoriah Waterland 	/* entry assertions */
34545c51f124SMoriah Waterland 
34555c51f124SMoriah Waterland 	assert(r_path != (char **)NULL);
34565c51f124SMoriah Waterland 
34575c51f124SMoriah Waterland 	/* return error if the path is completely empty */
34585c51f124SMoriah Waterland 
34595c51f124SMoriah Waterland 	if (*r_path == '\0') {
34605c51f124SMoriah Waterland 		return (R_FAILURE);
34615c51f124SMoriah Waterland 	}
34625c51f124SMoriah Waterland 
34635c51f124SMoriah Waterland 	/* remove all leading whitespace */
34645c51f124SMoriah Waterland 
34655c51f124SMoriah Waterland 	removeLeadingWhitespace(r_path);
34665c51f124SMoriah Waterland 
34675c51f124SMoriah Waterland 	/*
34685c51f124SMoriah Waterland 	 * convert to real path: an absolute pathname that names the same file,
34695c51f124SMoriah Waterland 	 * whose resolution does not involve ".", "..",  or  symbolic links.
34705c51f124SMoriah Waterland 	 */
34715c51f124SMoriah Waterland 
34725c51f124SMoriah Waterland 	if (realpath(*r_path, resolvedPath) != NULL) {
34735c51f124SMoriah Waterland 		free(*r_path);
34745c51f124SMoriah Waterland 		*r_path = strdup(resolvedPath);
34755c51f124SMoriah Waterland 	}
34765c51f124SMoriah Waterland 
34775c51f124SMoriah Waterland 	/*
34785c51f124SMoriah Waterland 	 *  convert the multi-byte version of the path to a
34795c51f124SMoriah Waterland 	 *  wide-character rendering, for doing our figuring.
34805c51f124SMoriah Waterland 	 */
34815c51f124SMoriah Waterland 
34825c51f124SMoriah Waterland 	mbPathlen = strlen(*r_path);
34835c51f124SMoriah Waterland 
34845c51f124SMoriah Waterland 	if ((wcPath = (wchar_t *)
34855c51f124SMoriah Waterland 		calloc(1, sizeof (wchar_t)*(mbPathlen+1))) == NULL) {
34865c51f124SMoriah Waterland 		return (R_FAILURE);
34875c51f124SMoriah Waterland 	}
34885c51f124SMoriah Waterland 
34895c51f124SMoriah Waterland 	/*LINTED*/
34905c51f124SMoriah Waterland 	if ((wcPathlen = mbstowcs(wcPath, *r_path, mbPathlen)) == -1) {
34915c51f124SMoriah Waterland 		free(wcPath);
34925c51f124SMoriah Waterland 		return (R_FAILURE);
34935c51f124SMoriah Waterland 	}
34945c51f124SMoriah Waterland 
34955c51f124SMoriah Waterland 	/*
34965c51f124SMoriah Waterland 	 *  remove duplicate slashes first ("//../" -> "/")
34975c51f124SMoriah Waterland 	 */
34985c51f124SMoriah Waterland 
34995c51f124SMoriah Waterland 	for (wptr = wcPath, i = 0; i < wcPathlen; i++) {
35005c51f124SMoriah Waterland 		*wptr++ = wcPath[i];
35015c51f124SMoriah Waterland 
35025c51f124SMoriah Waterland 		if (wcPath[i] == '/') {
35035c51f124SMoriah Waterland 			i++;
35045c51f124SMoriah Waterland 
35055c51f124SMoriah Waterland 			while (wcPath[i] == '/') {
35065c51f124SMoriah Waterland 				i++;
35075c51f124SMoriah Waterland 			}
35085c51f124SMoriah Waterland 
35095c51f124SMoriah Waterland 			i--;
35105c51f124SMoriah Waterland 		}
35115c51f124SMoriah Waterland 	}
35125c51f124SMoriah Waterland 
35135c51f124SMoriah Waterland 	*wptr = '\0';
35145c51f124SMoriah Waterland 
35155c51f124SMoriah Waterland 	/*
35165c51f124SMoriah Waterland 	 *  now convert back to the multi-byte format.
35175c51f124SMoriah Waterland 	 */
35185c51f124SMoriah Waterland 
35195c51f124SMoriah Waterland 	/*LINTED*/
35205c51f124SMoriah Waterland 	if (wcstombs(*r_path, wcPath, mbPathlen) == -1) {
35215c51f124SMoriah Waterland 		free(wcPath);
35225c51f124SMoriah Waterland 		return (R_FAILURE);
35235c51f124SMoriah Waterland 	}
35245c51f124SMoriah Waterland 
35255c51f124SMoriah Waterland 	/* at this point have a path */
35265c51f124SMoriah Waterland 
35275c51f124SMoriah Waterland 	/* free up temporary storage */
35285c51f124SMoriah Waterland 
35295c51f124SMoriah Waterland 	free(wcPath);
35305c51f124SMoriah Waterland 
35315c51f124SMoriah Waterland 	return (R_SUCCESS);
35325c51f124SMoriah Waterland }
35335c51f124SMoriah Waterland 
35345c51f124SMoriah Waterland /*
35355c51f124SMoriah Waterland  * Name:	removeLeadingWhitespace
35365c51f124SMoriah Waterland  * Synopsis:	Remove leading whitespace from string
35375c51f124SMoriah Waterland  * Description:	Remove all leading whitespace characters from a string
35385c51f124SMoriah Waterland  * Arguments:	a_str - [RO, *RW] - (char **)
35395c51f124SMoriah Waterland  *			Pointer to handle to string (in allocated storage) to
35405c51f124SMoriah Waterland  *			remove all leading whitespace from
35415c51f124SMoriah Waterland  * Returns:	void
35425c51f124SMoriah Waterland  *			The input string is modified as follows:
35435c51f124SMoriah Waterland  *			== NULL:
35445c51f124SMoriah Waterland  *				- input string was NULL
35455c51f124SMoriah Waterland  *				- input string is all whitespace
35465c51f124SMoriah Waterland  *			!= NULL:
35475c51f124SMoriah Waterland  *				- copy of input string with leading
35485c51f124SMoriah Waterland  *				  whitespace removed
35495c51f124SMoriah Waterland  * CAUTION:	The input string must be allocated space (via malloc() or
35505c51f124SMoriah Waterland  *		strdup()) - it must not be a static or inline character string
35515c51f124SMoriah Waterland  * NOTE:	The input string a_str will be freed with 'free'
35525c51f124SMoriah Waterland  *		if it is all whitespace, or if it contains any leading
35535c51f124SMoriah Waterland  *		whitespace characters
35545c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
35555c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
35565c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
35575c51f124SMoriah Waterland  * Errors:	If the string cannot be created, the process exits
35585c51f124SMoriah Waterland  */
35595c51f124SMoriah Waterland 
35605c51f124SMoriah Waterland static void
removeLeadingWhitespace(char ** a_str)35615c51f124SMoriah Waterland removeLeadingWhitespace(char **a_str)
35625c51f124SMoriah Waterland {
35635c51f124SMoriah Waterland 	char	*o_str;
35645c51f124SMoriah Waterland 
35655c51f124SMoriah Waterland 	/* entry assertions */
35665c51f124SMoriah Waterland 
35675c51f124SMoriah Waterland 	assert(a_str != (char **)NULL);
35685c51f124SMoriah Waterland 
35695c51f124SMoriah Waterland 	/* if string is null, just return */
35705c51f124SMoriah Waterland 
35715c51f124SMoriah Waterland 	if (*a_str == NULL) {
35725c51f124SMoriah Waterland 		return;
35735c51f124SMoriah Waterland 	}
35745c51f124SMoriah Waterland 	o_str = *a_str;
35755c51f124SMoriah Waterland 
35765c51f124SMoriah Waterland 	/* if string is empty, deallocate and return NULL */
35775c51f124SMoriah Waterland 
35785c51f124SMoriah Waterland 	if (*o_str == '\0') {
35795c51f124SMoriah Waterland 		/* free string */
35805c51f124SMoriah Waterland 		free(*a_str);
35815c51f124SMoriah Waterland 		*a_str = NULL;
35825c51f124SMoriah Waterland 		return;
35835c51f124SMoriah Waterland 	}
35845c51f124SMoriah Waterland 
35855c51f124SMoriah Waterland 	/* if first character is not a space, just return */
35865c51f124SMoriah Waterland 
35875c51f124SMoriah Waterland 	if (!isspace(*o_str)) {
35885c51f124SMoriah Waterland 		return;
35895c51f124SMoriah Waterland 	}
35905c51f124SMoriah Waterland 
35915c51f124SMoriah Waterland 	/* advance past all space characters */
35925c51f124SMoriah Waterland 
35935c51f124SMoriah Waterland 	while ((*o_str != '\0') && (isspace(*o_str))) {
35945c51f124SMoriah Waterland 		o_str++;
35955c51f124SMoriah Waterland 	}
35965c51f124SMoriah Waterland 
35975c51f124SMoriah Waterland 	/* if string was all space characters, deallocate and return NULL */
35985c51f124SMoriah Waterland 
35995c51f124SMoriah Waterland 	if (*o_str == '\0') {
36005c51f124SMoriah Waterland 		/* free string */
36015c51f124SMoriah Waterland 		free(*a_str);
36025c51f124SMoriah Waterland 		*a_str = NULL;
36035c51f124SMoriah Waterland 		return;
36045c51f124SMoriah Waterland 	}
36055c51f124SMoriah Waterland 
36065c51f124SMoriah Waterland 	/* have non-space/null byte, return dup, deallocate original */
36075c51f124SMoriah Waterland 
36085c51f124SMoriah Waterland 	o_str = strdup(o_str);
36095c51f124SMoriah Waterland 	free(*a_str);
36105c51f124SMoriah Waterland 	*a_str = o_str;
36115c51f124SMoriah Waterland }
36125c51f124SMoriah Waterland 
36135c51f124SMoriah Waterland /*
36145c51f124SMoriah Waterland  * Name:	getZoneName
36155c51f124SMoriah Waterland  * Description:	get the name of the zone this process is running in
36165c51f124SMoriah Waterland  * Arguments:	r_zoneName - pointer to pointer to receive zone name
36175c51f124SMoriah Waterland  * Output:	r_zoneName - a pointer to malloc()ed storage containing
36185c51f124SMoriah Waterland  *			the zone name this process is running in is stored
36195c51f124SMoriah Waterland  *			in the location pointed to by r_zoneName
36205c51f124SMoriah Waterland  * Returns:	R_SUCCESS - the zone name is successfully returned
36215c51f124SMoriah Waterland  *		R_FAILURE - the zone name is not successfully returned
36225c51f124SMoriah Waterland  *		R_ERROR - error attempting to get the zone name
36235c51f124SMoriah Waterland  */
36245c51f124SMoriah Waterland 
36255c51f124SMoriah Waterland static int
getZoneName(char ** r_zoneName)36265c51f124SMoriah Waterland getZoneName(char **r_zoneName)
36275c51f124SMoriah Waterland {
36285c51f124SMoriah Waterland static char zoneName[ZONENAME_MAX] = { '\0' };
36295c51f124SMoriah Waterland 
36305c51f124SMoriah Waterland 	/* if zone name not already present, retrieve and cache name */
36315c51f124SMoriah Waterland 
36325c51f124SMoriah Waterland 	if (zoneName[0] == '\0') {
36335c51f124SMoriah Waterland 		if (getzonenamebyid(getzoneid(), zoneName,
36345c51f124SMoriah Waterland 			sizeof (zoneName)) < 0) {
36355c51f124SMoriah Waterland 			log_msg(LOG_MSG_ERR, ERR_CANNOT_GET_ZONENAME);
36365c51f124SMoriah Waterland 			return (R_ERROR);
36375c51f124SMoriah Waterland 		}
36385c51f124SMoriah Waterland 	}
36395c51f124SMoriah Waterland 
36405c51f124SMoriah Waterland 	/* return cached zone name */
36415c51f124SMoriah Waterland 
36425c51f124SMoriah Waterland 	*r_zoneName = zoneName;
36435c51f124SMoriah Waterland 	return (R_SUCCESS);
36445c51f124SMoriah Waterland }
36455c51f124SMoriah Waterland 
36465c51f124SMoriah Waterland /*
36475c51f124SMoriah Waterland  * Name:	getRootPath
36485c51f124SMoriah Waterland  * Description:	get the root path being tested by this process
36495c51f124SMoriah Waterland  * Arguments:	r_rootPath - pointer to pointer to receive root path
36505c51f124SMoriah Waterland  * Output:	r_rootPath - a pointer to malloc()ed storage containing
36515c51f124SMoriah Waterland  *			the root path name this process is testing
36525c51f124SMoriah Waterland  * Returns:	R_SUCCESS - the root path is successfully returned
36535c51f124SMoriah Waterland  *		R_FAILURE - the root path is not successfully returned
36545c51f124SMoriah Waterland  *		R_ERROR - error attempting to get the root path
36555c51f124SMoriah Waterland  */
36565c51f124SMoriah Waterland 
36575c51f124SMoriah Waterland static int
getRootPath(char ** r_rootPath)36585c51f124SMoriah Waterland getRootPath(char **r_rootPath)
36595c51f124SMoriah Waterland {
36605c51f124SMoriah Waterland 	*r_rootPath = _rootPath;
36615c51f124SMoriah Waterland 	return (R_SUCCESS);
36625c51f124SMoriah Waterland }
36635c51f124SMoriah Waterland 
36645c51f124SMoriah Waterland /*
36655c51f124SMoriah Waterland  * Name:	setVerbose
36665c51f124SMoriah Waterland  * Description:	Turns on verbose output
36675c51f124SMoriah Waterland  * Scope:	public
36685c51f124SMoriah Waterland  * Arguments:	verbose = B_TRUE indicates verbose mode
36695c51f124SMoriah Waterland  * Returns:	none
36705c51f124SMoriah Waterland  */
36715c51f124SMoriah Waterland 
36725c51f124SMoriah Waterland static void
setVerbose(boolean_t setting)36735c51f124SMoriah Waterland setVerbose(boolean_t setting)
36745c51f124SMoriah Waterland {
36755c51f124SMoriah Waterland 	/* set log verbose messages */
36765c51f124SMoriah Waterland 
36775c51f124SMoriah Waterland 	log_set_verbose(setting);
36785c51f124SMoriah Waterland 
36795c51f124SMoriah Waterland 	/* set interactive messages */
36805c51f124SMoriah Waterland 
36815c51f124SMoriah Waterland 	echoSetFlag(setting);
36825c51f124SMoriah Waterland }
36835c51f124SMoriah Waterland 
36845c51f124SMoriah Waterland /*
36855c51f124SMoriah Waterland  * Name:	negate_results
36865c51f124SMoriah Waterland  * Description:	control negation of results
36875c51f124SMoriah Waterland  * Scope:	public
36885c51f124SMoriah Waterland  * Arguments:	setting
36895c51f124SMoriah Waterland  *		== B_TRUE indicates negated results mode
36905c51f124SMoriah Waterland  *		== B_FALSE indicates non-negated results mode
36915c51f124SMoriah Waterland  * Returns:	none
36925c51f124SMoriah Waterland  */
36935c51f124SMoriah Waterland 
36945c51f124SMoriah Waterland static void
setNegateResults(boolean_t setting)36955c51f124SMoriah Waterland setNegateResults(boolean_t setting)
36965c51f124SMoriah Waterland {
36975c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_SET_NEGATE_RESULTS,
36985c51f124SMoriah Waterland 		_negateResults, setting);
36995c51f124SMoriah Waterland 
37005c51f124SMoriah Waterland 	_negateResults = setting;
37015c51f124SMoriah Waterland }
37025c51f124SMoriah Waterland 
37035c51f124SMoriah Waterland /*
37045c51f124SMoriah Waterland  * Name:	getNegateResults
37055c51f124SMoriah Waterland  * Description:	Returns whether or not to results are negated
37065c51f124SMoriah Waterland  * Scope:	public
37075c51f124SMoriah Waterland  * Arguments:	none
37085c51f124SMoriah Waterland  * Returns:	B_TRUE - results are negated
37095c51f124SMoriah Waterland  *		B_FALSE - results are not negated
37105c51f124SMoriah Waterland  */
37115c51f124SMoriah Waterland 
37125c51f124SMoriah Waterland static boolean_t
getNegateResults(void)37135c51f124SMoriah Waterland getNegateResults(void)
37145c51f124SMoriah Waterland {
37155c51f124SMoriah Waterland 	return (_negateResults);
37165c51f124SMoriah Waterland }
37175c51f124SMoriah Waterland 
37185c51f124SMoriah Waterland /*
37195c51f124SMoriah Waterland  * Name:	usage
37205c51f124SMoriah Waterland  * Description:	output usage string
37215c51f124SMoriah Waterland  * Arguments:	a_format - format to use to generate message
37225c51f124SMoriah Waterland  *		arguments following a_format - as needed for a_format
37235c51f124SMoriah Waterland  * Output:	Outputs the usage string to stderr.
37245c51f124SMoriah Waterland  * Returns:	R_ERROR
37255c51f124SMoriah Waterland  */
37265c51f124SMoriah Waterland 
37275c51f124SMoriah Waterland static int
usage(char * a_format,...)37285c51f124SMoriah Waterland usage(char *a_format, ...)
37295c51f124SMoriah Waterland {
37305c51f124SMoriah Waterland 	int		cur_cmd;
37315c51f124SMoriah Waterland 	char		cmdlst[LINE_MAX+1] = { '\0' };
37325c51f124SMoriah Waterland 	char		*message;
37335c51f124SMoriah Waterland 	char		bfr[1];
37345c51f124SMoriah Waterland 	char		*p = get_prog_name();
37355c51f124SMoriah Waterland 	size_t		vres = 0;
37365c51f124SMoriah Waterland 	va_list		ap;
37375c51f124SMoriah Waterland 
37385c51f124SMoriah Waterland 	/* entry assertions */
37395c51f124SMoriah Waterland 
37405c51f124SMoriah Waterland 	assert(a_format != NULL);
37415c51f124SMoriah Waterland 	assert(*a_format != '\0');
37425c51f124SMoriah Waterland 
37435c51f124SMoriah Waterland 	/* determine size of the message in bytes */
37445c51f124SMoriah Waterland 
37455c51f124SMoriah Waterland 	va_start(ap, a_format);
37465c51f124SMoriah Waterland 	/* LINTED warning: variable format specifier to vsnprintf(); */
37475c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
37485c51f124SMoriah Waterland 	va_end(ap);
37495c51f124SMoriah Waterland 
37505c51f124SMoriah Waterland 	assert(vres > 0);
37515c51f124SMoriah Waterland 
37525c51f124SMoriah Waterland 	/* allocate storage to hold the message */
37535c51f124SMoriah Waterland 
37545c51f124SMoriah Waterland 	message = (char *)calloc(1, vres+2);
37555c51f124SMoriah Waterland 	assert(message != NULL);
37565c51f124SMoriah Waterland 
37575c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
37585c51f124SMoriah Waterland 
37595c51f124SMoriah Waterland 	va_start(ap, a_format);
37605c51f124SMoriah Waterland 	/* LINTED warning: variable format specifier to vsnprintf(); */
37615c51f124SMoriah Waterland 	vres = vsnprintf(message, vres+1, a_format, ap);
37625c51f124SMoriah Waterland 	va_end(ap);
37635c51f124SMoriah Waterland 
37645c51f124SMoriah Waterland 	assert(vres > 0);
37655c51f124SMoriah Waterland 
37665c51f124SMoriah Waterland 	/* generate list of all defined conditions */
37675c51f124SMoriah Waterland 
37685c51f124SMoriah Waterland 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
37695c51f124SMoriah Waterland 		(void) strlcat(cmdlst, "\t", sizeof (cmdlst));
37705c51f124SMoriah Waterland 		(void) strlcat(cmdlst, cmds[cur_cmd].c_name, sizeof (cmdlst));
37715c51f124SMoriah Waterland 		if (cmds[cur_cmd].c_args != NULL) {
37725c51f124SMoriah Waterland 			(void) strlcat(cmdlst, cmds[cur_cmd].c_args,
37735c51f124SMoriah Waterland 						sizeof (cmdlst));
37745c51f124SMoriah Waterland 		}
37755c51f124SMoriah Waterland 		(void) strlcat(cmdlst, "\n", sizeof (cmdlst));
37765c51f124SMoriah Waterland 	}
37775c51f124SMoriah Waterland 
37785c51f124SMoriah Waterland 	/* output usage with conditions */
37795c51f124SMoriah Waterland 
37805c51f124SMoriah Waterland 	log_msg(LOG_MSG_INFO, MSG_USAGE, message, p ? p : "pkgcond", cmdlst);
37815c51f124SMoriah Waterland 
37825c51f124SMoriah Waterland 	return (R_ERROR);
37835c51f124SMoriah Waterland }
37845c51f124SMoriah Waterland 
37855c51f124SMoriah Waterland /*
37865c51f124SMoriah Waterland  * Name:	parseGlobalData
37875c51f124SMoriah Waterland  * Description:	parse environment global data and store in global data structure
37885c51f124SMoriah Waterland  * Arguments:	a_envVar - pointer to string representing the name of the
37895c51f124SMoriah Waterland  *			environment variable to get and parse
37905c51f124SMoriah Waterland  *		r_gdt - pointer to pointer to global data structure to fill in
37915c51f124SMoriah Waterland  *			using the parsed data from a_envVar
37925c51f124SMoriah Waterland  * Output:	none
37935c51f124SMoriah Waterland  * Returns:	R_SUCCESS - the global data is successfully parsed
37945c51f124SMoriah Waterland  *		R_FAILURE - problem parsing global data
37955c51f124SMoriah Waterland  *		R_ERROR - fatal error attempting to parse global data
37965c51f124SMoriah Waterland  */
37975c51f124SMoriah Waterland 
37985c51f124SMoriah Waterland static int
parseGlobalData(char * a_envVar,GLOBALDATA_T ** r_gdt)37995c51f124SMoriah Waterland parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt)
38005c51f124SMoriah Waterland {
38015c51f124SMoriah Waterland 	int		r;
38025c51f124SMoriah Waterland 	int		n;
38035c51f124SMoriah Waterland 	char		*a;
38045c51f124SMoriah Waterland 	SML_TAG		*tag;
38055c51f124SMoriah Waterland 	SML_TAG		*ntag;
38065c51f124SMoriah Waterland 
38075c51f124SMoriah Waterland 	assert(r_gdt != (GLOBALDATA_T **)NULL);
38085c51f124SMoriah Waterland 
38095c51f124SMoriah Waterland 	/*
38105c51f124SMoriah Waterland 	 * allocate space for global data structure if needed
38115c51f124SMoriah Waterland 	 */
38125c51f124SMoriah Waterland 
38135c51f124SMoriah Waterland 	if (*r_gdt == (GLOBALDATA_T *)NULL) {
38145c51f124SMoriah Waterland 		*r_gdt = (GLOBALDATA_T *)calloc(1, sizeof (GLOBALDATA_T));
38155c51f124SMoriah Waterland 	}
38165c51f124SMoriah Waterland 
38175c51f124SMoriah Waterland 	/*
38185c51f124SMoriah Waterland 	 * get initial installation indication:
38195c51f124SMoriah Waterland 	 * If the initial install variable is set to "true", then an initial
38205c51f124SMoriah Waterland 	 * installation of Solaris is underway. When this condition is true:
38215c51f124SMoriah Waterland 	 * - if the path being checked is the package install root, then
38225c51f124SMoriah Waterland 	 *   the path is considered to be an 'alternative root' which is
38235c51f124SMoriah Waterland 	 *   currently being installed.
38245c51f124SMoriah Waterland 	 * - if the path being checked is not the package install root, then
38255c51f124SMoriah Waterland 	 *   the path needs to be further analyzed to determine what it may
38265c51f124SMoriah Waterland 	 *   be referring to.
38275c51f124SMoriah Waterland 	 */
38285c51f124SMoriah Waterland 
38295c51f124SMoriah Waterland 	a = getenv(ENV_VAR_INITIAL_INSTALL);
38305c51f124SMoriah Waterland 	if ((a != NULL) && (strcasecmp(a, "true") == 0)) {
38315c51f124SMoriah Waterland 		(*r_gdt)->gd_initialInstall = B_TRUE;
38325c51f124SMoriah Waterland 	}
38335c51f124SMoriah Waterland 
38345c51f124SMoriah Waterland 	/* get current zone name */
38355c51f124SMoriah Waterland 
38365c51f124SMoriah Waterland 	r = getZoneName(&(*r_gdt)->gd_zoneName);
38375c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
38385c51f124SMoriah Waterland 		(*r_gdt)->gd_zoneName = "";
38395c51f124SMoriah Waterland 	}
38405c51f124SMoriah Waterland 
38415c51f124SMoriah Waterland 	/*
38425c51f124SMoriah Waterland 	 * get zone installation status:
38435c51f124SMoriah Waterland 	 * - If the package install zone name is not set, then an installation
38445c51f124SMoriah Waterland 	 *   of a global zone, or of a non-global zone, is not underway.
38455c51f124SMoriah Waterland 	 * - If the package install zone name is set to "global", then an
38465c51f124SMoriah Waterland 	 *   installation of a global zone is underway. In this case, no path
38475c51f124SMoriah Waterland 	 *   can be a netinstall image, diskless client, mounted miniroot,
38485c51f124SMoriah Waterland 	 *   non-global zone, the current running system, alternative root,
38495c51f124SMoriah Waterland 	 *   or alternative boot environment.
38505c51f124SMoriah Waterland 	 * - If the package install zone name is set to a value other than
38515c51f124SMoriah Waterland 	 *   "global", then an installation of a non-global zone with that name
38525c51f124SMoriah Waterland 	 *   is underway.  In this case, no path can be a netinstall image,
38535c51f124SMoriah Waterland 	 *   diskless client, mounted miniroot, global zone, the current
38545c51f124SMoriah Waterland 	 *   running system, alternative root, or alternative boot environment.
38555c51f124SMoriah Waterland 	 */
38565c51f124SMoriah Waterland 
38575c51f124SMoriah Waterland 	a = getenv(ENV_VAR_PKGZONENAME);
38585c51f124SMoriah Waterland 	if ((a == NULL) || (*a == '\0')) {
38595c51f124SMoriah Waterland 		/* not installing a zone */
38605c51f124SMoriah Waterland 		(*r_gdt)->gd_globalZoneInstall = B_FALSE;
38615c51f124SMoriah Waterland 		(*r_gdt)->gd_nonglobalZoneInstall = B_FALSE;
38625c51f124SMoriah Waterland 	} else if (strcmp(a, GLOBAL_ZONENAME) == 0) {
38635c51f124SMoriah Waterland 		/* installing a global zone */
38645c51f124SMoriah Waterland 		(*r_gdt)->gd_globalZoneInstall = B_TRUE;
38655c51f124SMoriah Waterland 		(*r_gdt)->gd_nonglobalZoneInstall = B_FALSE;
38665c51f124SMoriah Waterland 		(*r_gdt)->gd_zoneName = a;
38675c51f124SMoriah Waterland 	} else {
38685c51f124SMoriah Waterland 		/* installing a non-global zone by that name */
38695c51f124SMoriah Waterland 		(*r_gdt)->gd_globalZoneInstall = B_FALSE;
38705c51f124SMoriah Waterland 		(*r_gdt)->gd_nonglobalZoneInstall = B_TRUE;
38715c51f124SMoriah Waterland 		(*r_gdt)->gd_zoneName = a;
38725c51f124SMoriah Waterland 	}
38735c51f124SMoriah Waterland 
38745c51f124SMoriah Waterland 	/*
3875*4656d474SGarrett D'Amore 	 * get package install root.
38765c51f124SMoriah Waterland 	 */
38775c51f124SMoriah Waterland 
38785c51f124SMoriah Waterland 	a = getenv(ENV_VAR_PKGROOT);
38795c51f124SMoriah Waterland 	if ((a != NULL) && (*a != '\0')) {
38805c51f124SMoriah Waterland 		(*r_gdt)->gd_installRoot = a;
38815c51f124SMoriah Waterland 	} else {
38825c51f124SMoriah Waterland 		(*r_gdt)->gd_installRoot = "/";
38835c51f124SMoriah Waterland 	}
38845c51f124SMoriah Waterland 
38855c51f124SMoriah Waterland 	/* get the global data environment variable */
38865c51f124SMoriah Waterland 
38875c51f124SMoriah Waterland 	a = getenv(a_envVar);
38885c51f124SMoriah Waterland 
38895c51f124SMoriah Waterland 	/* if no data then issue warning and return success */
38905c51f124SMoriah Waterland 
38915c51f124SMoriah Waterland 	if ((a == NULL) || (*a_envVar == '\0')) {
38925c51f124SMoriah Waterland 		log_msg(LOG_MSG_DEBUG, DBG_NO_GLOBAL_DATA_AVAILABLE, a_envVar);
38935c51f124SMoriah Waterland 		return (R_SUCCESS);
38945c51f124SMoriah Waterland 	}
38955c51f124SMoriah Waterland 
38965c51f124SMoriah Waterland 	/* data present - parse into SML structure */
38975c51f124SMoriah Waterland 
38985c51f124SMoriah Waterland 	log_msg(LOG_MSG_DEBUG, DBG_PARSE_GLOBAL, a);
38995c51f124SMoriah Waterland 
39005c51f124SMoriah Waterland 	r = smlConvertStringToTag(&tag, a);
39015c51f124SMoriah Waterland 	if (r != R_SUCCESS) {
39025c51f124SMoriah Waterland 		log_msg(LOG_MSG_ERR, ERR_CANNOT_PARSE_GLOBAL_DATA, a);
39035c51f124SMoriah Waterland 		return (R_FAILURE);
39045c51f124SMoriah Waterland 	}
39055c51f124SMoriah Waterland 
39065c51f124SMoriah Waterland 	smlDbgPrintTag(tag, DBG_PARSED_ENVIRONMENT, a_envVar);
39075c51f124SMoriah Waterland 
39085c51f124SMoriah Waterland 	/* fill in global data structure */
39095c51f124SMoriah Waterland 
39105c51f124SMoriah Waterland 	/* find the environment condition information structure */
39115c51f124SMoriah Waterland 
39125c51f124SMoriah Waterland 	ntag = smlGetTagByName(tag, 0, TAG_COND_TOPLEVEL);
39135c51f124SMoriah Waterland 	if (ntag == SML_TAG__NULL) {
39145c51f124SMoriah Waterland 		log_msg(LOG_MSG_WRN, WRN_PARSED_DATA_MISSING,
39155c51f124SMoriah Waterland 			TAG_COND_TOPLEVEL);
39165c51f124SMoriah Waterland 		return (R_FAILURE);
39175c51f124SMoriah Waterland 	}
39185c51f124SMoriah Waterland 
39195c51f124SMoriah Waterland 	/*
39205c51f124SMoriah Waterland 	 * data found - extract what we know about
39215c51f124SMoriah Waterland 	 */
39225c51f124SMoriah Waterland 
39235c51f124SMoriah Waterland 	/* parent zone name */
39245c51f124SMoriah Waterland 
39255c51f124SMoriah Waterland 	a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_NAME);
39265c51f124SMoriah Waterland 	(*r_gdt)->gd_parentZoneName = a;
39275c51f124SMoriah Waterland 
39285c51f124SMoriah Waterland 	/* parent zone type */
39295c51f124SMoriah Waterland 
39305c51f124SMoriah Waterland 	a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_TYPE);
39315c51f124SMoriah Waterland 	(*r_gdt)->gd_parentZoneType = a;
39325c51f124SMoriah Waterland 
39335c51f124SMoriah Waterland 	/* current zone name */
39345c51f124SMoriah Waterland 
39355c51f124SMoriah Waterland 	a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE,
39365c51f124SMoriah Waterland 		TAG_COND_ZONE_NAME);
39375c51f124SMoriah Waterland 	(*r_gdt)->gd_currentZoneName = a;
39385c51f124SMoriah Waterland 
39395c51f124SMoriah Waterland 	/* current zone type */
39405c51f124SMoriah Waterland 
39415c51f124SMoriah Waterland 	a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE,
39425c51f124SMoriah Waterland 		TAG_COND_ZONE_TYPE);
39435c51f124SMoriah Waterland 	(*r_gdt)->gd_currentZoneType = a;
39445c51f124SMoriah Waterland 
39455c51f124SMoriah Waterland 	return (R_SUCCESS);
39465c51f124SMoriah Waterland }
39475c51f124SMoriah Waterland 
39485c51f124SMoriah Waterland /*
39495c51f124SMoriah Waterland  * Name:	dumpGlobalData
39505c51f124SMoriah Waterland  * Description:	dump global data structure using echoDebug
39515c51f124SMoriah Waterland  * Arguments:	a_gdt - pointer to global data structure to dump
39525c51f124SMoriah Waterland  * Outputs:	echoDebug is called to output global data strucutre information
39535c51f124SMoriah Waterland  * Returns:	void
39545c51f124SMoriah Waterland  */
39555c51f124SMoriah Waterland 
39565c51f124SMoriah Waterland static void
dumpGlobalData(GLOBALDATA_T * a_gdt)39575c51f124SMoriah Waterland dumpGlobalData(GLOBALDATA_T *a_gdt)
39585c51f124SMoriah Waterland {
39595c51f124SMoriah Waterland 	/* entry assertions */
39605c51f124SMoriah Waterland 
39615c51f124SMoriah Waterland 	assert(a_gdt != (GLOBALDATA_T *)NULL);
39625c51f124SMoriah Waterland 
39635c51f124SMoriah Waterland 	/* debugging enabled, dump the global data structure */
39645c51f124SMoriah Waterland 
39655c51f124SMoriah Waterland 	echoDebug(DBG_DUMP_GLOBAL_ENTRY);
39665c51f124SMoriah Waterland 	echoDebug(DBG_DUMP_GLOBAL_PARENT_ZONE,
39675c51f124SMoriah Waterland 		a_gdt->gd_parentZoneName ? a_gdt->gd_parentZoneName : "",
39685c51f124SMoriah Waterland 		a_gdt->gd_parentZoneType ? a_gdt->gd_parentZoneType : "");
39695c51f124SMoriah Waterland 	echoDebug(DBG_DUMP_GLOBAL_CURRENT_ZONE,
39705c51f124SMoriah Waterland 		a_gdt->gd_currentZoneName ? a_gdt->gd_currentZoneName : "",
39715c51f124SMoriah Waterland 		a_gdt->gd_currentZoneType ? a_gdt->gd_currentZoneType : "");
39725c51f124SMoriah Waterland 
39735c51f124SMoriah Waterland }
39745c51f124SMoriah Waterland 
39755c51f124SMoriah Waterland /*
39765c51f124SMoriah Waterland  * Name:	recursionCheck
39775c51f124SMoriah Waterland  * Description:	prevent recursive calling of functions
39785c51f124SMoriah Waterland  * Arguments:	r_recursion - pointer to int recursion counter
39795c51f124SMoriah Waterland  *		a_function - pointer to name of function
39805c51f124SMoriah Waterland  * Returns:	B_TRUE - function is recursively called
39815c51f124SMoriah Waterland  *		B_FALSE - function not recursively called
39825c51f124SMoriah Waterland  */
39835c51f124SMoriah Waterland 
39845c51f124SMoriah Waterland static boolean_t
recursionCheck(int * r_recursion,char * a_function)39855c51f124SMoriah Waterland recursionCheck(int *r_recursion, char *a_function)
39865c51f124SMoriah Waterland {
39875c51f124SMoriah Waterland 	/* prevent recursion */
39885c51f124SMoriah Waterland 
39895c51f124SMoriah Waterland 	(*r_recursion)++;
39905c51f124SMoriah Waterland 	if (*r_recursion > 1) {
39915c51f124SMoriah Waterland 		echoDebug(DBG_RECURSION, a_function, *r_recursion);
39925c51f124SMoriah Waterland 		(*r_recursion)--;
39935c51f124SMoriah Waterland 		return (B_TRUE);
39945c51f124SMoriah Waterland 	}
39955c51f124SMoriah Waterland 
39965c51f124SMoriah Waterland 	echoDebug(DBG_NO_RECURSION, a_function);
39975c51f124SMoriah Waterland 	return (B_FALSE);
39985c51f124SMoriah Waterland }
39995c51f124SMoriah Waterland 
40005c51f124SMoriah Waterland /*
40015c51f124SMoriah Waterland  * Name:	quit
40025c51f124SMoriah Waterland  * Description:	cleanup and exit
40035c51f124SMoriah Waterland  * Arguments:	a_retcode - the code to use to determine final exit status;
40045c51f124SMoriah Waterland  *			if this is NOT "99" and if a "ckreturnFunc" is
40055c51f124SMoriah Waterland  *			set, then that function is called with a_retcode
40065c51f124SMoriah Waterland  *			to set the final exit status.
40075c51f124SMoriah Waterland  *		Valid values are:
40085c51f124SMoriah Waterland  *		0 - success
40095c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
40105c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
40115c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
40125c51f124SMoriah Waterland  *		4 - admin settings prevented operation
40135c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
40145c51f124SMoriah Waterland  *		"10" is added to indicate "immediate reboot required"
40155c51f124SMoriah Waterland  *		"20" is be added to indicate "reboot after install required"
40165c51f124SMoriah Waterland  *		99 - do not interpret the code - just exit "99"
40175c51f124SMoriah Waterland  * Returns:	<<this function does not return - calls exit()>>
40185c51f124SMoriah Waterland  * NOTE:	This is needed because libinst functions can call "quit(99)"
40195c51f124SMoriah Waterland  *		to force an error exit.
40205c51f124SMoriah Waterland  */
40215c51f124SMoriah Waterland 
40225c51f124SMoriah Waterland void
quit(int a_retcode)40235c51f124SMoriah Waterland quit(int a_retcode)
40245c51f124SMoriah Waterland {
40255c51f124SMoriah Waterland 	/* process return code if not quit(99) */
40265c51f124SMoriah Waterland 
40275c51f124SMoriah Waterland 	if (a_retcode == 99) {
40285c51f124SMoriah Waterland 		exit(0x7f);	/* processing error (127) */
40295c51f124SMoriah Waterland 	}
40305c51f124SMoriah Waterland 
40315c51f124SMoriah Waterland 	exit(R_FAILURE);
40325c51f124SMoriah Waterland }
4033