xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgcond/main.c (revision 12734:76969fc28795)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
23*12734Sgary.pennington@oracle.com  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
249781SMoriah.Waterland@Sun.COM  */
259781SMoriah.Waterland@Sun.COM 
269781SMoriah.Waterland@Sun.COM 
279781SMoriah.Waterland@Sun.COM /*
289781SMoriah.Waterland@Sun.COM  * Program:	pkgcond
299781SMoriah.Waterland@Sun.COM  *
309781SMoriah.Waterland@Sun.COM  * Function:	Implements the package command suite public utility pkgcond(1M)
319781SMoriah.Waterland@Sun.COM  *
329781SMoriah.Waterland@Sun.COM  * Usage:	pkgcond [-nv] [-O debug] condition [ argument ]
339781SMoriah.Waterland@Sun.COM  *
349781SMoriah.Waterland@Sun.COM  *		command options:
359781SMoriah.Waterland@Sun.COM  *			-n - negate results of condition test
369781SMoriah.Waterland@Sun.COM  *			-v - verbose output of condition testing
379781SMoriah.Waterland@Sun.COM  *
389781SMoriah.Waterland@Sun.COM  *		<condition> may be any one of:
399781SMoriah.Waterland@Sun.COM  *			can_add_driver [path]
409781SMoriah.Waterland@Sun.COM  *			can_remove_driver [path]
419781SMoriah.Waterland@Sun.COM  *			can_update_driver [path]
429781SMoriah.Waterland@Sun.COM  *			is_alternative_root [path]
439781SMoriah.Waterland@Sun.COM  *			is_boot_environment [path]
449781SMoriah.Waterland@Sun.COM  *			is_diskless_client [path]
459781SMoriah.Waterland@Sun.COM  *			is_global_zone [path]
469781SMoriah.Waterland@Sun.COM  *			is_mounted_miniroot [path]
479781SMoriah.Waterland@Sun.COM  *			is_netinstall_image [path]
489781SMoriah.Waterland@Sun.COM  *			is_nonglobal_zone [path]
499781SMoriah.Waterland@Sun.COM  *			is_path_writable path
509781SMoriah.Waterland@Sun.COM  *			is_running_system [path]
519781SMoriah.Waterland@Sun.COM  *			is_what [path]
529781SMoriah.Waterland@Sun.COM  *			is_whole_root_nonglobal_zone [path]
539781SMoriah.Waterland@Sun.COM  *
549781SMoriah.Waterland@Sun.COM  *		<option(s)> are specific to the condition used
559781SMoriah.Waterland@Sun.COM  *
569781SMoriah.Waterland@Sun.COM  * Input:	depends on command
579781SMoriah.Waterland@Sun.COM  *
589781SMoriah.Waterland@Sun.COM  * Output:	depends on command
599781SMoriah.Waterland@Sun.COM  *
609781SMoriah.Waterland@Sun.COM  * Exit status:	If the -n option is not specified:
619781SMoriah.Waterland@Sun.COM  *		== 0 - the specified condition is true (or exists).
629781SMoriah.Waterland@Sun.COM  *		== 1 - the specified condition is false (or does not exist).
639781SMoriah.Waterland@Sun.COM  *		== 2 - command line usage errors (including bad keywords)
649781SMoriah.Waterland@Sun.COM  *		== 3 - command failed to perform the test due to a fatal error
659781SMoriah.Waterland@Sun.COM  *
669781SMoriah.Waterland@Sun.COM  *		If the -n option is specified:
679781SMoriah.Waterland@Sun.COM  *		== 0 - the specified condition is false (or does not exist).
689781SMoriah.Waterland@Sun.COM  *		== 1 - the specified condition is true (or exists).
699781SMoriah.Waterland@Sun.COM  *		== 2 - command line usage errors (including bad keywords)
709781SMoriah.Waterland@Sun.COM  *		== 3 - command failed to perform the test due to a fatal error
719781SMoriah.Waterland@Sun.COM  */
729781SMoriah.Waterland@Sun.COM 
739781SMoriah.Waterland@Sun.COM #include <stdio.h>
749781SMoriah.Waterland@Sun.COM #include <sys/mnttab.h>
759781SMoriah.Waterland@Sun.COM #include <sys/mntent.h>
769781SMoriah.Waterland@Sun.COM #include <stdarg.h>
779781SMoriah.Waterland@Sun.COM #include <stdlib.h>
789781SMoriah.Waterland@Sun.COM #include <string.h>
799781SMoriah.Waterland@Sun.COM #include <strings.h>
809781SMoriah.Waterland@Sun.COM #include <fcntl.h>
819781SMoriah.Waterland@Sun.COM #include <ctype.h>
829781SMoriah.Waterland@Sun.COM #include <sys/types.h>
839781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
849781SMoriah.Waterland@Sun.COM #include <unistd.h>
859781SMoriah.Waterland@Sun.COM #include <locale.h>
869781SMoriah.Waterland@Sun.COM #include <errno.h>
879781SMoriah.Waterland@Sun.COM #include <sys/param.h>
889781SMoriah.Waterland@Sun.COM #include <assert.h>
899781SMoriah.Waterland@Sun.COM 
909781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
919781SMoriah.Waterland@Sun.COM #include <pkglib.h>
929781SMoriah.Waterland@Sun.COM #include <install.h>
939781SMoriah.Waterland@Sun.COM #include <libinst.h>
949781SMoriah.Waterland@Sun.COM #include <libadm.h>
959781SMoriah.Waterland@Sun.COM #include <messages.h>
969781SMoriah.Waterland@Sun.COM #include "pkgcond.h"
979781SMoriah.Waterland@Sun.COM #include "pkgcond_msgs.h"
989781SMoriah.Waterland@Sun.COM 
999781SMoriah.Waterland@Sun.COM /* Should be defined by cc -D */
1009781SMoriah.Waterland@Sun.COM 
1019781SMoriah.Waterland@Sun.COM #if	!defined(TEXT_DOMAIN)
1029781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
1039781SMoriah.Waterland@Sun.COM #endif
1049781SMoriah.Waterland@Sun.COM 
1059781SMoriah.Waterland@Sun.COM /* commands to execute */
1069781SMoriah.Waterland@Sun.COM 
1079781SMoriah.Waterland@Sun.COM #define	LS_CMD		"/usr/bin/ls"
1089781SMoriah.Waterland@Sun.COM 
1099781SMoriah.Waterland@Sun.COM /*
1109781SMoriah.Waterland@Sun.COM  * type definition and "types" for testPath()
1119781SMoriah.Waterland@Sun.COM  */
1129781SMoriah.Waterland@Sun.COM 
1139781SMoriah.Waterland@Sun.COM typedef enum {
1149781SMoriah.Waterland@Sun.COM 	TEST_EXISTS = 0x01,
1159781SMoriah.Waterland@Sun.COM 	TEST_NOT_EXISTS = 0x02,
1169781SMoriah.Waterland@Sun.COM 	TEST_IS_DIRECTORY = 0x04,
1179781SMoriah.Waterland@Sun.COM 	TEST_IS_FILE = 0x08,
1189781SMoriah.Waterland@Sun.COM 	TEST_NOT_DIRECTORY = 0x10,
1199781SMoriah.Waterland@Sun.COM 	TEST_NOT_FILE = 0x20,
1209781SMoriah.Waterland@Sun.COM 	TEST_IS_SYMBOLIC_LINK = 0x40,
1219781SMoriah.Waterland@Sun.COM 	TEST_NOT_SYMBOLIC_LINK = 0x80,
1229781SMoriah.Waterland@Sun.COM 	TEST_GLOBAL_TOKEN_IN_FILE = 0x100
1239781SMoriah.Waterland@Sun.COM } TEST_TYPES;
1249781SMoriah.Waterland@Sun.COM 
1259781SMoriah.Waterland@Sun.COM /* holds file system info */
1269781SMoriah.Waterland@Sun.COM 
1279781SMoriah.Waterland@Sun.COM struct fsi_t {
1289781SMoriah.Waterland@Sun.COM 	char	*fsi_mntOptions;
1299781SMoriah.Waterland@Sun.COM 	char	*fsi_fsType;
1309781SMoriah.Waterland@Sun.COM 	char	*fsi_mntPoint;
1319781SMoriah.Waterland@Sun.COM };
1329781SMoriah.Waterland@Sun.COM typedef struct fsi_t	FSI_T;
1339781SMoriah.Waterland@Sun.COM 
1349781SMoriah.Waterland@Sun.COM /* holds parsed global data */
1359781SMoriah.Waterland@Sun.COM 
1369781SMoriah.Waterland@Sun.COM struct globalData_t {
1379781SMoriah.Waterland@Sun.COM 		/* initial install: PKG_INIT_INSTALL=true */
1389781SMoriah.Waterland@Sun.COM 	boolean_t gd_initialInstall;
1399781SMoriah.Waterland@Sun.COM 		/* global zone install: SUNW_PKG_INSTALL_ZONENAME=global */
1409781SMoriah.Waterland@Sun.COM 	boolean_t gd_globalZoneInstall;
1419781SMoriah.Waterland@Sun.COM 		/* non-global zone install: SUNW_PKG_INSTALL_ZONENAME!=global */
1429781SMoriah.Waterland@Sun.COM 	boolean_t gd_nonglobalZoneInstall;
1439781SMoriah.Waterland@Sun.COM 		/* non-global zone is in a mounted state */
1449781SMoriah.Waterland@Sun.COM 	boolean_t inMountedState;
1459781SMoriah.Waterland@Sun.COM 		/* sorted list of all mounted file systems */
1469781SMoriah.Waterland@Sun.COM 	FSI_T	*gd_fileSystemConfig;
1479781SMoriah.Waterland@Sun.COM 		/* number of mounted file systems in list */
1489781SMoriah.Waterland@Sun.COM 	long	gd_fileSystemConfigLen;
1499781SMoriah.Waterland@Sun.COM 		/* current zone name */
1509781SMoriah.Waterland@Sun.COM 	char	*gd_zoneName;
1519781SMoriah.Waterland@Sun.COM 		/* version of target: PATCH_CLIENT_VERSION */
1529781SMoriah.Waterland@Sun.COM 	char	*gd_patchClientVersion;
1539781SMoriah.Waterland@Sun.COM 		/* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneName */
1549781SMoriah.Waterland@Sun.COM 	char	*gd_parentZoneName;
1559781SMoriah.Waterland@Sun.COM 		/* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneType */
1569781SMoriah.Waterland@Sun.COM 	char	*gd_parentZoneType;
1579781SMoriah.Waterland@Sun.COM 		/* root path to target: PKG_INSTALL_ROOT */
1589781SMoriah.Waterland@Sun.COM 	char	*gd_installRoot;
1599781SMoriah.Waterland@Sun.COM 		/* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneName */
1609781SMoriah.Waterland@Sun.COM 	char	*gd_currentZoneName;
1619781SMoriah.Waterland@Sun.COM 		/* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneType */
1629781SMoriah.Waterland@Sun.COM 	char	*gd_currentZoneType;
1639781SMoriah.Waterland@Sun.COM 		/* path provided on command line */
1649781SMoriah.Waterland@Sun.COM 	char	*gd_cmdline_path;
1659781SMoriah.Waterland@Sun.COM };
1669781SMoriah.Waterland@Sun.COM typedef struct globalData_t	GLOBALDATA_T;
1679781SMoriah.Waterland@Sun.COM 
1689781SMoriah.Waterland@Sun.COM /* holds subcommands and their definitions */
1699781SMoriah.Waterland@Sun.COM 
1709781SMoriah.Waterland@Sun.COM struct cmd_t {
1719781SMoriah.Waterland@Sun.COM 	char		*c_name;
1729781SMoriah.Waterland@Sun.COM 	char		*c_args;
1739781SMoriah.Waterland@Sun.COM 	int		(*c_func)(int argc, char **argv, GLOBALDATA_T *a_gdt);
1749781SMoriah.Waterland@Sun.COM };
1759781SMoriah.Waterland@Sun.COM typedef struct cmd_t	CMD_T;
1769781SMoriah.Waterland@Sun.COM 
1779781SMoriah.Waterland@Sun.COM /* Command function prototypes */
1789781SMoriah.Waterland@Sun.COM 
1799781SMoriah.Waterland@Sun.COM static int		cmd_can_add_driver(int argc, char **argv,
1809781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1819781SMoriah.Waterland@Sun.COM static int		cmd_can_remove_driver(int argc, char **argv,
1829781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1839781SMoriah.Waterland@Sun.COM static int		cmd_can_update_driver(int argc, char **argv,
1849781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1859781SMoriah.Waterland@Sun.COM static int		cmd_is_alternative_root(int argc, char **argv,
1869781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1879781SMoriah.Waterland@Sun.COM static int		cmd_is_boot_environment(int argc, char **argv,
1889781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1899781SMoriah.Waterland@Sun.COM static int		cmd_is_diskless_client(int argc, char **argv,
1909781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1919781SMoriah.Waterland@Sun.COM static int		cmd_is_global_zone(int argc, char **argv,
1929781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1939781SMoriah.Waterland@Sun.COM static int		cmd_is_mounted_miniroot(int argc, char **argv,
1949781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1959781SMoriah.Waterland@Sun.COM static int		cmd_is_netinstall_image(int argc, char **argv,
1969781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1979781SMoriah.Waterland@Sun.COM static int		cmd_is_nonglobal_zone(int argc, char **argv,
1989781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
1999781SMoriah.Waterland@Sun.COM static int		cmd_is_path_writable(int argc, char **argv,
2009781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
2019781SMoriah.Waterland@Sun.COM static int		cmd_is_running_system(int argc, char **argv,
2029781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
2039781SMoriah.Waterland@Sun.COM static int		cmd_is_what(int argc, char **argv,
2049781SMoriah.Waterland@Sun.COM 				GLOBALDATA_T *a_gdt);
2059781SMoriah.Waterland@Sun.COM 
2069781SMoriah.Waterland@Sun.COM /* Utility function Prototypes */
2079781SMoriah.Waterland@Sun.COM 
2089781SMoriah.Waterland@Sun.COM static boolean_t	getNegateResults(void);
2099781SMoriah.Waterland@Sun.COM static boolean_t	recursionCheck(int *r_recursion, char *a_function);
2109781SMoriah.Waterland@Sun.COM static int		adjustResults(int a_result);
2119781SMoriah.Waterland@Sun.COM static int		calculateFileSystemConfig(GLOBALDATA_T *a_gdt);
2129781SMoriah.Waterland@Sun.COM static int		getRootPath(char **r_rootPath);
2139781SMoriah.Waterland@Sun.COM static int		getZoneName(char **r_zoneName);
2149781SMoriah.Waterland@Sun.COM static int		mountOptionPresent(char *a_mntOptions, char *a_opt);
2159781SMoriah.Waterland@Sun.COM static int		parseGlobalData(char *a_envVar, GLOBALDATA_T **a_gdt);
2169781SMoriah.Waterland@Sun.COM static int		resolvePath(char **r_path);
2179781SMoriah.Waterland@Sun.COM static int		setRootPath(char *a_path, char *a_envVar,
2189781SMoriah.Waterland@Sun.COM     boolean_t a_mustExist);
2199781SMoriah.Waterland@Sun.COM static int		testPath(TEST_TYPES a_tt, char *format, ...);
2209781SMoriah.Waterland@Sun.COM static int		usage(char *a_format, ...);
2219781SMoriah.Waterland@Sun.COM static int		findToken(char *path, char *token);
2229781SMoriah.Waterland@Sun.COM static char		*getMountOption(char **p);
2239781SMoriah.Waterland@Sun.COM static void		dumpGlobalData(GLOBALDATA_T *a_gdt);
2249781SMoriah.Waterland@Sun.COM static void		removeLeadingWhitespace(char **a_str);
2259781SMoriah.Waterland@Sun.COM static void		setNegateResults(boolean_t setting);
2269781SMoriah.Waterland@Sun.COM static void		setVerbose(boolean_t);
2279781SMoriah.Waterland@Sun.COM static void		sortedInsert(FSI_T **r_list, long *a_listSize,
2289781SMoriah.Waterland@Sun.COM     char *a_mntPoint, char *a_fsType, char *a_mntOptions);
2299781SMoriah.Waterland@Sun.COM static void		setCmdLinePath(char **a_path, char **args,
2309781SMoriah.Waterland@Sun.COM     int num_args);
2319781SMoriah.Waterland@Sun.COM 
2329781SMoriah.Waterland@Sun.COM /* local static data */
2339781SMoriah.Waterland@Sun.COM 
2349781SMoriah.Waterland@Sun.COM static boolean_t	_negateResults = B_FALSE;
2359781SMoriah.Waterland@Sun.COM static char		*_rootPath = "/";
2369781SMoriah.Waterland@Sun.COM 
2379781SMoriah.Waterland@Sun.COM /* define subcommand data structure */
2389781SMoriah.Waterland@Sun.COM 
2399781SMoriah.Waterland@Sun.COM static CMD_T cmds[] = {
2409781SMoriah.Waterland@Sun.COM 	{ "can_add_driver",		" [path]",
2419781SMoriah.Waterland@Sun.COM 		cmd_can_add_driver },
2429781SMoriah.Waterland@Sun.COM 	{ "can_remove_driver",		" [path]",
2439781SMoriah.Waterland@Sun.COM 		cmd_can_remove_driver },
2449781SMoriah.Waterland@Sun.COM 	{ "can_update_driver",		" [path]",
2459781SMoriah.Waterland@Sun.COM 		cmd_can_update_driver },
2469781SMoriah.Waterland@Sun.COM 	{ "is_alternative_root",	" [path]",
2479781SMoriah.Waterland@Sun.COM 		cmd_is_alternative_root },
2489781SMoriah.Waterland@Sun.COM 	{ "is_boot_environment",	" [path]",
2499781SMoriah.Waterland@Sun.COM 		cmd_is_boot_environment },
2509781SMoriah.Waterland@Sun.COM 	{ "is_diskless_client",		" [path]",
2519781SMoriah.Waterland@Sun.COM 		cmd_is_diskless_client },
2529781SMoriah.Waterland@Sun.COM 	{ "is_global_zone",		" [path]",
2539781SMoriah.Waterland@Sun.COM 		cmd_is_global_zone },
2549781SMoriah.Waterland@Sun.COM 	{ "is_mounted_miniroot",	" [path]",
2559781SMoriah.Waterland@Sun.COM 		cmd_is_mounted_miniroot },
2569781SMoriah.Waterland@Sun.COM 	{ "is_netinstall_image",	" [path]",
2579781SMoriah.Waterland@Sun.COM 		cmd_is_netinstall_image },
2589781SMoriah.Waterland@Sun.COM 	{ "is_nonglobal_zone",		" [path]",
2599781SMoriah.Waterland@Sun.COM 		cmd_is_nonglobal_zone },
2609781SMoriah.Waterland@Sun.COM 	{ "is_path_writable",		" path",
2619781SMoriah.Waterland@Sun.COM 		cmd_is_path_writable },
2629781SMoriah.Waterland@Sun.COM 	{ "is_running_system",		" [path]",
2639781SMoriah.Waterland@Sun.COM 		cmd_is_running_system },
2649781SMoriah.Waterland@Sun.COM 	{ "is_what", " [path]",
2659781SMoriah.Waterland@Sun.COM 		cmd_is_what },
2669781SMoriah.Waterland@Sun.COM 	/* last one must be all NULLs */
267*12734Sgary.pennington@oracle.com 	{ NULL, NULL, NULL }
2689781SMoriah.Waterland@Sun.COM };
2699781SMoriah.Waterland@Sun.COM 
2709781SMoriah.Waterland@Sun.COM /*
2719781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2729781SMoriah.Waterland@Sun.COM  * main
2739781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2749781SMoriah.Waterland@Sun.COM  */
2759781SMoriah.Waterland@Sun.COM 
2769781SMoriah.Waterland@Sun.COM /*
2779781SMoriah.Waterland@Sun.COM  * Name:	main
2789781SMoriah.Waterland@Sun.COM  * Description:	main processing loop for pkgcond *
2799781SMoriah.Waterland@Sun.COM  * Return:	0 - condition is satisfied (true)
2809781SMoriah.Waterland@Sun.COM  *		1 - condition is not satisfied (false)
2819781SMoriah.Waterland@Sun.COM  *		2 - command line usage errors
2829781SMoriah.Waterland@Sun.COM  *		3 - failure to determine condition
2839781SMoriah.Waterland@Sun.COM  */
2849781SMoriah.Waterland@Sun.COM 
2859781SMoriah.Waterland@Sun.COM int
main(int argc,char ** argv)2869781SMoriah.Waterland@Sun.COM main(int argc, char **argv)
2879781SMoriah.Waterland@Sun.COM {
2889781SMoriah.Waterland@Sun.COM 	GLOBALDATA_T	*gdt = NULL;
2899781SMoriah.Waterland@Sun.COM 	char		**newargv;
2909781SMoriah.Waterland@Sun.COM 	char		*p;
2919781SMoriah.Waterland@Sun.COM 	int		cur_cmd;
2929781SMoriah.Waterland@Sun.COM 	int		i;
2939781SMoriah.Waterland@Sun.COM 	int		newargc;
2949781SMoriah.Waterland@Sun.COM 
2959781SMoriah.Waterland@Sun.COM 	/* make standard output non-buffered */
2969781SMoriah.Waterland@Sun.COM 
2979781SMoriah.Waterland@Sun.COM 	setbuf(stdout, NULL);
2989781SMoriah.Waterland@Sun.COM 
2999781SMoriah.Waterland@Sun.COM 	/* set the default text domain for messaging */
3009781SMoriah.Waterland@Sun.COM 
3019781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
3029781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
3039781SMoriah.Waterland@Sun.COM 
3049781SMoriah.Waterland@Sun.COM 	/* remember command name */
3059781SMoriah.Waterland@Sun.COM 
3069781SMoriah.Waterland@Sun.COM 	set_prog_name(argv[0]);
3079781SMoriah.Waterland@Sun.COM 
3089781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
3099781SMoriah.Waterland@Sun.COM 
3109781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
3119781SMoriah.Waterland@Sun.COM 
3129781SMoriah.Waterland@Sun.COM 	/* set verbose mode if appropriate environment variable is set */
3139781SMoriah.Waterland@Sun.COM 
3149781SMoriah.Waterland@Sun.COM 	if (getenv(ENV_VAR_VERBOSE)) {
3159781SMoriah.Waterland@Sun.COM 		/* same as -v */
3169781SMoriah.Waterland@Sun.COM 		setVerbose(B_TRUE);
3179781SMoriah.Waterland@Sun.COM 	}
3189781SMoriah.Waterland@Sun.COM 
3199781SMoriah.Waterland@Sun.COM 	/* set debug mode if appropriate environment variable is set */
3209781SMoriah.Waterland@Sun.COM 
3219781SMoriah.Waterland@Sun.COM 	if (getenv(ENV_VAR_DEBUG)) {
3229781SMoriah.Waterland@Sun.COM 		/* same as -O debug */
3239781SMoriah.Waterland@Sun.COM 
3249781SMoriah.Waterland@Sun.COM 		/* set sml tracing (sml.c) */
3259781SMoriah.Waterland@Sun.COM 		smlSetVerbose(B_TRUE);
3269781SMoriah.Waterland@Sun.COM 
3279781SMoriah.Waterland@Sun.COM 		/* set log and echo (interactive) message tracing */
3289781SMoriah.Waterland@Sun.COM 		setVerbose(B_TRUE);
3299781SMoriah.Waterland@Sun.COM 
3309781SMoriah.Waterland@Sun.COM 		/* enable echoDebug debugging messages */
3319781SMoriah.Waterland@Sun.COM 		echoDebugSetFlag(B_TRUE);
3329781SMoriah.Waterland@Sun.COM 	}
3339781SMoriah.Waterland@Sun.COM 
3349781SMoriah.Waterland@Sun.COM 	/* generate usage if no options or arguments specified */
3359781SMoriah.Waterland@Sun.COM 
3369781SMoriah.Waterland@Sun.COM 	if (argc <= 1) {
3379781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_NO_ARGUMENTS_SPECIFIED);
3389781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
3399781SMoriah.Waterland@Sun.COM 	}
3409781SMoriah.Waterland@Sun.COM 
3419781SMoriah.Waterland@Sun.COM 	/*
3429781SMoriah.Waterland@Sun.COM 	 * process any arguments that can appear before the subcommand
3439781SMoriah.Waterland@Sun.COM 	 */
3449781SMoriah.Waterland@Sun.COM 
3459781SMoriah.Waterland@Sun.COM 	while ((i = getopt(argc, argv, ":O:vn?")) != EOF) {
3469781SMoriah.Waterland@Sun.COM 		switch (i) {
3479781SMoriah.Waterland@Sun.COM 		/*
3489781SMoriah.Waterland@Sun.COM 		 * Not a public interface: the -O option allows the behavior
3499781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
3509781SMoriah.Waterland@Sun.COM 		 * -> debug
3519781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
3529781SMoriah.Waterland@Sun.COM 		 */
3539781SMoriah.Waterland@Sun.COM 
3549781SMoriah.Waterland@Sun.COM 		case 'O':
3559781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != NULL;
3569781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
3579781SMoriah.Waterland@Sun.COM 
3589781SMoriah.Waterland@Sun.COM 				/* debug - enable all tracing */
3599781SMoriah.Waterland@Sun.COM 
3609781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
3619781SMoriah.Waterland@Sun.COM 					/* set sml tracing */
3629781SMoriah.Waterland@Sun.COM 					smlSetVerbose(B_TRUE);
3639781SMoriah.Waterland@Sun.COM 					/* set log/echo tracing */
3649781SMoriah.Waterland@Sun.COM 					setVerbose(B_TRUE);
3659781SMoriah.Waterland@Sun.COM 					/* enable debugging messages */
3669781SMoriah.Waterland@Sun.COM 					echoDebugSetFlag(B_TRUE);
3679781SMoriah.Waterland@Sun.COM 					continue;
3689781SMoriah.Waterland@Sun.COM 				}
3699781SMoriah.Waterland@Sun.COM 
3709781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
3719781SMoriah.Waterland@Sun.COM 				return (adjustResults(R_USAGE));
3729781SMoriah.Waterland@Sun.COM 			}
3739781SMoriah.Waterland@Sun.COM 			break;
3749781SMoriah.Waterland@Sun.COM 
3759781SMoriah.Waterland@Sun.COM 		/*
3769781SMoriah.Waterland@Sun.COM 		 * Public interface: enable verbose (debug) output.
3779781SMoriah.Waterland@Sun.COM 		 */
3789781SMoriah.Waterland@Sun.COM 
3799781SMoriah.Waterland@Sun.COM 		case 'v':	/* verbose mode enabled */
3809781SMoriah.Waterland@Sun.COM 			/* set command tracing only */
3819781SMoriah.Waterland@Sun.COM 			setVerbose(B_TRUE);
3829781SMoriah.Waterland@Sun.COM 			break;
3839781SMoriah.Waterland@Sun.COM 
3849781SMoriah.Waterland@Sun.COM 		/*
3859781SMoriah.Waterland@Sun.COM 		 * Public interface: negate output results.
3869781SMoriah.Waterland@Sun.COM 		 */
3879781SMoriah.Waterland@Sun.COM 
3889781SMoriah.Waterland@Sun.COM 		case 'n':
3899781SMoriah.Waterland@Sun.COM 			setNegateResults(B_TRUE);
3909781SMoriah.Waterland@Sun.COM 			break;
3919781SMoriah.Waterland@Sun.COM 
3929781SMoriah.Waterland@Sun.COM 		/*
3939781SMoriah.Waterland@Sun.COM 		 * unrecognized option
3949781SMoriah.Waterland@Sun.COM 		 */
3959781SMoriah.Waterland@Sun.COM 
3969781SMoriah.Waterland@Sun.COM 		case '?':
3979781SMoriah.Waterland@Sun.COM 		default:
3989781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_INVALID_OPTION_SPECIFIED, optopt);
3999781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
4009781SMoriah.Waterland@Sun.COM 		}
4019781SMoriah.Waterland@Sun.COM 	}
4029781SMoriah.Waterland@Sun.COM 
4039781SMoriah.Waterland@Sun.COM 	/*
4049781SMoriah.Waterland@Sun.COM 	 * done processing options that can preceed subcommand
4059781SMoriah.Waterland@Sun.COM 	 */
4069781SMoriah.Waterland@Sun.COM 
4079781SMoriah.Waterland@Sun.COM 	/* error if no subcommand specified */
4089781SMoriah.Waterland@Sun.COM 
4099781SMoriah.Waterland@Sun.COM 	if ((argc-optind) <= 0) {
4109781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_NO_ARGUMENTS_SPECIFIED);
4119781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
4129781SMoriah.Waterland@Sun.COM 	}
4139781SMoriah.Waterland@Sun.COM 
4149781SMoriah.Waterland@Sun.COM 	/* parse global data if environment variable set */
4159781SMoriah.Waterland@Sun.COM 
4169781SMoriah.Waterland@Sun.COM 	if (parseGlobalData(PKGCOND_GLOBAL_VARIABLE, &gdt) != R_SUCCESS) {
4179781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_CANNOT_USE_GLOBAL_DATA,
4189781SMoriah.Waterland@Sun.COM 			PKGCOND_GLOBAL_VARIABLE);
4199781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
4209781SMoriah.Waterland@Sun.COM 	}
4219781SMoriah.Waterland@Sun.COM 
4229781SMoriah.Waterland@Sun.COM 	if (setRootPath(gdt->gd_installRoot,
4239781SMoriah.Waterland@Sun.COM 	    (strcmp(gdt->gd_installRoot, "/") == 0) ? NULL :
4249781SMoriah.Waterland@Sun.COM 	    ENV_VAR_SET, B_TRUE) != R_SUCCESS) {
4259781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_CANNOT_SET_ROOT_PATH,
4269781SMoriah.Waterland@Sun.COM 			ENV_VAR_PKGROOT);
4279781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
4289781SMoriah.Waterland@Sun.COM 	}
4299781SMoriah.Waterland@Sun.COM 
4309781SMoriah.Waterland@Sun.COM 	/* set path provided on the command line */
4319781SMoriah.Waterland@Sun.COM 
4329781SMoriah.Waterland@Sun.COM 	setCmdLinePath(&(gdt->gd_cmdline_path), argv, argc);
4339781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CMDLINE_PATH,
4349781SMoriah.Waterland@Sun.COM 	    gdt->gd_cmdline_path == NULL ? "" : gdt->gd_cmdline_path);
4359781SMoriah.Waterland@Sun.COM 
4369781SMoriah.Waterland@Sun.COM 	/* determine how file systems are layered in this zone */
4379781SMoriah.Waterland@Sun.COM 
4389781SMoriah.Waterland@Sun.COM 	if (calculateFileSystemConfig(gdt) != R_SUCCESS) {
4399781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_CANNOT_CALC_FS_CONFIG);
4409781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
4419781SMoriah.Waterland@Sun.COM 	}
4429781SMoriah.Waterland@Sun.COM 
4439781SMoriah.Waterland@Sun.COM 	/* dump global data read in (only if debugging) */
4449781SMoriah.Waterland@Sun.COM 
4459781SMoriah.Waterland@Sun.COM 	dumpGlobalData(gdt);
4469781SMoriah.Waterland@Sun.COM 
4479781SMoriah.Waterland@Sun.COM 	/* search for specified subcommand and execute if found */
4489781SMoriah.Waterland@Sun.COM 
4499781SMoriah.Waterland@Sun.COM 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
4509781SMoriah.Waterland@Sun.COM 		if (ci_streq(argv[optind], cmds[cur_cmd].c_name)) {
4519781SMoriah.Waterland@Sun.COM 			int	result;
4529781SMoriah.Waterland@Sun.COM 
4539781SMoriah.Waterland@Sun.COM 			/* make subcommand the first option */
4549781SMoriah.Waterland@Sun.COM 
4559781SMoriah.Waterland@Sun.COM 			newargc = argc - optind;
4569781SMoriah.Waterland@Sun.COM 			newargv = argv + optind;
4579781SMoriah.Waterland@Sun.COM 			opterr = optind = 1; optopt = 0;
4589781SMoriah.Waterland@Sun.COM 
4599781SMoriah.Waterland@Sun.COM 
4609781SMoriah.Waterland@Sun.COM 			/* call subcommand with its own argc/argv */
4619781SMoriah.Waterland@Sun.COM 
4629781SMoriah.Waterland@Sun.COM 			result = cmds[cur_cmd].c_func(newargc, newargv, gdt);
4639781SMoriah.Waterland@Sun.COM 
4649781SMoriah.Waterland@Sun.COM 			/* process result code and exit */
4659781SMoriah.Waterland@Sun.COM 
4669781SMoriah.Waterland@Sun.COM 			result = adjustResults(result);
4679781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_RESULTS, result);
4689781SMoriah.Waterland@Sun.COM 			return (result);
4699781SMoriah.Waterland@Sun.COM 		}
4709781SMoriah.Waterland@Sun.COM 	}
4719781SMoriah.Waterland@Sun.COM 
4729781SMoriah.Waterland@Sun.COM 	/* subcommand not found - output error message and exit with error */
4739781SMoriah.Waterland@Sun.COM 
4749781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_ERR, ERR_BAD_SUB, argv[optind]);
4759781SMoriah.Waterland@Sun.COM 	(void) usage(MSG_UNRECOGNIZED_CONDITION_SPECIFIED);
4769781SMoriah.Waterland@Sun.COM 	return (R_USAGE);
4779781SMoriah.Waterland@Sun.COM }
4789781SMoriah.Waterland@Sun.COM 
4799781SMoriah.Waterland@Sun.COM /*
4809781SMoriah.Waterland@Sun.COM  * *****************************************************************************
4819781SMoriah.Waterland@Sun.COM  * command implementation functions
4829781SMoriah.Waterland@Sun.COM  * *****************************************************************************
4839781SMoriah.Waterland@Sun.COM  */
4849781SMoriah.Waterland@Sun.COM 
4859781SMoriah.Waterland@Sun.COM /*
4869781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_diskless_client
4879781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a diskless client
4889781SMoriah.Waterland@Sun.COM  * Scope:	public
4899781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
4909781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
4919781SMoriah.Waterland@Sun.COM  * Returns:	int
4929781SMoriah.Waterland@Sun.COM  *			== 0 - success
4939781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
4949781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
4959781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
4969781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
4979781SMoriah.Waterland@Sun.COM  *  - must not be a whole root non-global zone
4989781SMoriah.Waterland@Sun.COM  *  - must not be a non-global zone
4999781SMoriah.Waterland@Sun.COM  *  - must not be a mounted mini-root
5009781SMoriah.Waterland@Sun.COM  *  - must not be a netinstall image
5019781SMoriah.Waterland@Sun.COM  *  - must not be a boot environment
5029781SMoriah.Waterland@Sun.COM  *  - The package "SUNWdclnt" must be installed at "/"
5039781SMoriah.Waterland@Sun.COM  *  - The root path must not be "/"
5049781SMoriah.Waterland@Sun.COM  *  - The path "/export/exec/Solaris_\*\/usr" must exist at "/"
5059781SMoriah.Waterland@Sun.COM  *  - The directory "$ROOTDIR/../templates" must exist
5069781SMoriah.Waterland@Sun.COM  */
5079781SMoriah.Waterland@Sun.COM 
5089781SMoriah.Waterland@Sun.COM static int
cmd_is_diskless_client(int argc,char ** argv,GLOBALDATA_T * a_gdt)5099781SMoriah.Waterland@Sun.COM cmd_is_diskless_client(int argc, char **argv, GLOBALDATA_T *a_gdt)
5109781SMoriah.Waterland@Sun.COM {
5119781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
5129781SMoriah.Waterland@Sun.COM 	char	cmd[MAXPATHLEN+1];
5139781SMoriah.Waterland@Sun.COM 	int	c;
5149781SMoriah.Waterland@Sun.COM 	int	r;
5159781SMoriah.Waterland@Sun.COM 	int	rc;
5169781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_diskless_client";
5179781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
5189781SMoriah.Waterland@Sun.COM 
5199781SMoriah.Waterland@Sun.COM 	/* process any command line options */
5209781SMoriah.Waterland@Sun.COM 
5219781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
5229781SMoriah.Waterland@Sun.COM 		switch (c) {
5239781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
5249781SMoriah.Waterland@Sun.COM 			break;
5259781SMoriah.Waterland@Sun.COM 		case '?':
5269781SMoriah.Waterland@Sun.COM 		default:
5279781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
5289781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
5299781SMoriah.Waterland@Sun.COM 		}
5309781SMoriah.Waterland@Sun.COM 	}
5319781SMoriah.Waterland@Sun.COM 
5329781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
5339781SMoriah.Waterland@Sun.COM 
5349781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
5359781SMoriah.Waterland@Sun.COM 
5369781SMoriah.Waterland@Sun.COM 		/*
5379781SMoriah.Waterland@Sun.COM 		 * a diskless client cannot be any of the following
5389781SMoriah.Waterland@Sun.COM 		 */
5399781SMoriah.Waterland@Sun.COM 
540*12734Sgary.pennington@oracle.com 		/* cannot be non-global zone */
541*12734Sgary.pennington@oracle.com 
542*12734Sgary.pennington@oracle.com 		r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
5439781SMoriah.Waterland@Sun.COM 
5449781SMoriah.Waterland@Sun.COM 		/* cannot be mounted miniroot */
5459781SMoriah.Waterland@Sun.COM 
5469781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
5479781SMoriah.Waterland@Sun.COM 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
5489781SMoriah.Waterland@Sun.COM 		}
5499781SMoriah.Waterland@Sun.COM 
5509781SMoriah.Waterland@Sun.COM 		/* cannot be a netinstall image */
5519781SMoriah.Waterland@Sun.COM 
5529781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
5539781SMoriah.Waterland@Sun.COM 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
5549781SMoriah.Waterland@Sun.COM 		}
5559781SMoriah.Waterland@Sun.COM 
5569781SMoriah.Waterland@Sun.COM 		/* cannot be a boot environment */
5579781SMoriah.Waterland@Sun.COM 
5589781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
5599781SMoriah.Waterland@Sun.COM 			r = cmd_is_boot_environment(argc, argv, a_gdt);
5609781SMoriah.Waterland@Sun.COM 		}
5619781SMoriah.Waterland@Sun.COM 
5629781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
5639781SMoriah.Waterland@Sun.COM 
5649781SMoriah.Waterland@Sun.COM 		recursion--;
5659781SMoriah.Waterland@Sun.COM 
5669781SMoriah.Waterland@Sun.COM 		/* return failure if any of the preceeding are true */
5679781SMoriah.Waterland@Sun.COM 
5689781SMoriah.Waterland@Sun.COM 		switch (r) {
5699781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
5709781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
5719781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
5729781SMoriah.Waterland@Sun.COM 				break;
5739781SMoriah.Waterland@Sun.COM 			case R_USAGE:
5749781SMoriah.Waterland@Sun.COM 			case R_ERROR:
5759781SMoriah.Waterland@Sun.COM 			default:
5769781SMoriah.Waterland@Sun.COM 				return (r);
5779781SMoriah.Waterland@Sun.COM 		}
5789781SMoriah.Waterland@Sun.COM 	}
5799781SMoriah.Waterland@Sun.COM 
5809781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
5819781SMoriah.Waterland@Sun.COM 
5829781SMoriah.Waterland@Sun.COM 	argc -= optind;
5839781SMoriah.Waterland@Sun.COM 	argv += optind;
5849781SMoriah.Waterland@Sun.COM 
5859781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
5869781SMoriah.Waterland@Sun.COM 
5879781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
5889781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
5899781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
5909781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
5919781SMoriah.Waterland@Sun.COM 	}
5929781SMoriah.Waterland@Sun.COM 
5939781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
5949781SMoriah.Waterland@Sun.COM 
5959781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
5969781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
5979781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
5989781SMoriah.Waterland@Sun.COM 		}
5999781SMoriah.Waterland@Sun.COM 	}
6009781SMoriah.Waterland@Sun.COM 
6019781SMoriah.Waterland@Sun.COM 	/* get current root path */
6029781SMoriah.Waterland@Sun.COM 
6039781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
6049781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
6059781SMoriah.Waterland@Sun.COM 		return (r);
6069781SMoriah.Waterland@Sun.COM 	}
6079781SMoriah.Waterland@Sun.COM 
6089781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
6099781SMoriah.Waterland@Sun.COM 
6109781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
6119781SMoriah.Waterland@Sun.COM 
6129781SMoriah.Waterland@Sun.COM 	/* SUNWdclnt must be installed */
6139781SMoriah.Waterland@Sun.COM 
6149781SMoriah.Waterland@Sun.COM 	if (pkgTestInstalled("SUNWdclnt", "/") != B_TRUE) {
6159781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_PKG_NOT_INSTALLED,
6169781SMoriah.Waterland@Sun.COM 			rootPath, "SUNWdclnt", "/");
6179781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6189781SMoriah.Waterland@Sun.COM 	}
6199781SMoriah.Waterland@Sun.COM 
6209781SMoriah.Waterland@Sun.COM 	/*   - $ROOTDIR must not be "/" */
6219781SMoriah.Waterland@Sun.COM 
6229781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") == 0) {
6239781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ROOTPATH_BAD, rootPath, "/");
6249781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6259781SMoriah.Waterland@Sun.COM 	}
6269781SMoriah.Waterland@Sun.COM 
6279781SMoriah.Waterland@Sun.COM 	/*   - zone name must be global */
6289781SMoriah.Waterland@Sun.COM 
6299781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
6309781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_BAD, rootPath,
6319781SMoriah.Waterland@Sun.COM 			GLOBAL_ZONENAME);
6329781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6339781SMoriah.Waterland@Sun.COM 	}
6349781SMoriah.Waterland@Sun.COM 
6359781SMoriah.Waterland@Sun.COM 	/*
6369781SMoriah.Waterland@Sun.COM 	 * /export/exec/Solaris_"*"/usr must exist;
6379781SMoriah.Waterland@Sun.COM 	 * create ls command to test:
6389781SMoriah.Waterland@Sun.COM 	 * /usr/bin/ls /export/exec/Solaris_"*"/usr
6399781SMoriah.Waterland@Sun.COM 	 */
6409781SMoriah.Waterland@Sun.COM 
6419781SMoriah.Waterland@Sun.COM 	(void) snprintf(cmd, sizeof (cmd), "%s %s >/dev/null 2>&1",
6429781SMoriah.Waterland@Sun.COM 		LS_CMD, "/export/exec/Solaris_*/usr");
6439781SMoriah.Waterland@Sun.COM 
6449781SMoriah.Waterland@Sun.COM 	/* execute command */
6459781SMoriah.Waterland@Sun.COM 
6469781SMoriah.Waterland@Sun.COM 	rc = system(cmd);
6479781SMoriah.Waterland@Sun.COM 
6489781SMoriah.Waterland@Sun.COM 	/* return error if ls returns something other than "0" */
6499781SMoriah.Waterland@Sun.COM 
6509781SMoriah.Waterland@Sun.COM 	if (rc != 0) {
6519781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_MISSING,
6529781SMoriah.Waterland@Sun.COM 			rootPath, "/export/exec/Solaris_*/usr");
6539781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6549781SMoriah.Waterland@Sun.COM 	}
6559781SMoriah.Waterland@Sun.COM 
6569781SMoriah.Waterland@Sun.COM 	/*
6579781SMoriah.Waterland@Sun.COM 	 * /usr must be empty on a diskless client:
6589781SMoriah.Waterland@Sun.COM 	 * create ls command to test:
6599781SMoriah.Waterland@Sun.COM 	 * /usr/bin/ls -d1 $ROOTDIR/usr/\*
6609781SMoriah.Waterland@Sun.COM 	 */
6619781SMoriah.Waterland@Sun.COM 	(void) snprintf(cmd, sizeof (cmd), "%s %s %s/%s >/dev/null 2>&1",
6629781SMoriah.Waterland@Sun.COM 		LS_CMD, "-1d", rootPath, "usr/*");
6639781SMoriah.Waterland@Sun.COM 
6649781SMoriah.Waterland@Sun.COM 	/* execute command */
6659781SMoriah.Waterland@Sun.COM 
6669781SMoriah.Waterland@Sun.COM 	rc = system(cmd);
6679781SMoriah.Waterland@Sun.COM 
6689781SMoriah.Waterland@Sun.COM 	/* return error if ls returns "0" */
6699781SMoriah.Waterland@Sun.COM 
6709781SMoriah.Waterland@Sun.COM 	if (rc == 0) {
6719781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_USR_IS_NOT_EMPTY,
6729781SMoriah.Waterland@Sun.COM 			rootPath);
6739781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6749781SMoriah.Waterland@Sun.COM 	}
6759781SMoriah.Waterland@Sun.COM 
6769781SMoriah.Waterland@Sun.COM 	/* there must be a templates directory at ${ROOTPATH}/../templates */
6779781SMoriah.Waterland@Sun.COM 
6789781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
6799781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "../templates");
6809781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
6819781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_NO_TEMPLATES_PATH,
6829781SMoriah.Waterland@Sun.COM 			rootPath, rootPath, "../templates");
6839781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6849781SMoriah.Waterland@Sun.COM 	}
6859781SMoriah.Waterland@Sun.COM 
6869781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
6879781SMoriah.Waterland@Sun.COM 
6889781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
6899781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
6909781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be diskless client */
6919781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_INITIAL_INSTALL, rootPath);
6929781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
6939781SMoriah.Waterland@Sun.COM 	}
6949781SMoriah.Waterland@Sun.COM 
6959781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
6969781SMoriah.Waterland@Sun.COM 
6979781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
6989781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
6999781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be diskless client */
7009781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_INSTALL, rootPath);
7019781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
7029781SMoriah.Waterland@Sun.COM 	}
7039781SMoriah.Waterland@Sun.COM 
7049781SMoriah.Waterland@Sun.COM 	/* the path is a diskless client */
7059781SMoriah.Waterland@Sun.COM 
7069781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_IS_DISKLESS_CLIENT, rootPath);
7079781SMoriah.Waterland@Sun.COM 
7089781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
7099781SMoriah.Waterland@Sun.COM }
7109781SMoriah.Waterland@Sun.COM 
7119781SMoriah.Waterland@Sun.COM /*
7129781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_global_zone
7139781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
7149781SMoriah.Waterland@Sun.COM  * Scope:	public
7159781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
7169781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
7179781SMoriah.Waterland@Sun.COM  * Returns:	int
7189781SMoriah.Waterland@Sun.COM  *			== 0 - success
7199781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
7209781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
7219781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
7229781SMoriah.Waterland@Sun.COM  *  - must not be installation of a non-global zone
7239781SMoriah.Waterland@Sun.COM  *  - must not be a non-global zone
7249781SMoriah.Waterland@Sun.COM  *  - must not be a mounted mini-root
7259781SMoriah.Waterland@Sun.COM  *  - must not be a netinstall image
7269781SMoriah.Waterland@Sun.COM  *  - must not be a diskless client
7279781SMoriah.Waterland@Sun.COM  *  - if $ROOTDIR is "/":
7289781SMoriah.Waterland@Sun.COM  *  -- if zone name is "GLOBAL", then is a global zone;
7299781SMoriah.Waterland@Sun.COM  *  -- else not a global zone.
7309781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/etc/zones must exist and be a directory
7319781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/.tmp_proto must not exist
7329781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/var must exist and must not be a symbolic link
7339781SMoriah.Waterland@Sun.COM  */
7349781SMoriah.Waterland@Sun.COM 
7359781SMoriah.Waterland@Sun.COM static int
cmd_is_global_zone(int argc,char ** argv,GLOBALDATA_T * a_gdt)7369781SMoriah.Waterland@Sun.COM cmd_is_global_zone(int argc, char **argv, GLOBALDATA_T *a_gdt)
7379781SMoriah.Waterland@Sun.COM {
7389781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
7399781SMoriah.Waterland@Sun.COM 	int	c;
7409781SMoriah.Waterland@Sun.COM 	int	r;
7419781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_global_zone";
7429781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
7439781SMoriah.Waterland@Sun.COM 
7449781SMoriah.Waterland@Sun.COM 	/* process any command line options */
7459781SMoriah.Waterland@Sun.COM 
7469781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
7479781SMoriah.Waterland@Sun.COM 		switch (c) {
7489781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
7499781SMoriah.Waterland@Sun.COM 			break;
7509781SMoriah.Waterland@Sun.COM 		case '?':
7519781SMoriah.Waterland@Sun.COM 		default:
7529781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
7539781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
7549781SMoriah.Waterland@Sun.COM 		}
7559781SMoriah.Waterland@Sun.COM 	}
7569781SMoriah.Waterland@Sun.COM 
7579781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
7589781SMoriah.Waterland@Sun.COM 
7599781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
7609781SMoriah.Waterland@Sun.COM 
7619781SMoriah.Waterland@Sun.COM 		/*
7629781SMoriah.Waterland@Sun.COM 		 * a global zone cannot be any of the following
7639781SMoriah.Waterland@Sun.COM 		 */
7649781SMoriah.Waterland@Sun.COM 
7659781SMoriah.Waterland@Sun.COM 		/* cannot be a non-global zone */
7669781SMoriah.Waterland@Sun.COM 
7679781SMoriah.Waterland@Sun.COM 		r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
7689781SMoriah.Waterland@Sun.COM 
7699781SMoriah.Waterland@Sun.COM 		/* cannot be a mounted miniroot */
7709781SMoriah.Waterland@Sun.COM 
7719781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
7729781SMoriah.Waterland@Sun.COM 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
7739781SMoriah.Waterland@Sun.COM 		}
7749781SMoriah.Waterland@Sun.COM 
7759781SMoriah.Waterland@Sun.COM 		/* cannot be a netinstall image */
7769781SMoriah.Waterland@Sun.COM 
7779781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
7789781SMoriah.Waterland@Sun.COM 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
7799781SMoriah.Waterland@Sun.COM 		}
7809781SMoriah.Waterland@Sun.COM 
7819781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless client */
7829781SMoriah.Waterland@Sun.COM 
7839781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
7849781SMoriah.Waterland@Sun.COM 			r = cmd_is_diskless_client(argc, argv, a_gdt);
7859781SMoriah.Waterland@Sun.COM 		}
7869781SMoriah.Waterland@Sun.COM 
7879781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
7889781SMoriah.Waterland@Sun.COM 
7899781SMoriah.Waterland@Sun.COM 		recursion--;
7909781SMoriah.Waterland@Sun.COM 
7919781SMoriah.Waterland@Sun.COM 		/* return failure if any of the preceeding are true */
7929781SMoriah.Waterland@Sun.COM 
7939781SMoriah.Waterland@Sun.COM 		switch (r) {
7949781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
7959781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
7969781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
7979781SMoriah.Waterland@Sun.COM 				break;
7989781SMoriah.Waterland@Sun.COM 			case R_USAGE:
7999781SMoriah.Waterland@Sun.COM 			case R_ERROR:
8009781SMoriah.Waterland@Sun.COM 			default:
8019781SMoriah.Waterland@Sun.COM 				return (r);
8029781SMoriah.Waterland@Sun.COM 		}
8039781SMoriah.Waterland@Sun.COM 	}
8049781SMoriah.Waterland@Sun.COM 
8059781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
8069781SMoriah.Waterland@Sun.COM 
8079781SMoriah.Waterland@Sun.COM 	argc -= optind;
8089781SMoriah.Waterland@Sun.COM 	argv += optind;
8099781SMoriah.Waterland@Sun.COM 
8109781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
8119781SMoriah.Waterland@Sun.COM 
8129781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
8139781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
8149781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
8159781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
8169781SMoriah.Waterland@Sun.COM 	}
8179781SMoriah.Waterland@Sun.COM 
8189781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
8199781SMoriah.Waterland@Sun.COM 
8209781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
8219781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
8229781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
8239781SMoriah.Waterland@Sun.COM 		}
8249781SMoriah.Waterland@Sun.COM 	}
8259781SMoriah.Waterland@Sun.COM 
8269781SMoriah.Waterland@Sun.COM 	/* get current root path */
8279781SMoriah.Waterland@Sun.COM 
8289781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
8299781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
8309781SMoriah.Waterland@Sun.COM 		return (r);
8319781SMoriah.Waterland@Sun.COM 	}
8329781SMoriah.Waterland@Sun.COM 
8339781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
8349781SMoriah.Waterland@Sun.COM 
8359781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
8369781SMoriah.Waterland@Sun.COM 
8379781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
8389781SMoriah.Waterland@Sun.COM 
8399781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
8409781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
8419781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be global zone */
8429781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_INITIAL_INSTALL, rootPath);
8439781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
8449781SMoriah.Waterland@Sun.COM 	}
8459781SMoriah.Waterland@Sun.COM 
8469781SMoriah.Waterland@Sun.COM 	/* must not be installation of a non-global zone */
8479781SMoriah.Waterland@Sun.COM 
8489781SMoriah.Waterland@Sun.COM 	if (a_gdt->gd_nonglobalZoneInstall == B_TRUE) {
8499781SMoriah.Waterland@Sun.COM 		/* initial nonglobal zone install: no path can be global zone */
8509781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_NGZ_ZONE_INSTALL, rootPath);
8519781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
8529781SMoriah.Waterland@Sun.COM 	}
8539781SMoriah.Waterland@Sun.COM 
8549781SMoriah.Waterland@Sun.COM 	/* handle if global zone installation to the install root */
8559781SMoriah.Waterland@Sun.COM 
8569781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) &&
8579781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
8589781SMoriah.Waterland@Sun.COM 			/* the path is a global zone */
8599781SMoriah.Waterland@Sun.COM 
8609781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE,
8619781SMoriah.Waterland@Sun.COM 				rootPath);
8629781SMoriah.Waterland@Sun.COM 
8639781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
8649781SMoriah.Waterland@Sun.COM 	}
8659781SMoriah.Waterland@Sun.COM 
8669781SMoriah.Waterland@Sun.COM 	/* true if current root is "/" and zone name is GLOBAL_ZONENAME */
8679781SMoriah.Waterland@Sun.COM 
8689781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") == 0) {
8699781SMoriah.Waterland@Sun.COM 		if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
8709781SMoriah.Waterland@Sun.COM 			/* the path is a global zone */
8719781SMoriah.Waterland@Sun.COM 
8729781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE,
8739781SMoriah.Waterland@Sun.COM 				rootPath);
8749781SMoriah.Waterland@Sun.COM 
8759781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
8769781SMoriah.Waterland@Sun.COM 		}
8779781SMoriah.Waterland@Sun.COM 
8789781SMoriah.Waterland@Sun.COM 		/* inside a non-global zone */
8799781SMoriah.Waterland@Sun.COM 
8809781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_ZONENAME_ISNT_GLOBAL,
8819781SMoriah.Waterland@Sun.COM 			rootPath, a_gdt->gd_zoneName);
8829781SMoriah.Waterland@Sun.COM 
8839781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
8849781SMoriah.Waterland@Sun.COM 	}
8859781SMoriah.Waterland@Sun.COM 
8869781SMoriah.Waterland@Sun.COM 	/*
8879781SMoriah.Waterland@Sun.COM 	 * current root is not "/" - see if target looks like a global zone
8889781SMoriah.Waterland@Sun.COM 	 *
8899781SMoriah.Waterland@Sun.COM 	 * - rootpath is not "/"
8909781SMoriah.Waterland@Sun.COM 	 * - and $ROOTDIR/etc/zones exists
8919781SMoriah.Waterland@Sun.COM 	 * - and $ROOTDIR/.tmp_proto does not exist
8929781SMoriah.Waterland@Sun.COM 	 * - and $ROOTDIR/var is not a symbolic link
8939781SMoriah.Waterland@Sun.COM 	 */
8949781SMoriah.Waterland@Sun.COM 
8959781SMoriah.Waterland@Sun.COM 	/* not global zone if /etc/zones does not exist */
8969781SMoriah.Waterland@Sun.COM 
8979781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
8989781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/etc/zones");
8999781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
9009781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_ISNT_DIRECTORY,
9019781SMoriah.Waterland@Sun.COM 			rootPath, "/etc/zones");
9029781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
9039781SMoriah.Waterland@Sun.COM 	}
9049781SMoriah.Waterland@Sun.COM 
9059781SMoriah.Waterland@Sun.COM 	/* .tmp_proto must not exist */
9069781SMoriah.Waterland@Sun.COM 
9079781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_NOT_EXISTS,
9089781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, ".tmp_proto");
9099781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
9109781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_EXISTS,
9119781SMoriah.Waterland@Sun.COM 			rootPath, "/.tmp_proto");
9129781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
9139781SMoriah.Waterland@Sun.COM 	}
9149781SMoriah.Waterland@Sun.COM 
9159781SMoriah.Waterland@Sun.COM 	/* /var must not be a symbolic link */
9169781SMoriah.Waterland@Sun.COM 
9179781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
9189781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/var");
9199781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
9209781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_SYMLINK,
9219781SMoriah.Waterland@Sun.COM 			rootPath, "/var");
9229781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
9239781SMoriah.Waterland@Sun.COM 	}
9249781SMoriah.Waterland@Sun.COM 
9259781SMoriah.Waterland@Sun.COM 	/* the path is a global zone */
9269781SMoriah.Waterland@Sun.COM 
9279781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, rootPath);
9289781SMoriah.Waterland@Sun.COM 
9299781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
9309781SMoriah.Waterland@Sun.COM }
9319781SMoriah.Waterland@Sun.COM 
9329781SMoriah.Waterland@Sun.COM /*
9339781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_netinstall_image
9349781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a net install image
9359781SMoriah.Waterland@Sun.COM  * Scope:	public
9369781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
9379781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
9389781SMoriah.Waterland@Sun.COM  * Returns:	int
9399781SMoriah.Waterland@Sun.COM  *			== 0 - success
9409781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
9419781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
9429781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
9439781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
9449781SMoriah.Waterland@Sun.COM  *  - must not be a global zone
9459781SMoriah.Waterland@Sun.COM  *  - must not be a mounted mini-root
9469781SMoriah.Waterland@Sun.COM  *  - zone name must be "global"
9479781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/.tmp_proto must exist and must be a directory
9489781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/var must exist and must be a symbolic link
9499781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/tmp/kernel must exist and must be a directory
9509781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/.tmp_proto/kernel must exist and must be a symbolic link
9519781SMoriah.Waterland@Sun.COM  */
9529781SMoriah.Waterland@Sun.COM 
9539781SMoriah.Waterland@Sun.COM static int
cmd_is_netinstall_image(int argc,char ** argv,GLOBALDATA_T * a_gdt)9549781SMoriah.Waterland@Sun.COM cmd_is_netinstall_image(int argc, char **argv, GLOBALDATA_T *a_gdt)
9559781SMoriah.Waterland@Sun.COM {
9569781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
9579781SMoriah.Waterland@Sun.COM 	int	c;
9589781SMoriah.Waterland@Sun.COM 	int	r;
9599781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_netinstall_image";
9609781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
9619781SMoriah.Waterland@Sun.COM 
9629781SMoriah.Waterland@Sun.COM 	/* process any command line options */
9639781SMoriah.Waterland@Sun.COM 
9649781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
9659781SMoriah.Waterland@Sun.COM 		switch (c) {
9669781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
9679781SMoriah.Waterland@Sun.COM 			break;
9689781SMoriah.Waterland@Sun.COM 		case '?':
9699781SMoriah.Waterland@Sun.COM 		default:
9709781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
9719781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
9729781SMoriah.Waterland@Sun.COM 		}
9739781SMoriah.Waterland@Sun.COM 	}
9749781SMoriah.Waterland@Sun.COM 
9759781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
9769781SMoriah.Waterland@Sun.COM 
9779781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
9789781SMoriah.Waterland@Sun.COM 
9799781SMoriah.Waterland@Sun.COM 		/* a netinstall image cannot be a global zone */
9809781SMoriah.Waterland@Sun.COM 
9819781SMoriah.Waterland@Sun.COM 		r = cmd_is_global_zone(argc, argv, a_gdt);
9829781SMoriah.Waterland@Sun.COM 
9839781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
9849781SMoriah.Waterland@Sun.COM 
9859781SMoriah.Waterland@Sun.COM 		recursion--;
9869781SMoriah.Waterland@Sun.COM 
9879781SMoriah.Waterland@Sun.COM 		switch (r) {
9889781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
9899781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
9909781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
9919781SMoriah.Waterland@Sun.COM 				break;
9929781SMoriah.Waterland@Sun.COM 			case R_USAGE:
9939781SMoriah.Waterland@Sun.COM 			case R_ERROR:
9949781SMoriah.Waterland@Sun.COM 			default:
9959781SMoriah.Waterland@Sun.COM 				return (r);
9969781SMoriah.Waterland@Sun.COM 		}
9979781SMoriah.Waterland@Sun.COM 	}
9989781SMoriah.Waterland@Sun.COM 
9999781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
10009781SMoriah.Waterland@Sun.COM 
10019781SMoriah.Waterland@Sun.COM 	argc -= optind;
10029781SMoriah.Waterland@Sun.COM 	argv += optind;
10039781SMoriah.Waterland@Sun.COM 
10049781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
10059781SMoriah.Waterland@Sun.COM 
10069781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
10079781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
10089781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
10099781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
10109781SMoriah.Waterland@Sun.COM 	}
10119781SMoriah.Waterland@Sun.COM 
10129781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
10139781SMoriah.Waterland@Sun.COM 
10149781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
10159781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
10169781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
10179781SMoriah.Waterland@Sun.COM 		}
10189781SMoriah.Waterland@Sun.COM 	}
10199781SMoriah.Waterland@Sun.COM 
10209781SMoriah.Waterland@Sun.COM 	/* get current root path */
10219781SMoriah.Waterland@Sun.COM 
10229781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
10239781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
10249781SMoriah.Waterland@Sun.COM 		return (r);
10259781SMoriah.Waterland@Sun.COM 	}
10269781SMoriah.Waterland@Sun.COM 
10279781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
10289781SMoriah.Waterland@Sun.COM 
10299781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
10309781SMoriah.Waterland@Sun.COM 
10319781SMoriah.Waterland@Sun.COM 	/* current zone name must be "global" */
10329781SMoriah.Waterland@Sun.COM 
10339781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
10349781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_BAD_CURRENT_ZONE,
10359781SMoriah.Waterland@Sun.COM 			rootPath, GLOBAL_ZONENAME);
10369781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10379781SMoriah.Waterland@Sun.COM 	}
10389781SMoriah.Waterland@Sun.COM 
10399781SMoriah.Waterland@Sun.COM 	/* cannot be a mounted_miniroot */
10409781SMoriah.Waterland@Sun.COM 
10419781SMoriah.Waterland@Sun.COM 	if (cmd_is_mounted_miniroot(argc, argv, a_gdt) == R_SUCCESS) {
10429781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT,
10439781SMoriah.Waterland@Sun.COM 			rootPath);
10449781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10459781SMoriah.Waterland@Sun.COM 	}
10469781SMoriah.Waterland@Sun.COM 
10479781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/.tmp_proto exists */
10489781SMoriah.Waterland@Sun.COM 
10499781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
10509781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, ".tmp_proto");
10519781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
10529781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY,
10539781SMoriah.Waterland@Sun.COM 			rootPath, "/.tmp_proto");
10549781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10559781SMoriah.Waterland@Sun.COM 	}
10569781SMoriah.Waterland@Sun.COM 
10579781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/var is a symbolic link */
10589781SMoriah.Waterland@Sun.COM 
10599781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_IS_SYMBOLIC_LINK,
10609781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/var");
10619781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
10629781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK,
10639781SMoriah.Waterland@Sun.COM 			rootPath, "/var");
10649781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10659781SMoriah.Waterland@Sun.COM 	}
10669781SMoriah.Waterland@Sun.COM 
10679781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/tmp/kernel does exist */
10689781SMoriah.Waterland@Sun.COM 
10699781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
10709781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/tmp/kernel");
10719781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
10729781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY,
10739781SMoriah.Waterland@Sun.COM 			rootPath, "/tmp/kernel");
10749781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10759781SMoriah.Waterland@Sun.COM 	}
10769781SMoriah.Waterland@Sun.COM 
10779781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/.tmp_proto/kernel is a symbolic link */
10789781SMoriah.Waterland@Sun.COM 
10799781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_IS_SYMBOLIC_LINK,
10809781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/.tmp_proto/kernel");
10819781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
10829781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK,
10839781SMoriah.Waterland@Sun.COM 			rootPath, "/.tmp_proto/kernel");
10849781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10859781SMoriah.Waterland@Sun.COM 	}
10869781SMoriah.Waterland@Sun.COM 
10879781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
10889781SMoriah.Waterland@Sun.COM 
10899781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
10909781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
10919781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be netinstall image */
10929781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_INITIAL_INSTALL, rootPath);
10939781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
10949781SMoriah.Waterland@Sun.COM 	}
10959781SMoriah.Waterland@Sun.COM 
10969781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
10979781SMoriah.Waterland@Sun.COM 
10989781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
10999781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
11009781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be netinstall image */
11019781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_INIM_ZONE_INSTALL, rootPath);
11029781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
11039781SMoriah.Waterland@Sun.COM 	}
11049781SMoriah.Waterland@Sun.COM 
11059781SMoriah.Waterland@Sun.COM 	/* target is a netinstall image */
11069781SMoriah.Waterland@Sun.COM 
11079781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_IS_NETINSTALL_IMAGE, rootPath);
11089781SMoriah.Waterland@Sun.COM 
11099781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
11109781SMoriah.Waterland@Sun.COM }
11119781SMoriah.Waterland@Sun.COM 
11129781SMoriah.Waterland@Sun.COM /*
11139781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_mounted_miniroot
11149781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a mounted miniroot image
11159781SMoriah.Waterland@Sun.COM  * Scope:	public
11169781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
11179781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
11189781SMoriah.Waterland@Sun.COM  * Returns:	int
11199781SMoriah.Waterland@Sun.COM  *			== 0 - success
11209781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
11219781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
11229781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
11239781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
11249781SMoriah.Waterland@Sun.COM  *  - zone name must be "global"
11259781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/tmp/kernel must exist and must be a symbolic link
11269781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/tmp/root/kernel must exist and must be a directory
11279781SMoriah.Waterland@Sun.COM  */
11289781SMoriah.Waterland@Sun.COM 
11299781SMoriah.Waterland@Sun.COM static int
cmd_is_mounted_miniroot(int argc,char ** argv,GLOBALDATA_T * a_gdt)11309781SMoriah.Waterland@Sun.COM cmd_is_mounted_miniroot(int argc, char **argv, GLOBALDATA_T *a_gdt)
11319781SMoriah.Waterland@Sun.COM {
11329781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
11339781SMoriah.Waterland@Sun.COM 	int	c;
11349781SMoriah.Waterland@Sun.COM 	int	r;
11359781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_mounted_miniroot";
11369781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
11379781SMoriah.Waterland@Sun.COM 
11389781SMoriah.Waterland@Sun.COM 	/* process any command line options */
11399781SMoriah.Waterland@Sun.COM 
11409781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
11419781SMoriah.Waterland@Sun.COM 		switch (c) {
11429781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
11439781SMoriah.Waterland@Sun.COM 			break;
11449781SMoriah.Waterland@Sun.COM 		case '?':
11459781SMoriah.Waterland@Sun.COM 		default:
11469781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
11479781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
11489781SMoriah.Waterland@Sun.COM 		}
11499781SMoriah.Waterland@Sun.COM 	}
11509781SMoriah.Waterland@Sun.COM 
11519781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
11529781SMoriah.Waterland@Sun.COM 
11539781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
11549781SMoriah.Waterland@Sun.COM 		recursion--;
11559781SMoriah.Waterland@Sun.COM 	}
11569781SMoriah.Waterland@Sun.COM 
11579781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
11589781SMoriah.Waterland@Sun.COM 
11599781SMoriah.Waterland@Sun.COM 	argc -= optind;
11609781SMoriah.Waterland@Sun.COM 	argv += optind;
11619781SMoriah.Waterland@Sun.COM 
11629781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
11639781SMoriah.Waterland@Sun.COM 
11649781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
11659781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
11669781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
11679781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
11689781SMoriah.Waterland@Sun.COM 	}
11699781SMoriah.Waterland@Sun.COM 
11709781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
11719781SMoriah.Waterland@Sun.COM 
11729781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
11739781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
11749781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
11759781SMoriah.Waterland@Sun.COM 		}
11769781SMoriah.Waterland@Sun.COM 	}
11779781SMoriah.Waterland@Sun.COM 
11789781SMoriah.Waterland@Sun.COM 	/* get current root path */
11799781SMoriah.Waterland@Sun.COM 
11809781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
11819781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
11829781SMoriah.Waterland@Sun.COM 		return (r);
11839781SMoriah.Waterland@Sun.COM 	}
11849781SMoriah.Waterland@Sun.COM 
11859781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
11869781SMoriah.Waterland@Sun.COM 
11879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
11889781SMoriah.Waterland@Sun.COM 
11899781SMoriah.Waterland@Sun.COM 	/* current zone name must be "global" */
11909781SMoriah.Waterland@Sun.COM 
11919781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
11929781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_BAD_CURRENT_ZONE,
11939781SMoriah.Waterland@Sun.COM 			rootPath, GLOBAL_ZONENAME);
11949781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
11959781SMoriah.Waterland@Sun.COM 	}
11969781SMoriah.Waterland@Sun.COM 
11979781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/tmp/kernel is a symbolic link */
11989781SMoriah.Waterland@Sun.COM 
11999781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_IS_SYMBOLIC_LINK,
12009781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/tmp/kernel");
12019781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
12029781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_SYMLINK,
12039781SMoriah.Waterland@Sun.COM 			rootPath, "/tmp/kernel");
12049781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
12059781SMoriah.Waterland@Sun.COM 	}
12069781SMoriah.Waterland@Sun.COM 
12079781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/tmp/root/kernel is a directory */
12089781SMoriah.Waterland@Sun.COM 
12099781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
12109781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/tmp/root/kernel");
12119781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
12129781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_DIRECTORY,
12139781SMoriah.Waterland@Sun.COM 			rootPath, "/tmp/root/kernel");
12149781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
12159781SMoriah.Waterland@Sun.COM 	}
12169781SMoriah.Waterland@Sun.COM 
12179781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
12189781SMoriah.Waterland@Sun.COM 
12199781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
12209781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
12219781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be mounted miniroot */
12229781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_INITIAL_INSTALL, rootPath);
12239781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
12249781SMoriah.Waterland@Sun.COM 	}
12259781SMoriah.Waterland@Sun.COM 
12269781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
12279781SMoriah.Waterland@Sun.COM 
12289781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
12299781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
12309781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be mounted miniroot */
12319781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IMRT_ZONE_INSTALL, rootPath);
12329781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
12339781SMoriah.Waterland@Sun.COM 	}
12349781SMoriah.Waterland@Sun.COM 
12359781SMoriah.Waterland@Sun.COM 	/* target is a mounted miniroot */
12369781SMoriah.Waterland@Sun.COM 
12379781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT, rootPath);
12389781SMoriah.Waterland@Sun.COM 
12399781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
12409781SMoriah.Waterland@Sun.COM }
12419781SMoriah.Waterland@Sun.COM 
12429781SMoriah.Waterland@Sun.COM /*
12439781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_nonglobal_zone
12449781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
12459781SMoriah.Waterland@Sun.COM  * Scope:	public
12469781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
12479781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
12489781SMoriah.Waterland@Sun.COM  * Returns:	int
12499781SMoriah.Waterland@Sun.COM  *			== 0 - success
12509781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
12519781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
12529781SMoriah.Waterland@Sun.COM  *  - must not be installation of a global zone
12539781SMoriah.Waterland@Sun.COM  *  - success if installation of a non-global zone
12549781SMoriah.Waterland@Sun.COM  */
12559781SMoriah.Waterland@Sun.COM 
12569781SMoriah.Waterland@Sun.COM static int
cmd_is_nonglobal_zone(int argc,char ** argv,GLOBALDATA_T * a_gdt)12579781SMoriah.Waterland@Sun.COM cmd_is_nonglobal_zone(int argc, char **argv, GLOBALDATA_T *a_gdt)
12589781SMoriah.Waterland@Sun.COM {
12599781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
12609781SMoriah.Waterland@Sun.COM 	int	c;
12619781SMoriah.Waterland@Sun.COM 	int	r;
12629781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_nonglobal_zone";
12639781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
12649781SMoriah.Waterland@Sun.COM 
12659781SMoriah.Waterland@Sun.COM 	/* process any command line options */
12669781SMoriah.Waterland@Sun.COM 
12679781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
12689781SMoriah.Waterland@Sun.COM 		switch (c) {
12699781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
12709781SMoriah.Waterland@Sun.COM 			break;
12719781SMoriah.Waterland@Sun.COM 		case '?':
12729781SMoriah.Waterland@Sun.COM 		default:
12739781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
12749781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
12759781SMoriah.Waterland@Sun.COM 		}
12769781SMoriah.Waterland@Sun.COM 	}
12779781SMoriah.Waterland@Sun.COM 
12789781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
12799781SMoriah.Waterland@Sun.COM 
12809781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
12819781SMoriah.Waterland@Sun.COM 		recursion--;
12829781SMoriah.Waterland@Sun.COM 	}
12839781SMoriah.Waterland@Sun.COM 
12849781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
12859781SMoriah.Waterland@Sun.COM 
12869781SMoriah.Waterland@Sun.COM 	argc -= optind;
12879781SMoriah.Waterland@Sun.COM 	argv += optind;
12889781SMoriah.Waterland@Sun.COM 
12899781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
12909781SMoriah.Waterland@Sun.COM 
12919781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
12929781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
12939781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
12949781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
12959781SMoriah.Waterland@Sun.COM 	}
12969781SMoriah.Waterland@Sun.COM 
12979781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
12989781SMoriah.Waterland@Sun.COM 
12999781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
13009781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
13019781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
13029781SMoriah.Waterland@Sun.COM 		}
13039781SMoriah.Waterland@Sun.COM 	}
13049781SMoriah.Waterland@Sun.COM 
13059781SMoriah.Waterland@Sun.COM 	/* get current root path */
13069781SMoriah.Waterland@Sun.COM 
13079781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
13089781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
13099781SMoriah.Waterland@Sun.COM 		return (r);
13109781SMoriah.Waterland@Sun.COM 	}
13119781SMoriah.Waterland@Sun.COM 
13129781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
13139781SMoriah.Waterland@Sun.COM 
13149781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
13159781SMoriah.Waterland@Sun.COM 
13169781SMoriah.Waterland@Sun.COM 	/* handle if non-global zone installation to the install root */
13179781SMoriah.Waterland@Sun.COM 
13189781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_nonglobalZoneInstall == B_TRUE) &&
13199781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
13209781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_INSTALL_ZONENAME_IS_NGZ,
13219781SMoriah.Waterland@Sun.COM 			rootPath, a_gdt->gd_zoneName);
13229781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
13239781SMoriah.Waterland@Sun.COM 	}
13249781SMoriah.Waterland@Sun.COM 
13259781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
13269781SMoriah.Waterland@Sun.COM 
13279781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
13289781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
13299781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be non-global zone */
13309781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_INITIAL_INSTALL, rootPath);
13319781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
13329781SMoriah.Waterland@Sun.COM 	}
13339781SMoriah.Waterland@Sun.COM 
13349781SMoriah.Waterland@Sun.COM 	/* must not be installation of a global zone */
13359781SMoriah.Waterland@Sun.COM 
13369781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
13379781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
13389781SMoriah.Waterland@Sun.COM 		/* initial global zone install: no path can be nonglobal zone */
13399781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_GLOBAL_ZONE_INSTALL, rootPath);
13409781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
13419781SMoriah.Waterland@Sun.COM 	}
13429781SMoriah.Waterland@Sun.COM 
13439781SMoriah.Waterland@Sun.COM 	/*
13449781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13459781SMoriah.Waterland@Sun.COM 	 * if root directory is "/" then the only thing that needs to be done is
13469781SMoriah.Waterland@Sun.COM 	 * to test the zone name directly - if the zone name is "global" then
13479781SMoriah.Waterland@Sun.COM 	 * the target is not a non-global zone; otherwise if the zone name is
13489781SMoriah.Waterland@Sun.COM 	 * not "global" then the target IS a non-global zone.
13499781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13509781SMoriah.Waterland@Sun.COM 	 */
13519781SMoriah.Waterland@Sun.COM 
13529781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") == 0) {
13539781SMoriah.Waterland@Sun.COM 		/* target is current running root */
13549781SMoriah.Waterland@Sun.COM 		if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
13559781SMoriah.Waterland@Sun.COM 			/* in the global zone */
13569781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ,
13579781SMoriah.Waterland@Sun.COM 				rootPath, a_gdt->gd_zoneName);
13589781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
13599781SMoriah.Waterland@Sun.COM 		}
13609781SMoriah.Waterland@Sun.COM 		/* in a non-global zone */
13619781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_IS_NGZ,
13629781SMoriah.Waterland@Sun.COM 			rootPath, a_gdt->gd_zoneName);
13639781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
13649781SMoriah.Waterland@Sun.COM 	}
13659781SMoriah.Waterland@Sun.COM 
13669781SMoriah.Waterland@Sun.COM 	/*
13679781SMoriah.Waterland@Sun.COM 	 * $ROOTDIR/etc/zones/index must exist in a global zone. It also
13689781SMoriah.Waterland@Sun.COM 	 * exists in a non-global zone after s10u4 but we can't check that
13699781SMoriah.Waterland@Sun.COM 	 * since it is undeterministic for all releases so we only check
13709781SMoriah.Waterland@Sun.COM 	 * for the global zone here.
13719781SMoriah.Waterland@Sun.COM 	 */
13729781SMoriah.Waterland@Sun.COM 
13739781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/zones/index");
13749781SMoriah.Waterland@Sun.COM 	if (r == R_SUCCESS) {
13759781SMoriah.Waterland@Sun.COM 
13769781SMoriah.Waterland@Sun.COM 		/* See if "global" exists in .../etc/zones/index */
13779781SMoriah.Waterland@Sun.COM 
13789781SMoriah.Waterland@Sun.COM 		if (testPath(TEST_GLOBAL_TOKEN_IN_FILE, "%s/%s", rootPath,
13799781SMoriah.Waterland@Sun.COM 		    "/etc/zones/index") != R_SUCCESS) {
13809781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ,
13819781SMoriah.Waterland@Sun.COM 			    rootPath, GLOBAL_ZONENAME);
13829781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
13839781SMoriah.Waterland@Sun.COM 		}
13849781SMoriah.Waterland@Sun.COM 	}
13859781SMoriah.Waterland@Sun.COM 
13869781SMoriah.Waterland@Sun.COM 	/*
13879781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13889781SMoriah.Waterland@Sun.COM 	 * If the root directory is "/" then you can use only the zone
13899781SMoriah.Waterland@Sun.COM 	 * name to determine if the zone is non-global or not since the
13909781SMoriah.Waterland@Sun.COM 	 * package is being installed or removed to the current "zone".
13919781SMoriah.Waterland@Sun.COM 	 *
13929781SMoriah.Waterland@Sun.COM 	 * Since the root directory being tested is not "/" then you have to
13939781SMoriah.Waterland@Sun.COM 	 * look into the target to try and infer zone type using means other
13949781SMoriah.Waterland@Sun.COM 	 * than the zone name only.
13959781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13969781SMoriah.Waterland@Sun.COM 	 */
13979781SMoriah.Waterland@Sun.COM 
13989781SMoriah.Waterland@Sun.COM 	/* reject if any items found that cannot be in a non-global zone */
13999781SMoriah.Waterland@Sun.COM 
14009781SMoriah.Waterland@Sun.COM 	/* .tmp_proto must not exist */
14019781SMoriah.Waterland@Sun.COM 
14029781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_NOT_EXISTS, "%s/%s", rootPath, ".tmp_proto");
14039781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
14049781SMoriah.Waterland@Sun.COM 		/* $R/.tmp_proto cannot exist in a non-global zone */
14059781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS,
14069781SMoriah.Waterland@Sun.COM 			rootPath, "/.tmp_proto");
14079781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
14089781SMoriah.Waterland@Sun.COM 	}
14099781SMoriah.Waterland@Sun.COM 
14109781SMoriah.Waterland@Sun.COM 	/* /var must not be a symbolic link */
14119781SMoriah.Waterland@Sun.COM 
14129781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
14139781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/var");
14149781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
14159781SMoriah.Waterland@Sun.COM 		/* $R/var cannot be a symbolic link in a non-global zone */
14169781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_DOES_NOT_EXIST,
14179781SMoriah.Waterland@Sun.COM 			rootPath, "/var");
14189781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
14199781SMoriah.Waterland@Sun.COM 	}
14209781SMoriah.Waterland@Sun.COM 
14219781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/tmp/root/kernel must not exist */
14229781SMoriah.Waterland@Sun.COM 
14239781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_NOT_EXISTS,
14249781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/tmp/root/kernel");
14259781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
14269781SMoriah.Waterland@Sun.COM 		/* $R/tmp/root/kernel cannot exist in a non-global zone */
14279781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS,
14289781SMoriah.Waterland@Sun.COM 			rootPath, "/tmp/root/kernel");
14299781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
14309781SMoriah.Waterland@Sun.COM 	}
14319781SMoriah.Waterland@Sun.COM 
14329781SMoriah.Waterland@Sun.COM 	/*
14339781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
14349781SMoriah.Waterland@Sun.COM 	 * no items exist in $ROOTDIR that identify something other than
14359781SMoriah.Waterland@Sun.COM 	 * a non-global zone.
14369781SMoriah.Waterland@Sun.COM 	 *
14379781SMoriah.Waterland@Sun.COM 	 * if in global zone no more tests possible: is a non-global zone
14389781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
14399781SMoriah.Waterland@Sun.COM 	 */
14409781SMoriah.Waterland@Sun.COM 
14419781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) {
14429781SMoriah.Waterland@Sun.COM 		/* in the global zone */
14439781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_IN_GZ_IS_NONGLOBAL_ZONE,
14449781SMoriah.Waterland@Sun.COM 			rootPath);
14459781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
14469781SMoriah.Waterland@Sun.COM 	}
14479781SMoriah.Waterland@Sun.COM 
14489781SMoriah.Waterland@Sun.COM 	/*
14499781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
14509781SMoriah.Waterland@Sun.COM 	 * In non-global zone: interrogate zone name and type.
14519781SMoriah.Waterland@Sun.COM 	 *
14529781SMoriah.Waterland@Sun.COM 	 * The parent zone is the zone that the "pkgadd" or "pkgrm" command was
14539781SMoriah.Waterland@Sun.COM 	 * run in. The child zone is the zone that the "pkginstall" or
14549781SMoriah.Waterland@Sun.COM 	 * "pkgremove" command was run in.
14559781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
14569781SMoriah.Waterland@Sun.COM 	 */
14579781SMoriah.Waterland@Sun.COM 
14589781SMoriah.Waterland@Sun.COM 	/*
14599781SMoriah.Waterland@Sun.COM 	 * If parent zone name and current zone name defined, and
14609781SMoriah.Waterland@Sun.COM 	 * both zone names are the same, since pkgcond is running
14619781SMoriah.Waterland@Sun.COM 	 * inside of a non-global zone, this is how the scratch
14629781SMoriah.Waterland@Sun.COM 	 * zone is implemented, so target is a non-global zone
14639781SMoriah.Waterland@Sun.COM 	 */
14649781SMoriah.Waterland@Sun.COM 
14659781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_parentZoneName != NULL) &&
14669781SMoriah.Waterland@Sun.COM 		(a_gdt->gd_currentZoneName != NULL) &&
14679781SMoriah.Waterland@Sun.COM 		(strcmp(a_gdt->gd_parentZoneName,
14689781SMoriah.Waterland@Sun.COM 					a_gdt->gd_currentZoneName) == 0)) {
14699781SMoriah.Waterland@Sun.COM 			/* parent and current zone name identical: non-gz */
14709781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_DEBUG, DBG_NGZN_PARENT_CHILD_SAMEZONE,
14719781SMoriah.Waterland@Sun.COM 				rootPath, a_gdt->gd_parentZoneName);
14729781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
14739781SMoriah.Waterland@Sun.COM 	}
14749781SMoriah.Waterland@Sun.COM 
14759781SMoriah.Waterland@Sun.COM 	/*
1476*12734Sgary.pennington@oracle.com 	 * In non-global zone if zone specific read only FS's exist
14779781SMoriah.Waterland@Sun.COM 	 * or it is in a mounted state.
14789781SMoriah.Waterland@Sun.COM 	 */
14799781SMoriah.Waterland@Sun.COM 
1480*12734Sgary.pennington@oracle.com 	if (a_gdt->inMountedState) {
14819781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath);
14829781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
14839781SMoriah.Waterland@Sun.COM 	}
14849781SMoriah.Waterland@Sun.COM 
14859781SMoriah.Waterland@Sun.COM 	/*
14869781SMoriah.Waterland@Sun.COM 	 * the parent and current zone name are not the same;
14879781SMoriah.Waterland@Sun.COM 	 * interrogate the zone types: the parent must be global
14889781SMoriah.Waterland@Sun.COM 	 * and the current must be non-global, which would be set
14899781SMoriah.Waterland@Sun.COM 	 * when a package command is run in the global zone that in
14909781SMoriah.Waterland@Sun.COM 	 * turn runs a package command within the non-global zone.
14919781SMoriah.Waterland@Sun.COM 	 */
14929781SMoriah.Waterland@Sun.COM 
14939781SMoriah.Waterland@Sun.COM 	/* if defined, parent zone type must be "global" */
14949781SMoriah.Waterland@Sun.COM 
14959781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_parentZoneType != NULL) &&
14969781SMoriah.Waterland@Sun.COM 		(strcmp(a_gdt->gd_parentZoneType, "nonglobal") == 0)) {
14979781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_PARENT_ZONETYPE,
14989781SMoriah.Waterland@Sun.COM 			rootPath, "nonglobal");
14999781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
15009781SMoriah.Waterland@Sun.COM 	}
15019781SMoriah.Waterland@Sun.COM 
15029781SMoriah.Waterland@Sun.COM 	/* if defined, current zone type must be "nonglobal" */
15039781SMoriah.Waterland@Sun.COM 
15049781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_currentZoneType != NULL) &&
15059781SMoriah.Waterland@Sun.COM 		(strcmp(a_gdt->gd_currentZoneType, GLOBAL_ZONENAME) == 0)) {
15069781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_CURRENT_ZONETYPE,
15079781SMoriah.Waterland@Sun.COM 			rootPath, GLOBAL_ZONENAME);
15089781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
15099781SMoriah.Waterland@Sun.COM 	}
15109781SMoriah.Waterland@Sun.COM 
15119781SMoriah.Waterland@Sun.COM 	/*
15129781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
15139781SMoriah.Waterland@Sun.COM 	 * no other tests possible: target is a non-global zone
15149781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
15159781SMoriah.Waterland@Sun.COM 	 */
15169781SMoriah.Waterland@Sun.COM 
15179781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath);
15189781SMoriah.Waterland@Sun.COM 
15199781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
15209781SMoriah.Waterland@Sun.COM }
15219781SMoriah.Waterland@Sun.COM 
15229781SMoriah.Waterland@Sun.COM /*
15239781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_running_system
15249781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
15259781SMoriah.Waterland@Sun.COM  * Scope:	public
15269781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
15279781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
15289781SMoriah.Waterland@Sun.COM  * Returns:	int
15299781SMoriah.Waterland@Sun.COM  *			== 0 - success
15309781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
15319781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
15329781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
15339781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
15349781SMoriah.Waterland@Sun.COM  *  - must not be a diskless client
15359781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR must be "/"
15369781SMoriah.Waterland@Sun.COM  *  - zone name must be "global"
15379781SMoriah.Waterland@Sun.COM  */
15389781SMoriah.Waterland@Sun.COM 
15399781SMoriah.Waterland@Sun.COM static int
cmd_is_running_system(int argc,char ** argv,GLOBALDATA_T * a_gdt)15409781SMoriah.Waterland@Sun.COM cmd_is_running_system(int argc, char **argv, GLOBALDATA_T *a_gdt)
15419781SMoriah.Waterland@Sun.COM {
15429781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
15439781SMoriah.Waterland@Sun.COM 	int	c;
15449781SMoriah.Waterland@Sun.COM 	int	r;
15459781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_running_system";
15469781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
15479781SMoriah.Waterland@Sun.COM 
15489781SMoriah.Waterland@Sun.COM 	/* process any command line options */
15499781SMoriah.Waterland@Sun.COM 
15509781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
15519781SMoriah.Waterland@Sun.COM 		switch (c) {
15529781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
15539781SMoriah.Waterland@Sun.COM 			break;
15549781SMoriah.Waterland@Sun.COM 		case '?':
15559781SMoriah.Waterland@Sun.COM 		default:
15569781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
15579781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
15589781SMoriah.Waterland@Sun.COM 		}
15599781SMoriah.Waterland@Sun.COM 	}
15609781SMoriah.Waterland@Sun.COM 
15619781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
15629781SMoriah.Waterland@Sun.COM 
15639781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
15649781SMoriah.Waterland@Sun.COM 
15659781SMoriah.Waterland@Sun.COM 		/* a running system cannot be a diskless client */
15669781SMoriah.Waterland@Sun.COM 
15679781SMoriah.Waterland@Sun.COM 		r = cmd_is_diskless_client(argc, argv, a_gdt);
15689781SMoriah.Waterland@Sun.COM 
15699781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
15709781SMoriah.Waterland@Sun.COM 
15719781SMoriah.Waterland@Sun.COM 		recursion--;
15729781SMoriah.Waterland@Sun.COM 
15739781SMoriah.Waterland@Sun.COM 		switch (r) {
15749781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
15759781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
15769781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
15779781SMoriah.Waterland@Sun.COM 				break;
15789781SMoriah.Waterland@Sun.COM 			case R_USAGE:
15799781SMoriah.Waterland@Sun.COM 			case R_ERROR:
15809781SMoriah.Waterland@Sun.COM 			default:
15819781SMoriah.Waterland@Sun.COM 				return (r);
15829781SMoriah.Waterland@Sun.COM 		}
15839781SMoriah.Waterland@Sun.COM 	}
15849781SMoriah.Waterland@Sun.COM 
15859781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
15869781SMoriah.Waterland@Sun.COM 
15879781SMoriah.Waterland@Sun.COM 	argc -= optind;
15889781SMoriah.Waterland@Sun.COM 	argv += optind;
15899781SMoriah.Waterland@Sun.COM 
15909781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
15919781SMoriah.Waterland@Sun.COM 
15929781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
15939781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
15949781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
15959781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
15969781SMoriah.Waterland@Sun.COM 	}
15979781SMoriah.Waterland@Sun.COM 
15989781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
15999781SMoriah.Waterland@Sun.COM 
16009781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
16019781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
16029781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
16039781SMoriah.Waterland@Sun.COM 		}
16049781SMoriah.Waterland@Sun.COM 	}
16059781SMoriah.Waterland@Sun.COM 
16069781SMoriah.Waterland@Sun.COM 	/* get current root path */
16079781SMoriah.Waterland@Sun.COM 
16089781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
16099781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
16109781SMoriah.Waterland@Sun.COM 		return (r);
16119781SMoriah.Waterland@Sun.COM 	}
16129781SMoriah.Waterland@Sun.COM 
16139781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
16149781SMoriah.Waterland@Sun.COM 
16159781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
16169781SMoriah.Waterland@Sun.COM 
16179781SMoriah.Waterland@Sun.COM 	/* if root path is "/" then check zone name */
16189781SMoriah.Waterland@Sun.COM 
16199781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") != 0) {
16209781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ROOTPATH_BAD, rootPath, "/");
16219781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
16229781SMoriah.Waterland@Sun.COM 	}
16239781SMoriah.Waterland@Sun.COM 
16249781SMoriah.Waterland@Sun.COM 	/* zone name must be global */
16259781SMoriah.Waterland@Sun.COM 
16269781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
16279781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_BAD, rootPath,
16289781SMoriah.Waterland@Sun.COM 			GLOBAL_ZONENAME);
16299781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
16309781SMoriah.Waterland@Sun.COM 	}
16319781SMoriah.Waterland@Sun.COM 
16329781SMoriah.Waterland@Sun.COM 	/* must not be initial installation to the install root */
16339781SMoriah.Waterland@Sun.COM 
16349781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
16359781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
16369781SMoriah.Waterland@Sun.COM 		/* initial install: install root cannot be the running system */
16379781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IRST_INITIAL_INSTALL, rootPath);
16389781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
16399781SMoriah.Waterland@Sun.COM 	}
16409781SMoriah.Waterland@Sun.COM 
16419781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
16429781SMoriah.Waterland@Sun.COM 
16439781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
16449781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
16459781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be running system */
16469781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_INSTALL, rootPath);
16479781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
16489781SMoriah.Waterland@Sun.COM 	}
16499781SMoriah.Waterland@Sun.COM 
16509781SMoriah.Waterland@Sun.COM 	/* target is a running system */
16519781SMoriah.Waterland@Sun.COM 
16529781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_IRST_PATH_IS_RUNNING_SYSTEM, rootPath);
16539781SMoriah.Waterland@Sun.COM 
16549781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
16559781SMoriah.Waterland@Sun.COM }
16569781SMoriah.Waterland@Sun.COM 
16579781SMoriah.Waterland@Sun.COM /*
16589781SMoriah.Waterland@Sun.COM  * Name:	cmd_can_add_driver
16599781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
16609781SMoriah.Waterland@Sun.COM  * Scope:	public
16619781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
16629781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
16639781SMoriah.Waterland@Sun.COM  * Returns:	int
16649781SMoriah.Waterland@Sun.COM  *			== 0 - success
16659781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
16669781SMoriah.Waterland@Sun.COM  * Implementation:
16679781SMoriah.Waterland@Sun.COM  * A driver can be added to the system if the components of a Solaris
16689781SMoriah.Waterland@Sun.COM  * instance capable of loading drivers is present and it is not the
16699781SMoriah.Waterland@Sun.COM  * currently running system.
16709781SMoriah.Waterland@Sun.COM  */
16719781SMoriah.Waterland@Sun.COM 
16729781SMoriah.Waterland@Sun.COM static int
cmd_can_add_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)16739781SMoriah.Waterland@Sun.COM cmd_can_add_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
16749781SMoriah.Waterland@Sun.COM {
16759781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
16769781SMoriah.Waterland@Sun.COM 	int	c;
16779781SMoriah.Waterland@Sun.COM 	int	r;
16789781SMoriah.Waterland@Sun.COM static	char	*cmdName = "can_add_driver";
16799781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
16809781SMoriah.Waterland@Sun.COM 
16819781SMoriah.Waterland@Sun.COM 	/* process any command line options */
16829781SMoriah.Waterland@Sun.COM 
16839781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
16849781SMoriah.Waterland@Sun.COM 		switch (c) {
16859781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
16869781SMoriah.Waterland@Sun.COM 			break;
16879781SMoriah.Waterland@Sun.COM 		case '?':
16889781SMoriah.Waterland@Sun.COM 		default:
16899781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
16909781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
16919781SMoriah.Waterland@Sun.COM 		}
16929781SMoriah.Waterland@Sun.COM 	}
16939781SMoriah.Waterland@Sun.COM 
16949781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
16959781SMoriah.Waterland@Sun.COM 
16969781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
16979781SMoriah.Waterland@Sun.COM 
16989781SMoriah.Waterland@Sun.COM 		/* see if this is the current running system */
16999781SMoriah.Waterland@Sun.COM 
17009781SMoriah.Waterland@Sun.COM 		r = cmd_is_running_system(argc, argv, a_gdt);
17019781SMoriah.Waterland@Sun.COM 
17029781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless client */
17039781SMoriah.Waterland@Sun.COM 
17049781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
17059781SMoriah.Waterland@Sun.COM 			r = cmd_is_diskless_client(argc, argv, a_gdt);
17069781SMoriah.Waterland@Sun.COM 		}
17079781SMoriah.Waterland@Sun.COM 
17089781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
17099781SMoriah.Waterland@Sun.COM 
17109781SMoriah.Waterland@Sun.COM 		recursion--;
17119781SMoriah.Waterland@Sun.COM 
17129781SMoriah.Waterland@Sun.COM 		switch (r) {
17139781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
17149781SMoriah.Waterland@Sun.COM 				/* is a running system */
17159781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
17169781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
17179781SMoriah.Waterland@Sun.COM 				/* not a running syste */
17189781SMoriah.Waterland@Sun.COM 				break;
17199781SMoriah.Waterland@Sun.COM 			case R_USAGE:
17209781SMoriah.Waterland@Sun.COM 			case R_ERROR:
17219781SMoriah.Waterland@Sun.COM 			default:
17229781SMoriah.Waterland@Sun.COM 				/* cannot determine if is a running system */
17239781SMoriah.Waterland@Sun.COM 				return (r);
17249781SMoriah.Waterland@Sun.COM 		}
17259781SMoriah.Waterland@Sun.COM 	}
17269781SMoriah.Waterland@Sun.COM 
17279781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
17289781SMoriah.Waterland@Sun.COM 
17299781SMoriah.Waterland@Sun.COM 	argc -= optind;
17309781SMoriah.Waterland@Sun.COM 	argv += optind;
17319781SMoriah.Waterland@Sun.COM 
17329781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
17339781SMoriah.Waterland@Sun.COM 
17349781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
17359781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
17369781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
17379781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
17389781SMoriah.Waterland@Sun.COM 	}
17399781SMoriah.Waterland@Sun.COM 
17409781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
17419781SMoriah.Waterland@Sun.COM 
17429781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
17439781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
17449781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
17459781SMoriah.Waterland@Sun.COM 		}
17469781SMoriah.Waterland@Sun.COM 	}
17479781SMoriah.Waterland@Sun.COM 
17489781SMoriah.Waterland@Sun.COM 	/* get current root path */
17499781SMoriah.Waterland@Sun.COM 
17509781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
17519781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
17529781SMoriah.Waterland@Sun.COM 		return (r);
17539781SMoriah.Waterland@Sun.COM 	}
17549781SMoriah.Waterland@Sun.COM 
17559781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
17569781SMoriah.Waterland@Sun.COM 
17579781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
17589781SMoriah.Waterland@Sun.COM 
17599781SMoriah.Waterland@Sun.COM 	/* /etc must exist and must not be a symbolic link */
17609781SMoriah.Waterland@Sun.COM 
17619781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17629781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/etc");
17639781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
17649781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17659781SMoriah.Waterland@Sun.COM 			rootPath, "/etc");
17669781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
17679781SMoriah.Waterland@Sun.COM 	}
17689781SMoriah.Waterland@Sun.COM 
17699781SMoriah.Waterland@Sun.COM 	/* /platform must exist and must not be a symbolic link */
17709781SMoriah.Waterland@Sun.COM 
17719781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17729781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/platform");
17739781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
17749781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17759781SMoriah.Waterland@Sun.COM 			rootPath, "/platform");
17769781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
17779781SMoriah.Waterland@Sun.COM 	}
17789781SMoriah.Waterland@Sun.COM 
17799781SMoriah.Waterland@Sun.COM 	/* /kernel must exist and must not be a symbolic link */
17809781SMoriah.Waterland@Sun.COM 
17819781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
17829781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/kernel");
17839781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
17849781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK,
17859781SMoriah.Waterland@Sun.COM 			rootPath, "/kernel");
17869781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
17879781SMoriah.Waterland@Sun.COM 	}
17889781SMoriah.Waterland@Sun.COM 
17899781SMoriah.Waterland@Sun.COM 	/* can add a driver */
17909781SMoriah.Waterland@Sun.COM 
17919781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_ADDV_YES, rootPath);
17929781SMoriah.Waterland@Sun.COM 
17939781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
17949781SMoriah.Waterland@Sun.COM }
17959781SMoriah.Waterland@Sun.COM 
17969781SMoriah.Waterland@Sun.COM /*
17979781SMoriah.Waterland@Sun.COM  * Name:	cmd_can_update_driver
17989781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
17999781SMoriah.Waterland@Sun.COM  * Scope:	public
18009781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
18019781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
18029781SMoriah.Waterland@Sun.COM  * Returns:	int
18039781SMoriah.Waterland@Sun.COM  *			== 0 - success
18049781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
18059781SMoriah.Waterland@Sun.COM  * Implementation:
18069781SMoriah.Waterland@Sun.COM  * A driver can be added to the system if the components of a Solaris
18079781SMoriah.Waterland@Sun.COM  * instance capable of loading drivers is present and it is not the
18089781SMoriah.Waterland@Sun.COM  * currently running system.
18099781SMoriah.Waterland@Sun.COM  */
18109781SMoriah.Waterland@Sun.COM 
18119781SMoriah.Waterland@Sun.COM static int
cmd_can_update_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)18129781SMoriah.Waterland@Sun.COM cmd_can_update_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
18139781SMoriah.Waterland@Sun.COM {
18149781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
18159781SMoriah.Waterland@Sun.COM 	int	c;
18169781SMoriah.Waterland@Sun.COM 	int	r;
18179781SMoriah.Waterland@Sun.COM static	char	*cmdName = "can_update_driver";
18189781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
18199781SMoriah.Waterland@Sun.COM 
18209781SMoriah.Waterland@Sun.COM 	/* process any command line options */
18219781SMoriah.Waterland@Sun.COM 
18229781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
18239781SMoriah.Waterland@Sun.COM 		switch (c) {
18249781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
18259781SMoriah.Waterland@Sun.COM 			break;
18269781SMoriah.Waterland@Sun.COM 		case '?':
18279781SMoriah.Waterland@Sun.COM 		default:
18289781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
18299781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
18309781SMoriah.Waterland@Sun.COM 		}
18319781SMoriah.Waterland@Sun.COM 	}
18329781SMoriah.Waterland@Sun.COM 
18339781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
18349781SMoriah.Waterland@Sun.COM 
18359781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
18369781SMoriah.Waterland@Sun.COM 
18379781SMoriah.Waterland@Sun.COM 		/* see if this is the current running system */
18389781SMoriah.Waterland@Sun.COM 
18399781SMoriah.Waterland@Sun.COM 		r = cmd_is_running_system(argc, argv, a_gdt);
18409781SMoriah.Waterland@Sun.COM 
18419781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless client */
18429781SMoriah.Waterland@Sun.COM 
18439781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
18449781SMoriah.Waterland@Sun.COM 			r = cmd_is_diskless_client(argc, argv, a_gdt);
18459781SMoriah.Waterland@Sun.COM 		}
18469781SMoriah.Waterland@Sun.COM 
18479781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
18489781SMoriah.Waterland@Sun.COM 
18499781SMoriah.Waterland@Sun.COM 		recursion--;
18509781SMoriah.Waterland@Sun.COM 
18519781SMoriah.Waterland@Sun.COM 		switch (r) {
18529781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
18539781SMoriah.Waterland@Sun.COM 				/* is a running system */
18549781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
18559781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
18569781SMoriah.Waterland@Sun.COM 				/* not a running syste */
18579781SMoriah.Waterland@Sun.COM 				break;
18589781SMoriah.Waterland@Sun.COM 			case R_USAGE:
18599781SMoriah.Waterland@Sun.COM 			case R_ERROR:
18609781SMoriah.Waterland@Sun.COM 			default:
18619781SMoriah.Waterland@Sun.COM 				/* cannot determine if is a running system */
18629781SMoriah.Waterland@Sun.COM 				return (r);
18639781SMoriah.Waterland@Sun.COM 		}
18649781SMoriah.Waterland@Sun.COM 	}
18659781SMoriah.Waterland@Sun.COM 
18669781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
18679781SMoriah.Waterland@Sun.COM 
18689781SMoriah.Waterland@Sun.COM 	argc -= optind;
18699781SMoriah.Waterland@Sun.COM 	argv += optind;
18709781SMoriah.Waterland@Sun.COM 
18719781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
18729781SMoriah.Waterland@Sun.COM 
18739781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
18749781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
18759781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
18769781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
18779781SMoriah.Waterland@Sun.COM 	}
18789781SMoriah.Waterland@Sun.COM 
18799781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
18809781SMoriah.Waterland@Sun.COM 
18819781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
18829781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
18839781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
18849781SMoriah.Waterland@Sun.COM 		}
18859781SMoriah.Waterland@Sun.COM 	}
18869781SMoriah.Waterland@Sun.COM 
18879781SMoriah.Waterland@Sun.COM 	/* get current root path */
18889781SMoriah.Waterland@Sun.COM 
18899781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
18909781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
18919781SMoriah.Waterland@Sun.COM 		return (r);
18929781SMoriah.Waterland@Sun.COM 	}
18939781SMoriah.Waterland@Sun.COM 
18949781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
18959781SMoriah.Waterland@Sun.COM 
18969781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
18979781SMoriah.Waterland@Sun.COM 
18989781SMoriah.Waterland@Sun.COM 	/* /etc must exist and must not be a symbolic link */
18999781SMoriah.Waterland@Sun.COM 
19009781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
19019781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/etc");
19029781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
19039781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19049781SMoriah.Waterland@Sun.COM 			rootPath, "/etc");
19059781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
19069781SMoriah.Waterland@Sun.COM 	}
19079781SMoriah.Waterland@Sun.COM 
19089781SMoriah.Waterland@Sun.COM 	/* /platform must exist and must not be a symbolic link */
19099781SMoriah.Waterland@Sun.COM 
19109781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
19119781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/platform");
19129781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
19139781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19149781SMoriah.Waterland@Sun.COM 			rootPath, "/platform");
19159781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
19169781SMoriah.Waterland@Sun.COM 	}
19179781SMoriah.Waterland@Sun.COM 
19189781SMoriah.Waterland@Sun.COM 	/* /kernel must exist and must not be a symbolic link */
19199781SMoriah.Waterland@Sun.COM 
19209781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
19219781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/kernel");
19229781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
19239781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK,
19249781SMoriah.Waterland@Sun.COM 			rootPath, "/kernel");
19259781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
19269781SMoriah.Waterland@Sun.COM 	}
19279781SMoriah.Waterland@Sun.COM 
19289781SMoriah.Waterland@Sun.COM 	/* can update driver */
19299781SMoriah.Waterland@Sun.COM 
19309781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_UPDV_YES, rootPath);
19319781SMoriah.Waterland@Sun.COM 
19329781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
19339781SMoriah.Waterland@Sun.COM }
19349781SMoriah.Waterland@Sun.COM 
19359781SMoriah.Waterland@Sun.COM /*
19369781SMoriah.Waterland@Sun.COM  * Name:	cmd_can_remove_driver
19379781SMoriah.Waterland@Sun.COM  * Description:	determine if target is a global zone
19389781SMoriah.Waterland@Sun.COM  * Scope:	public
19399781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
19409781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
19419781SMoriah.Waterland@Sun.COM  * Returns:	int
19429781SMoriah.Waterland@Sun.COM  *			== 0 - success
19439781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
19449781SMoriah.Waterland@Sun.COM  * Implementation:
19459781SMoriah.Waterland@Sun.COM  * A driver can be added to the system if the components of a Solaris
19469781SMoriah.Waterland@Sun.COM  * instance capable of loading drivers is present and it is not the
19479781SMoriah.Waterland@Sun.COM  * currently running system.
19489781SMoriah.Waterland@Sun.COM  */
19499781SMoriah.Waterland@Sun.COM 
19509781SMoriah.Waterland@Sun.COM static int
cmd_can_remove_driver(int argc,char ** argv,GLOBALDATA_T * a_gdt)19519781SMoriah.Waterland@Sun.COM cmd_can_remove_driver(int argc, char **argv, GLOBALDATA_T *a_gdt)
19529781SMoriah.Waterland@Sun.COM {
19539781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
19549781SMoriah.Waterland@Sun.COM 	int	c;
19559781SMoriah.Waterland@Sun.COM 	int	r;
19569781SMoriah.Waterland@Sun.COM static	char	*cmdName = "can_remove_driver";
19579781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
19589781SMoriah.Waterland@Sun.COM 
19599781SMoriah.Waterland@Sun.COM 	/* process any command line options */
19609781SMoriah.Waterland@Sun.COM 
19619781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
19629781SMoriah.Waterland@Sun.COM 		switch (c) {
19639781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
19649781SMoriah.Waterland@Sun.COM 			break;
19659781SMoriah.Waterland@Sun.COM 		case '?':
19669781SMoriah.Waterland@Sun.COM 		default:
19679781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
19689781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
19699781SMoriah.Waterland@Sun.COM 		}
19709781SMoriah.Waterland@Sun.COM 	}
19719781SMoriah.Waterland@Sun.COM 
19729781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
19739781SMoriah.Waterland@Sun.COM 
19749781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
19759781SMoriah.Waterland@Sun.COM 
19769781SMoriah.Waterland@Sun.COM 		/* see if this is the current running system */
19779781SMoriah.Waterland@Sun.COM 
19789781SMoriah.Waterland@Sun.COM 		r = cmd_is_running_system(argc, argv, a_gdt);
19799781SMoriah.Waterland@Sun.COM 
19809781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless client */
19819781SMoriah.Waterland@Sun.COM 
19829781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
19839781SMoriah.Waterland@Sun.COM 			r = cmd_is_diskless_client(argc, argv, a_gdt);
19849781SMoriah.Waterland@Sun.COM 		}
19859781SMoriah.Waterland@Sun.COM 
19869781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
19879781SMoriah.Waterland@Sun.COM 
19889781SMoriah.Waterland@Sun.COM 		recursion--;
19899781SMoriah.Waterland@Sun.COM 
19909781SMoriah.Waterland@Sun.COM 		switch (r) {
19919781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
19929781SMoriah.Waterland@Sun.COM 				/* is a running system */
19939781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
19949781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
19959781SMoriah.Waterland@Sun.COM 				/* not a running syste */
19969781SMoriah.Waterland@Sun.COM 				break;
19979781SMoriah.Waterland@Sun.COM 			case R_USAGE:
19989781SMoriah.Waterland@Sun.COM 			case R_ERROR:
19999781SMoriah.Waterland@Sun.COM 			default:
20009781SMoriah.Waterland@Sun.COM 				/* cannot determine if is a running system */
20019781SMoriah.Waterland@Sun.COM 				return (r);
20029781SMoriah.Waterland@Sun.COM 		}
20039781SMoriah.Waterland@Sun.COM 	}
20049781SMoriah.Waterland@Sun.COM 
20059781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
20069781SMoriah.Waterland@Sun.COM 
20079781SMoriah.Waterland@Sun.COM 	argc -= optind;
20089781SMoriah.Waterland@Sun.COM 	argv += optind;
20099781SMoriah.Waterland@Sun.COM 
20109781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
20119781SMoriah.Waterland@Sun.COM 
20129781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
20139781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
20149781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
20159781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
20169781SMoriah.Waterland@Sun.COM 	}
20179781SMoriah.Waterland@Sun.COM 
20189781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
20199781SMoriah.Waterland@Sun.COM 
20209781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
20219781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
20229781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
20239781SMoriah.Waterland@Sun.COM 		}
20249781SMoriah.Waterland@Sun.COM 	}
20259781SMoriah.Waterland@Sun.COM 
20269781SMoriah.Waterland@Sun.COM 	/* get current root path */
20279781SMoriah.Waterland@Sun.COM 
20289781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
20299781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
20309781SMoriah.Waterland@Sun.COM 		return (r);
20319781SMoriah.Waterland@Sun.COM 	}
20329781SMoriah.Waterland@Sun.COM 
20339781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
20349781SMoriah.Waterland@Sun.COM 
20359781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
20369781SMoriah.Waterland@Sun.COM 
20379781SMoriah.Waterland@Sun.COM 	/* /etc must exist and must not be a symbolic link */
20389781SMoriah.Waterland@Sun.COM 
20399781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20409781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/etc");
20419781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
20429781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20439781SMoriah.Waterland@Sun.COM 			rootPath, "/etc");
20449781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
20459781SMoriah.Waterland@Sun.COM 	}
20469781SMoriah.Waterland@Sun.COM 
20479781SMoriah.Waterland@Sun.COM 	/* /platform must exist and must not be a symbolic link */
20489781SMoriah.Waterland@Sun.COM 
20499781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20509781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/platform");
20519781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
20529781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20539781SMoriah.Waterland@Sun.COM 			rootPath, "/platform");
20549781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
20559781SMoriah.Waterland@Sun.COM 	}
20569781SMoriah.Waterland@Sun.COM 
20579781SMoriah.Waterland@Sun.COM 	/* /kernel must exist and must not be a symbolic link */
20589781SMoriah.Waterland@Sun.COM 
20599781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK,
20609781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/kernel");
20619781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
20629781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK,
20639781SMoriah.Waterland@Sun.COM 			rootPath, "/kernel");
20649781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
20659781SMoriah.Waterland@Sun.COM 	}
20669781SMoriah.Waterland@Sun.COM 
20679781SMoriah.Waterland@Sun.COM 	/* can remove driver */
20689781SMoriah.Waterland@Sun.COM 
20699781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_RMDV_YES, rootPath);
20709781SMoriah.Waterland@Sun.COM 
20719781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
20729781SMoriah.Waterland@Sun.COM }
20739781SMoriah.Waterland@Sun.COM 
20749781SMoriah.Waterland@Sun.COM /*
20759781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_path_writable
2076*12734Sgary.pennington@oracle.com  * Description:	determine if target path is writable
20779781SMoriah.Waterland@Sun.COM  * Scope:	public
20789781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
20799781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
20809781SMoriah.Waterland@Sun.COM  * Returns:	int
20819781SMoriah.Waterland@Sun.COM  *			== 0 - success
20829781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
20839781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
20849781SMoriah.Waterland@Sun.COM  * - path must be found in the file systems configured
20859781SMoriah.Waterland@Sun.COM  * - mount options must not include "read only"
20869781SMoriah.Waterland@Sun.COM  */
20879781SMoriah.Waterland@Sun.COM 
20889781SMoriah.Waterland@Sun.COM static int
cmd_is_path_writable(int argc,char ** argv,GLOBALDATA_T * a_gdt)20899781SMoriah.Waterland@Sun.COM cmd_is_path_writable(int argc, char **argv, GLOBALDATA_T *a_gdt)
20909781SMoriah.Waterland@Sun.COM {
20919781SMoriah.Waterland@Sun.COM 	FSI_T	*list;
20929781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
20939781SMoriah.Waterland@Sun.COM 	int	c;
20949781SMoriah.Waterland@Sun.COM 	int	n;
20959781SMoriah.Waterland@Sun.COM 	int	nn;
20969781SMoriah.Waterland@Sun.COM 	int	r;
20979781SMoriah.Waterland@Sun.COM 	long	listSize;
20989781SMoriah.Waterland@Sun.COM 	long	rootPathLen;
20999781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_path_writable";
21009781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
21019781SMoriah.Waterland@Sun.COM 
21029781SMoriah.Waterland@Sun.COM 	/* process any command line options */
21039781SMoriah.Waterland@Sun.COM 
21049781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
21059781SMoriah.Waterland@Sun.COM 		switch (c) {
21069781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
21079781SMoriah.Waterland@Sun.COM 			break;
21089781SMoriah.Waterland@Sun.COM 		case '?':
21099781SMoriah.Waterland@Sun.COM 		default:
21109781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
21119781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
21129781SMoriah.Waterland@Sun.COM 		}
21139781SMoriah.Waterland@Sun.COM 	}
21149781SMoriah.Waterland@Sun.COM 
21159781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
21169781SMoriah.Waterland@Sun.COM 
21179781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
21189781SMoriah.Waterland@Sun.COM 		recursion--;
21199781SMoriah.Waterland@Sun.COM 	}
21209781SMoriah.Waterland@Sun.COM 
21219781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
21229781SMoriah.Waterland@Sun.COM 
21239781SMoriah.Waterland@Sun.COM 	argc -= optind;
21249781SMoriah.Waterland@Sun.COM 	argv += optind;
21259781SMoriah.Waterland@Sun.COM 
21269781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
21279781SMoriah.Waterland@Sun.COM 
21289781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
21299781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
21309781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
21319781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
21329781SMoriah.Waterland@Sun.COM 	}
21339781SMoriah.Waterland@Sun.COM 
21349781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
21359781SMoriah.Waterland@Sun.COM 
21369781SMoriah.Waterland@Sun.COM 	if (argc != 1) {
21379781SMoriah.Waterland@Sun.COM 		(void) usage(ERR_REQUIRED_ROOTPATH_MISSING, cmdName);
21389781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
21399781SMoriah.Waterland@Sun.COM 	}
21409781SMoriah.Waterland@Sun.COM 
21419781SMoriah.Waterland@Sun.COM 	if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
21429781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
21439781SMoriah.Waterland@Sun.COM 	}
21449781SMoriah.Waterland@Sun.COM 
21459781SMoriah.Waterland@Sun.COM 	/* get current root path */
21469781SMoriah.Waterland@Sun.COM 
21479781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
21489781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
21499781SMoriah.Waterland@Sun.COM 		return (r);
21509781SMoriah.Waterland@Sun.COM 	}
21519781SMoriah.Waterland@Sun.COM 
21529781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
21539781SMoriah.Waterland@Sun.COM 
21549781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
21559781SMoriah.Waterland@Sun.COM 
21569781SMoriah.Waterland@Sun.COM 	/* search file system conf for this path */
21579781SMoriah.Waterland@Sun.COM 
21589781SMoriah.Waterland@Sun.COM 	rootPathLen = strlen(rootPath);
21599781SMoriah.Waterland@Sun.COM 	list = a_gdt->gd_fileSystemConfig;
21609781SMoriah.Waterland@Sun.COM 	listSize = a_gdt->gd_fileSystemConfigLen;
21619781SMoriah.Waterland@Sun.COM 	for (nn = 0, n = 0; n < listSize; n++) {
21629781SMoriah.Waterland@Sun.COM 		long	mplen = strlen(list[n].fsi_mntPoint);
21639781SMoriah.Waterland@Sun.COM 		if (rootPathLen < mplen) {
21649781SMoriah.Waterland@Sun.COM 			/* root path is longer than target, ignore */
21659781SMoriah.Waterland@Sun.COM 			continue;
21669781SMoriah.Waterland@Sun.COM 		}
21679781SMoriah.Waterland@Sun.COM 		if (strncmp(rootPath, list[n].fsi_mntPoint, mplen) == 0) {
21689781SMoriah.Waterland@Sun.COM 			/* remember last partial match */
21699781SMoriah.Waterland@Sun.COM 			nn = n;
21709781SMoriah.Waterland@Sun.COM 		}
21719781SMoriah.Waterland@Sun.COM 	}
21729781SMoriah.Waterland@Sun.COM 
21739781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_PWRT_INFO,
21749781SMoriah.Waterland@Sun.COM 		rootPath, list[nn].fsi_mntPoint, list[nn].fsi_fsType,
21759781SMoriah.Waterland@Sun.COM 		list[nn].fsi_mntOptions);
21769781SMoriah.Waterland@Sun.COM 
21779781SMoriah.Waterland@Sun.COM 	/*
21789781SMoriah.Waterland@Sun.COM 	 * need to determine if the mount point is writeable:
21799781SMoriah.Waterland@Sun.COM 	 */
21809781SMoriah.Waterland@Sun.COM 
21819781SMoriah.Waterland@Sun.COM 	/* see if the file system is mounted with the "read only" option */
21829781SMoriah.Waterland@Sun.COM 
21839781SMoriah.Waterland@Sun.COM 	r = mountOptionPresent(list[nn].fsi_mntOptions, MNTOPT_RO);
21849781SMoriah.Waterland@Sun.COM 	if (r == R_SUCCESS) {
21859781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_PWRT_READONLY,
21869781SMoriah.Waterland@Sun.COM 			rootPath, list[nn].fsi_mntOptions);
21879781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
21889781SMoriah.Waterland@Sun.COM 	}
21899781SMoriah.Waterland@Sun.COM 
21909781SMoriah.Waterland@Sun.COM 	/* target path is writable */
21919781SMoriah.Waterland@Sun.COM 
21929781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_PWRT_IS, rootPath);
21939781SMoriah.Waterland@Sun.COM 
21949781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
21959781SMoriah.Waterland@Sun.COM }
21969781SMoriah.Waterland@Sun.COM 
21979781SMoriah.Waterland@Sun.COM /*
21989781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_alternative_root
21999781SMoriah.Waterland@Sun.COM  * Description:	determine if target is an alternative root
22009781SMoriah.Waterland@Sun.COM  * Scope:	public
22019781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
22029781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
22039781SMoriah.Waterland@Sun.COM  * Returns:	int
22049781SMoriah.Waterland@Sun.COM  *			== 0 - success
22059781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
22069781SMoriah.Waterland@Sun.COM  * Implementation:
22079781SMoriah.Waterland@Sun.COM  *  - success if an initial installation to the install root
22089781SMoriah.Waterland@Sun.COM  *	(an initial install to $PKG_INSTALL_ROOT means that $PKG_INSTALL_ROOT
22099781SMoriah.Waterland@Sun.COM  *	points to an alternative root that is under construction)
22109781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
22119781SMoriah.Waterland@Sun.COM  *  - must not be a boot environment
22129781SMoriah.Waterland@Sun.COM  *  - must not be a diskless client
22139781SMoriah.Waterland@Sun.COM  *  - must not be a mounted miniroot
22149781SMoriah.Waterland@Sun.COM  *  - must not be a netinstall image
22159781SMoriah.Waterland@Sun.COM  *  - must not be a nonglobal zone
22169781SMoriah.Waterland@Sun.COM  *  - must not be a running system
22179781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR must not be "/"
22189781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/var must exist
22199781SMoriah.Waterland@Sun.COM  */
22209781SMoriah.Waterland@Sun.COM 
22219781SMoriah.Waterland@Sun.COM static int
cmd_is_alternative_root(int argc,char ** argv,GLOBALDATA_T * a_gdt)22229781SMoriah.Waterland@Sun.COM cmd_is_alternative_root(int argc, char **argv, GLOBALDATA_T *a_gdt)
22239781SMoriah.Waterland@Sun.COM {
22249781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
22259781SMoriah.Waterland@Sun.COM 	int	c;
22269781SMoriah.Waterland@Sun.COM 	int	r;
22279781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_alternative_root";
22289781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
22299781SMoriah.Waterland@Sun.COM 
22309781SMoriah.Waterland@Sun.COM 	/* process any command line options */
22319781SMoriah.Waterland@Sun.COM 
22329781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
22339781SMoriah.Waterland@Sun.COM 		switch (c) {
22349781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
22359781SMoriah.Waterland@Sun.COM 			break;
22369781SMoriah.Waterland@Sun.COM 		case '?':
22379781SMoriah.Waterland@Sun.COM 		default:
22389781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
22399781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
22409781SMoriah.Waterland@Sun.COM 		}
22419781SMoriah.Waterland@Sun.COM 	}
22429781SMoriah.Waterland@Sun.COM 
22439781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
22449781SMoriah.Waterland@Sun.COM 
22459781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
22469781SMoriah.Waterland@Sun.COM 
22479781SMoriah.Waterland@Sun.COM 		/*
22489781SMoriah.Waterland@Sun.COM 		 * an alternative root cannot be any of the following
22499781SMoriah.Waterland@Sun.COM 		 */
22509781SMoriah.Waterland@Sun.COM 
22519781SMoriah.Waterland@Sun.COM 		/* cannot be a boot_environment */
22529781SMoriah.Waterland@Sun.COM 
22539781SMoriah.Waterland@Sun.COM 		r = cmd_is_boot_environment(argc, argv, a_gdt);
22549781SMoriah.Waterland@Sun.COM 
22559781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless_client */
22569781SMoriah.Waterland@Sun.COM 
22579781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
22589781SMoriah.Waterland@Sun.COM 			r = cmd_is_diskless_client(argc, argv, a_gdt);
22599781SMoriah.Waterland@Sun.COM 		}
22609781SMoriah.Waterland@Sun.COM 
22619781SMoriah.Waterland@Sun.COM 		/* cannot be a mounted_miniroot */
22629781SMoriah.Waterland@Sun.COM 
22639781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
22649781SMoriah.Waterland@Sun.COM 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
22659781SMoriah.Waterland@Sun.COM 		}
22669781SMoriah.Waterland@Sun.COM 
22679781SMoriah.Waterland@Sun.COM 		/* cannot be a netinstall_image */
22689781SMoriah.Waterland@Sun.COM 
22699781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
22709781SMoriah.Waterland@Sun.COM 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
22719781SMoriah.Waterland@Sun.COM 		}
22729781SMoriah.Waterland@Sun.COM 
22739781SMoriah.Waterland@Sun.COM 		/* cannot be a nonglobal_zone */
22749781SMoriah.Waterland@Sun.COM 
22759781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
22769781SMoriah.Waterland@Sun.COM 			r = cmd_is_nonglobal_zone(argc, argv, a_gdt);
22779781SMoriah.Waterland@Sun.COM 		}
22789781SMoriah.Waterland@Sun.COM 
22799781SMoriah.Waterland@Sun.COM 		/* cannot be a running_system */
22809781SMoriah.Waterland@Sun.COM 
22819781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
22829781SMoriah.Waterland@Sun.COM 			r = cmd_is_running_system(argc, argv, a_gdt);
22839781SMoriah.Waterland@Sun.COM 		}
22849781SMoriah.Waterland@Sun.COM 
22859781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
22869781SMoriah.Waterland@Sun.COM 
22879781SMoriah.Waterland@Sun.COM 		recursion--;
22889781SMoriah.Waterland@Sun.COM 
22899781SMoriah.Waterland@Sun.COM 		/* return failure if any of the preceeding are true */
22909781SMoriah.Waterland@Sun.COM 
22919781SMoriah.Waterland@Sun.COM 		switch (r) {
22929781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
22939781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
22949781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
22959781SMoriah.Waterland@Sun.COM 				break;
22969781SMoriah.Waterland@Sun.COM 			case R_USAGE:
22979781SMoriah.Waterland@Sun.COM 			case R_ERROR:
22989781SMoriah.Waterland@Sun.COM 			default:
22999781SMoriah.Waterland@Sun.COM 				return (r);
23009781SMoriah.Waterland@Sun.COM 		}
23019781SMoriah.Waterland@Sun.COM 	}
23029781SMoriah.Waterland@Sun.COM 
23039781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
23049781SMoriah.Waterland@Sun.COM 
23059781SMoriah.Waterland@Sun.COM 	argc -= optind;
23069781SMoriah.Waterland@Sun.COM 	argv += optind;
23079781SMoriah.Waterland@Sun.COM 
23089781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
23099781SMoriah.Waterland@Sun.COM 
23109781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
23119781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
23129781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
23139781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
23149781SMoriah.Waterland@Sun.COM 	}
23159781SMoriah.Waterland@Sun.COM 
23169781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
23179781SMoriah.Waterland@Sun.COM 
23189781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
23199781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
23209781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
23219781SMoriah.Waterland@Sun.COM 		}
23229781SMoriah.Waterland@Sun.COM 	}
23239781SMoriah.Waterland@Sun.COM 
23249781SMoriah.Waterland@Sun.COM 	/* get current root path */
23259781SMoriah.Waterland@Sun.COM 
23269781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
23279781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
23289781SMoriah.Waterland@Sun.COM 		return (r);
23299781SMoriah.Waterland@Sun.COM 	}
23309781SMoriah.Waterland@Sun.COM 
23319781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
23329781SMoriah.Waterland@Sun.COM 
23339781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
23349781SMoriah.Waterland@Sun.COM 
23359781SMoriah.Waterland@Sun.COM 	/* return success if initial installation */
23369781SMoriah.Waterland@Sun.COM 
23379781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
23389781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
23399781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IALR_INITIAL_INSTALL, rootPath);
23409781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
23419781SMoriah.Waterland@Sun.COM 	}
23429781SMoriah.Waterland@Sun.COM 
23439781SMoriah.Waterland@Sun.COM 	/* root path must not be "/" */
23449781SMoriah.Waterland@Sun.COM 
23459781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") == 0) {
23469781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IALR_BAD_ROOTPATH, rootPath, "/");
23479781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
23489781SMoriah.Waterland@Sun.COM 	}
23499781SMoriah.Waterland@Sun.COM 
23509781SMoriah.Waterland@Sun.COM 	/* /var must exist */
23519781SMoriah.Waterland@Sun.COM 
23529781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS,
23539781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/var");
23549781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
23559781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IALR_PATH_DOES_NOT_EXIST,
23569781SMoriah.Waterland@Sun.COM 			rootPath, "/var");
23579781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
23589781SMoriah.Waterland@Sun.COM 	}
23599781SMoriah.Waterland@Sun.COM 
23609781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
23619781SMoriah.Waterland@Sun.COM 
23629781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
23639781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
23649781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be alternative root */
23659781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_IALR_ZONE_INSTALL, rootPath);
23669781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
23679781SMoriah.Waterland@Sun.COM 	}
23689781SMoriah.Waterland@Sun.COM 
23699781SMoriah.Waterland@Sun.COM 	/* target is an alternative root */
23709781SMoriah.Waterland@Sun.COM 
23719781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_IALR_IS, rootPath);
23729781SMoriah.Waterland@Sun.COM 
23739781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
23749781SMoriah.Waterland@Sun.COM }
23759781SMoriah.Waterland@Sun.COM 
23769781SMoriah.Waterland@Sun.COM /*
23779781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_boot_environment
23789781SMoriah.Waterland@Sun.COM  * Description:	determine if target is an alternative, inactive boot environment
23799781SMoriah.Waterland@Sun.COM  * Scope:	public
23809781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
23819781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
23829781SMoriah.Waterland@Sun.COM  * Returns:	int
23839781SMoriah.Waterland@Sun.COM  *			== 0 - success
23849781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
23859781SMoriah.Waterland@Sun.COM  * IMPLEMENTATION:
23869781SMoriah.Waterland@Sun.COM  *  - must not be initial installation to the install root
23879781SMoriah.Waterland@Sun.COM  *  - must not be installation of a zone
23889781SMoriah.Waterland@Sun.COM  *  - must not be a diskless client
23899781SMoriah.Waterland@Sun.COM  *  - must not be a netinstall image
23909781SMoriah.Waterland@Sun.COM  *  - must not be a mounted miniroot
23919781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR must not be "/"
23929781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/etc/lutab must exist
23939781SMoriah.Waterland@Sun.COM  *  - $ROOTDIR/etc/lu must exist and must be a directory
23949781SMoriah.Waterland@Sun.COM  */
23959781SMoriah.Waterland@Sun.COM 
23969781SMoriah.Waterland@Sun.COM static int
cmd_is_boot_environment(int argc,char ** argv,GLOBALDATA_T * a_gdt)23979781SMoriah.Waterland@Sun.COM cmd_is_boot_environment(int argc, char **argv, GLOBALDATA_T *a_gdt)
23989781SMoriah.Waterland@Sun.COM {
23999781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
24009781SMoriah.Waterland@Sun.COM 	int	c;
24019781SMoriah.Waterland@Sun.COM 	int	r;
24029781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_boot_environment";
24039781SMoriah.Waterland@Sun.COM static	int	recursion = 0;
24049781SMoriah.Waterland@Sun.COM 
24059781SMoriah.Waterland@Sun.COM 	/* process any command line options */
24069781SMoriah.Waterland@Sun.COM 
24079781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
24089781SMoriah.Waterland@Sun.COM 		switch (c) {
24099781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
24109781SMoriah.Waterland@Sun.COM 			break;
24119781SMoriah.Waterland@Sun.COM 		case '?':
24129781SMoriah.Waterland@Sun.COM 		default:
24139781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
24149781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
24159781SMoriah.Waterland@Sun.COM 		}
24169781SMoriah.Waterland@Sun.COM 	}
24179781SMoriah.Waterland@Sun.COM 
24189781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
24199781SMoriah.Waterland@Sun.COM 
24209781SMoriah.Waterland@Sun.COM 	if (recursionCheck(&recursion, cmdName) == B_FALSE) {
24219781SMoriah.Waterland@Sun.COM 		/*
24229781SMoriah.Waterland@Sun.COM 		 * a boot environment cannot be any of the following
24239781SMoriah.Waterland@Sun.COM 		 */
24249781SMoriah.Waterland@Sun.COM 
24259781SMoriah.Waterland@Sun.COM 		/* cannot be a diskless client */
24269781SMoriah.Waterland@Sun.COM 
24279781SMoriah.Waterland@Sun.COM 		r = cmd_is_diskless_client(argc, argv, a_gdt);
24289781SMoriah.Waterland@Sun.COM 
24299781SMoriah.Waterland@Sun.COM 		/* cannot be a netinstall_image */
24309781SMoriah.Waterland@Sun.COM 
24319781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
24329781SMoriah.Waterland@Sun.COM 			r = cmd_is_netinstall_image(argc, argv, a_gdt);
24339781SMoriah.Waterland@Sun.COM 		}
24349781SMoriah.Waterland@Sun.COM 
24359781SMoriah.Waterland@Sun.COM 		/* cannot be a mounted_miniroot */
24369781SMoriah.Waterland@Sun.COM 
24379781SMoriah.Waterland@Sun.COM 		if (r != R_SUCCESS) {
24389781SMoriah.Waterland@Sun.COM 			r = cmd_is_mounted_miniroot(argc, argv, a_gdt);
24399781SMoriah.Waterland@Sun.COM 		}
24409781SMoriah.Waterland@Sun.COM 
24419781SMoriah.Waterland@Sun.COM 		/* no need to guard against recursion any more */
24429781SMoriah.Waterland@Sun.COM 
24439781SMoriah.Waterland@Sun.COM 		recursion--;
24449781SMoriah.Waterland@Sun.COM 
24459781SMoriah.Waterland@Sun.COM 		/* return failure if any of the preceeding are true */
24469781SMoriah.Waterland@Sun.COM 
24479781SMoriah.Waterland@Sun.COM 		switch (r) {
24489781SMoriah.Waterland@Sun.COM 			case R_SUCCESS:
24499781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
24509781SMoriah.Waterland@Sun.COM 			case R_FAILURE:
24519781SMoriah.Waterland@Sun.COM 				break;
24529781SMoriah.Waterland@Sun.COM 			case R_USAGE:
24539781SMoriah.Waterland@Sun.COM 			case R_ERROR:
24549781SMoriah.Waterland@Sun.COM 			default:
24559781SMoriah.Waterland@Sun.COM 				return (r);
24569781SMoriah.Waterland@Sun.COM 		}
24579781SMoriah.Waterland@Sun.COM 	}
24589781SMoriah.Waterland@Sun.COM 
24599781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
24609781SMoriah.Waterland@Sun.COM 
24619781SMoriah.Waterland@Sun.COM 	argc -= optind;
24629781SMoriah.Waterland@Sun.COM 	argv += optind;
24639781SMoriah.Waterland@Sun.COM 
24649781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
24659781SMoriah.Waterland@Sun.COM 
24669781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
24679781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
24689781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
24699781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
24709781SMoriah.Waterland@Sun.COM 	}
24719781SMoriah.Waterland@Sun.COM 
24729781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
24739781SMoriah.Waterland@Sun.COM 
24749781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
24759781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
24769781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
24779781SMoriah.Waterland@Sun.COM 		}
24789781SMoriah.Waterland@Sun.COM 	}
24799781SMoriah.Waterland@Sun.COM 
24809781SMoriah.Waterland@Sun.COM 	/* get current root path */
24819781SMoriah.Waterland@Sun.COM 
24829781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
24839781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
24849781SMoriah.Waterland@Sun.COM 		return (r);
24859781SMoriah.Waterland@Sun.COM 	}
24869781SMoriah.Waterland@Sun.COM 
24879781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
24889781SMoriah.Waterland@Sun.COM 
24899781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
24909781SMoriah.Waterland@Sun.COM 
24919781SMoriah.Waterland@Sun.COM 	/* root path must not be "/" */
24929781SMoriah.Waterland@Sun.COM 
24939781SMoriah.Waterland@Sun.COM 	if (strcmp(rootPath, "/") == 0) {
24949781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ROOTPATH, rootPath, "/");
24959781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
24969781SMoriah.Waterland@Sun.COM 	}
24979781SMoriah.Waterland@Sun.COM 
24989781SMoriah.Waterland@Sun.COM 	/* zone name must be global */
24999781SMoriah.Waterland@Sun.COM 
25009781SMoriah.Waterland@Sun.COM 	if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) {
25019781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ZONE, rootPath,
25029781SMoriah.Waterland@Sun.COM 			GLOBAL_ZONENAME);
25039781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
25049781SMoriah.Waterland@Sun.COM 	}
25059781SMoriah.Waterland@Sun.COM 
25069781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/etc/lutab must exist */
25079781SMoriah.Waterland@Sun.COM 
25089781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/lutab");
25099781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
25109781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLUTAB, rootPath,
25119781SMoriah.Waterland@Sun.COM 			"/etc/lutab");
25129781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
25139781SMoriah.Waterland@Sun.COM 	}
25149781SMoriah.Waterland@Sun.COM 
25159781SMoriah.Waterland@Sun.COM 	/* $ROOTDIR/etc/lu must exist */
25169781SMoriah.Waterland@Sun.COM 
25179781SMoriah.Waterland@Sun.COM 	r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY,
25189781SMoriah.Waterland@Sun.COM 		"%s/%s", rootPath, "/etc/lu");
25199781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
25209781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLU, rootPath, "/etc/lu");
25219781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
25229781SMoriah.Waterland@Sun.COM 	}
25239781SMoriah.Waterland@Sun.COM 
25249781SMoriah.Waterland@Sun.COM 	/* must not be initial installation */
25259781SMoriah.Waterland@Sun.COM 
25269781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_initialInstall == B_TRUE) &&
25279781SMoriah.Waterland@Sun.COM 	    (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) {
25289781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_INITIAL_INSTALL, rootPath);
25299781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
25309781SMoriah.Waterland@Sun.COM 	}
25319781SMoriah.Waterland@Sun.COM 
25329781SMoriah.Waterland@Sun.COM 	/* must not be installation of a zone */
25339781SMoriah.Waterland@Sun.COM 
25349781SMoriah.Waterland@Sun.COM 	if ((a_gdt->gd_globalZoneInstall == B_TRUE) ||
25359781SMoriah.Waterland@Sun.COM 	    (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) {
25369781SMoriah.Waterland@Sun.COM 		/* initial zone install: no path can be boot environment */
25379781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_BENV_ZONE_INSTALL, rootPath);
25389781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
25399781SMoriah.Waterland@Sun.COM 	}
25409781SMoriah.Waterland@Sun.COM 
25419781SMoriah.Waterland@Sun.COM 	/* target is a boot environment */
25429781SMoriah.Waterland@Sun.COM 
25439781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_BENV_IS, rootPath);
25449781SMoriah.Waterland@Sun.COM 
25459781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
25469781SMoriah.Waterland@Sun.COM }
25479781SMoriah.Waterland@Sun.COM 
25489781SMoriah.Waterland@Sun.COM /*
25499781SMoriah.Waterland@Sun.COM  * Name:	cmd_is_what
25509781SMoriah.Waterland@Sun.COM  * Description:	determine what the target is
25519781SMoriah.Waterland@Sun.COM  * Scope:	public
25529781SMoriah.Waterland@Sun.COM  * Arguments:	argc,argv:
25539781SMoriah.Waterland@Sun.COM  *		  - optional path to target to test
25549781SMoriah.Waterland@Sun.COM  * Returns:	int
25559781SMoriah.Waterland@Sun.COM  *			== 0 - success
25569781SMoriah.Waterland@Sun.COM  *			!= 0 - failure
25579781SMoriah.Waterland@Sun.COM  */
25589781SMoriah.Waterland@Sun.COM 
25599781SMoriah.Waterland@Sun.COM static int
cmd_is_what(int argc,char ** argv,GLOBALDATA_T * a_gdt)25609781SMoriah.Waterland@Sun.COM cmd_is_what(int argc, char **argv, GLOBALDATA_T *a_gdt)
25619781SMoriah.Waterland@Sun.COM {
25629781SMoriah.Waterland@Sun.COM 	char	*rootPath = NULL;
25639781SMoriah.Waterland@Sun.COM 	int	c;
25649781SMoriah.Waterland@Sun.COM 	int	cur_cmd;
25659781SMoriah.Waterland@Sun.COM 	int	r;
25669781SMoriah.Waterland@Sun.COM static	char	*cmdName = "is_what";
25679781SMoriah.Waterland@Sun.COM 
25689781SMoriah.Waterland@Sun.COM 	/* process any command line options */
25699781SMoriah.Waterland@Sun.COM 
25709781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, ":")) != EOF) {
25719781SMoriah.Waterland@Sun.COM 		switch (c) {
25729781SMoriah.Waterland@Sun.COM 		case '\0':	/* prevent end-of-loop not reached warning */
25739781SMoriah.Waterland@Sun.COM 			break;
25749781SMoriah.Waterland@Sun.COM 		case '?':
25759781SMoriah.Waterland@Sun.COM 		default:
25769781SMoriah.Waterland@Sun.COM 			(void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName);
25779781SMoriah.Waterland@Sun.COM 			return (R_USAGE);
25789781SMoriah.Waterland@Sun.COM 		}
25799781SMoriah.Waterland@Sun.COM 	}
25809781SMoriah.Waterland@Sun.COM 
25819781SMoriah.Waterland@Sun.COM 	/* normalize argc/argv */
25829781SMoriah.Waterland@Sun.COM 
25839781SMoriah.Waterland@Sun.COM 	argc -= optind;
25849781SMoriah.Waterland@Sun.COM 	argv += optind;
25859781SMoriah.Waterland@Sun.COM 
25869781SMoriah.Waterland@Sun.COM 	/* error if more than one argument */
25879781SMoriah.Waterland@Sun.COM 
25889781SMoriah.Waterland@Sun.COM 	if (argc > 1) {
25899781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]);
25909781SMoriah.Waterland@Sun.COM 		(void) usage(MSG_IS_INVALID_OPTION, argv[1]);
25919781SMoriah.Waterland@Sun.COM 		return (R_USAGE);
25929781SMoriah.Waterland@Sun.COM 	}
25939781SMoriah.Waterland@Sun.COM 
25949781SMoriah.Waterland@Sun.COM 	/* process root path if first argument present */
25959781SMoriah.Waterland@Sun.COM 
25969781SMoriah.Waterland@Sun.COM 	if (argc == 1) {
25979781SMoriah.Waterland@Sun.COM 		if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) {
25989781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
25999781SMoriah.Waterland@Sun.COM 		}
26009781SMoriah.Waterland@Sun.COM 	}
26019781SMoriah.Waterland@Sun.COM 
26029781SMoriah.Waterland@Sun.COM 	/* get current root path */
26039781SMoriah.Waterland@Sun.COM 
26049781SMoriah.Waterland@Sun.COM 	r = getRootPath(&rootPath);
26059781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
26069781SMoriah.Waterland@Sun.COM 		return (r);
26079781SMoriah.Waterland@Sun.COM 	}
26089781SMoriah.Waterland@Sun.COM 
26099781SMoriah.Waterland@Sun.COM 	/*
26109781SMoriah.Waterland@Sun.COM 	 * construct the command line for all of the packages
26119781SMoriah.Waterland@Sun.COM 	 */
26129781SMoriah.Waterland@Sun.COM 
26139781SMoriah.Waterland@Sun.COM 	argc = 0;
26149781SMoriah.Waterland@Sun.COM 	argv[argc++] = strdup(get_prog_name());
26159781SMoriah.Waterland@Sun.COM 	argv[argc++] = strdup(rootPath);
26169781SMoriah.Waterland@Sun.COM 
26179781SMoriah.Waterland@Sun.COM 	/* start of command debugging information */
26189781SMoriah.Waterland@Sun.COM 
26199781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ROOTPATH_IS, rootPath);
26209781SMoriah.Waterland@Sun.COM 
26219781SMoriah.Waterland@Sun.COM 	/* search for specified subcommand and execute if found */
26229781SMoriah.Waterland@Sun.COM 
26239781SMoriah.Waterland@Sun.COM 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
26249781SMoriah.Waterland@Sun.COM 		int	result;
26259781SMoriah.Waterland@Sun.COM 
26269781SMoriah.Waterland@Sun.COM 		/* do not recursively call this function */
26279781SMoriah.Waterland@Sun.COM 
26289781SMoriah.Waterland@Sun.COM 		if (cmds[cur_cmd].c_func == cmd_is_what) {
26299781SMoriah.Waterland@Sun.COM 			continue;
26309781SMoriah.Waterland@Sun.COM 		}
26319781SMoriah.Waterland@Sun.COM 
26329781SMoriah.Waterland@Sun.COM 		/* call subcommand with its own argc/argv */
26339781SMoriah.Waterland@Sun.COM 
26349781SMoriah.Waterland@Sun.COM 		result = cmds[cur_cmd].c_func(argc, argv, a_gdt);
26359781SMoriah.Waterland@Sun.COM 
26369781SMoriah.Waterland@Sun.COM 		/* process result code and exit */
26379781SMoriah.Waterland@Sun.COM 
26389781SMoriah.Waterland@Sun.COM 		result = adjustResults(result);
26399781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_INFO, MSG_IS_WHAT_RESULT,
26409781SMoriah.Waterland@Sun.COM 			cmds[cur_cmd].c_name, result);
26419781SMoriah.Waterland@Sun.COM 	}
26429781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
26439781SMoriah.Waterland@Sun.COM }
26449781SMoriah.Waterland@Sun.COM 
26459781SMoriah.Waterland@Sun.COM /*
26469781SMoriah.Waterland@Sun.COM  * *****************************************************************************
26479781SMoriah.Waterland@Sun.COM  * utility support functions
26489781SMoriah.Waterland@Sun.COM  * *****************************************************************************
26499781SMoriah.Waterland@Sun.COM  */
26509781SMoriah.Waterland@Sun.COM 
26519781SMoriah.Waterland@Sun.COM /*
26529781SMoriah.Waterland@Sun.COM  * Name:	getMountOption
26539781SMoriah.Waterland@Sun.COM  * Description:	return next mount option in a string
26549781SMoriah.Waterland@Sun.COM  * Arguments:	p - pointer to string containing mount options
26559781SMoriah.Waterland@Sun.COM  * Output:	none
26569781SMoriah.Waterland@Sun.COM  * Returns:	char * - pointer to next option in string "p"
26579781SMoriah.Waterland@Sun.COM  * Side Effects: advances input "p" and inserts \0 in place of the
26589781SMoriah.Waterland@Sun.COM  *		option separator found.
26599781SMoriah.Waterland@Sun.COM  */
26609781SMoriah.Waterland@Sun.COM 
26619781SMoriah.Waterland@Sun.COM static char *
getMountOption(char ** p)26629781SMoriah.Waterland@Sun.COM getMountOption(char **p)
26639781SMoriah.Waterland@Sun.COM {
26649781SMoriah.Waterland@Sun.COM 	char *cp = *p;
26659781SMoriah.Waterland@Sun.COM 	char *retstr;
26669781SMoriah.Waterland@Sun.COM 
26679781SMoriah.Waterland@Sun.COM 	/* advance past all white space */
26689781SMoriah.Waterland@Sun.COM 
26699781SMoriah.Waterland@Sun.COM 	while (*cp && isspace(*cp))
26709781SMoriah.Waterland@Sun.COM 		cp++;
26719781SMoriah.Waterland@Sun.COM 
26729781SMoriah.Waterland@Sun.COM 	/* remember start of next option */
26739781SMoriah.Waterland@Sun.COM 
26749781SMoriah.Waterland@Sun.COM 	retstr = cp;
26759781SMoriah.Waterland@Sun.COM 
26769781SMoriah.Waterland@Sun.COM 	/* advance to end of string or option separator */
26779781SMoriah.Waterland@Sun.COM 
26789781SMoriah.Waterland@Sun.COM 	while (*cp && *cp != ',')
26799781SMoriah.Waterland@Sun.COM 		cp++;
26809781SMoriah.Waterland@Sun.COM 
26819781SMoriah.Waterland@Sun.COM 	/* replace separator with '\0' if not at end of string */
26829781SMoriah.Waterland@Sun.COM 	if (*cp) {
26839781SMoriah.Waterland@Sun.COM 		*cp = '\0';
26849781SMoriah.Waterland@Sun.COM 		cp++;
26859781SMoriah.Waterland@Sun.COM 	}
26869781SMoriah.Waterland@Sun.COM 
26879781SMoriah.Waterland@Sun.COM 	/* reset caller's pointer and return pointer to option */
26889781SMoriah.Waterland@Sun.COM 
26899781SMoriah.Waterland@Sun.COM 	*p = cp;
26909781SMoriah.Waterland@Sun.COM 	return (retstr);
26919781SMoriah.Waterland@Sun.COM }
26929781SMoriah.Waterland@Sun.COM 
26939781SMoriah.Waterland@Sun.COM /*
26949781SMoriah.Waterland@Sun.COM  * Name:	mountOptionPresent
26959781SMoriah.Waterland@Sun.COM  * Description:	determine if specified mount option is present in list
26969781SMoriah.Waterland@Sun.COM  *		of mount point options
26979781SMoriah.Waterland@Sun.COM  * Arguments:	a_mntOptions - pointer to string containing list of mount
26989781SMoriah.Waterland@Sun.COM  *			point options to search
26999781SMoriah.Waterland@Sun.COM  *		a_opt - pointer to string containing option to search for
27009781SMoriah.Waterland@Sun.COM  * Output:	none
27019781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - option is present in list of mount point options
27029781SMoriah.Waterland@Sun.COM  *		R_FAILURE - options is not present
27039781SMoriah.Waterland@Sun.COM  *		R_ERROR - unable to determine if option is present or not
27049781SMoriah.Waterland@Sun.COM  */
27059781SMoriah.Waterland@Sun.COM 
27069781SMoriah.Waterland@Sun.COM static int
mountOptionPresent(char * a_mntOptions,char * a_opt)27079781SMoriah.Waterland@Sun.COM mountOptionPresent(char *a_mntOptions, char *a_opt)
27089781SMoriah.Waterland@Sun.COM {
27099781SMoriah.Waterland@Sun.COM 	char tmpopts[MNT_LINE_MAX];
27109781SMoriah.Waterland@Sun.COM 	char *f, *opts = tmpopts;
27119781SMoriah.Waterland@Sun.COM 
27129781SMoriah.Waterland@Sun.COM 	/* return false if no mount options present */
27139781SMoriah.Waterland@Sun.COM 
27149781SMoriah.Waterland@Sun.COM 	if ((a_opt == NULL) || (*a_opt == '\0')) {
27159781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
27169781SMoriah.Waterland@Sun.COM 	}
27179781SMoriah.Waterland@Sun.COM 
27189781SMoriah.Waterland@Sun.COM 	/* return not present if no list of options to search */
27199781SMoriah.Waterland@Sun.COM 
27209781SMoriah.Waterland@Sun.COM 	if (a_mntOptions == NULL) {
27219781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
27229781SMoriah.Waterland@Sun.COM 	}
27239781SMoriah.Waterland@Sun.COM 
27249781SMoriah.Waterland@Sun.COM 	/* return not present if list of options to search is empty */
27259781SMoriah.Waterland@Sun.COM 
27269781SMoriah.Waterland@Sun.COM 	if (*a_mntOptions == '\0') {
27279781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
27289781SMoriah.Waterland@Sun.COM 	}
27299781SMoriah.Waterland@Sun.COM 
27309781SMoriah.Waterland@Sun.COM 	/* make local copy of option list to search */
27319781SMoriah.Waterland@Sun.COM 
27329781SMoriah.Waterland@Sun.COM 	(void) strcpy(opts, a_mntOptions);
27339781SMoriah.Waterland@Sun.COM 
27349781SMoriah.Waterland@Sun.COM 	/* scan each option looking for the specified option */
27359781SMoriah.Waterland@Sun.COM 
27369781SMoriah.Waterland@Sun.COM 	f = getMountOption(&opts);
27379781SMoriah.Waterland@Sun.COM 	for (; *f; f = getMountOption(&opts)) {
27389781SMoriah.Waterland@Sun.COM 		/* return success if option matches target */
27399781SMoriah.Waterland@Sun.COM 		if (strncmp(a_opt, f, strlen(a_opt)) == 0) {
27409781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
27419781SMoriah.Waterland@Sun.COM 		}
27429781SMoriah.Waterland@Sun.COM 	}
27439781SMoriah.Waterland@Sun.COM 
27449781SMoriah.Waterland@Sun.COM 	/* option not found */
27459781SMoriah.Waterland@Sun.COM 
27469781SMoriah.Waterland@Sun.COM 	return (R_FAILURE);
27479781SMoriah.Waterland@Sun.COM }
27489781SMoriah.Waterland@Sun.COM 
27499781SMoriah.Waterland@Sun.COM /*
27509781SMoriah.Waterland@Sun.COM  * Name:	sortedInsert
27519781SMoriah.Waterland@Sun.COM  * Description:	perform an alphabetical sorted insert into a list
27529781SMoriah.Waterland@Sun.COM  * Arguments:	r_list - pointer to list to insert next entry into
27539781SMoriah.Waterland@Sun.COM  *		a_listSize - pointer to current list size
27549781SMoriah.Waterland@Sun.COM  *		a_mntPoint - mount point to insert (is sort key)
27559781SMoriah.Waterland@Sun.COM  *		a_fsType - file system type for mount point
27569781SMoriah.Waterland@Sun.COM  *		a_mntOptions - file syste mount options for mount point
27579781SMoriah.Waterland@Sun.COM  * Output:	None
27589781SMoriah.Waterland@Sun.COM  * Returns:	None
27599781SMoriah.Waterland@Sun.COM  */
27609781SMoriah.Waterland@Sun.COM 
27619781SMoriah.Waterland@Sun.COM static void
sortedInsert(FSI_T ** r_list,long * a_listSize,char * a_mntPoint,char * a_fsType,char * a_mntOptions)27629781SMoriah.Waterland@Sun.COM sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint,
27639781SMoriah.Waterland@Sun.COM 	char *a_fsType, char *a_mntOptions)
27649781SMoriah.Waterland@Sun.COM {
27659781SMoriah.Waterland@Sun.COM 	int	listSize;
27669781SMoriah.Waterland@Sun.COM 	FSI_T	*list;
27679781SMoriah.Waterland@Sun.COM 	int	n;
27689781SMoriah.Waterland@Sun.COM 
27699781SMoriah.Waterland@Sun.COM 	/* entry assertions */
27709781SMoriah.Waterland@Sun.COM 
27719781SMoriah.Waterland@Sun.COM 	assert(a_listSize != (long *)NULL);
27729781SMoriah.Waterland@Sun.COM 	assert(a_mntPoint != NULL);
27739781SMoriah.Waterland@Sun.COM 	assert(a_fsType != NULL);
27749781SMoriah.Waterland@Sun.COM 	assert(a_mntOptions != NULL);
27759781SMoriah.Waterland@Sun.COM 
27769781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
27779781SMoriah.Waterland@Sun.COM 
27789781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_SINS_ENTRY, a_mntPoint, a_fsType, a_mntOptions);
27799781SMoriah.Waterland@Sun.COM 
27809781SMoriah.Waterland@Sun.COM 	/* localize references to the list and list size */
27819781SMoriah.Waterland@Sun.COM 
27829781SMoriah.Waterland@Sun.COM 	listSize = *a_listSize;
27839781SMoriah.Waterland@Sun.COM 	list = *r_list;
27849781SMoriah.Waterland@Sun.COM 
27859781SMoriah.Waterland@Sun.COM 	/*
27869781SMoriah.Waterland@Sun.COM 	 * if list empty insert this entry as the first one in the list
27879781SMoriah.Waterland@Sun.COM 	 */
27889781SMoriah.Waterland@Sun.COM 
27899781SMoriah.Waterland@Sun.COM 	if (listSize == 0) {
27909781SMoriah.Waterland@Sun.COM 		/* allocate new entry for list */
27919781SMoriah.Waterland@Sun.COM 		listSize++;
27929781SMoriah.Waterland@Sun.COM 		list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1));
27939781SMoriah.Waterland@Sun.COM 
27949781SMoriah.Waterland@Sun.COM 		/* first entry is data passed to this function */
27959781SMoriah.Waterland@Sun.COM 		list[0].fsi_mntPoint = strdup(a_mntPoint);
27969781SMoriah.Waterland@Sun.COM 		list[0].fsi_fsType = strdup(a_fsType);
27979781SMoriah.Waterland@Sun.COM 		list[0].fsi_mntOptions = strdup(a_mntOptions);
27989781SMoriah.Waterland@Sun.COM 
27999781SMoriah.Waterland@Sun.COM 		/* second entry is all NULL - end of entry marker */
28009781SMoriah.Waterland@Sun.COM 		list[1].fsi_mntPoint = NULL;
28019781SMoriah.Waterland@Sun.COM 		list[1].fsi_fsType = NULL;
28029781SMoriah.Waterland@Sun.COM 		list[1].fsi_mntOptions = NULL;
28039781SMoriah.Waterland@Sun.COM 
28049781SMoriah.Waterland@Sun.COM 		/* restore list and list size references to caller */
28059781SMoriah.Waterland@Sun.COM 		*a_listSize = listSize;
28069781SMoriah.Waterland@Sun.COM 		*r_list = list;
28079781SMoriah.Waterland@Sun.COM 
28089781SMoriah.Waterland@Sun.COM 		return;
28099781SMoriah.Waterland@Sun.COM 	}
28109781SMoriah.Waterland@Sun.COM 
28119781SMoriah.Waterland@Sun.COM 	/*
28129781SMoriah.Waterland@Sun.COM 	 * list not empty - scan looking for largest match
28139781SMoriah.Waterland@Sun.COM 	 */
28149781SMoriah.Waterland@Sun.COM 
28159781SMoriah.Waterland@Sun.COM 	for (n = 0; n < listSize; n++) {
28169781SMoriah.Waterland@Sun.COM 		int	c;
28179781SMoriah.Waterland@Sun.COM 
28189781SMoriah.Waterland@Sun.COM 		/* compare target with current list entry */
28199781SMoriah.Waterland@Sun.COM 
28209781SMoriah.Waterland@Sun.COM 		c = strcmp(list[n].fsi_mntPoint, a_mntPoint);
28219781SMoriah.Waterland@Sun.COM 
28229781SMoriah.Waterland@Sun.COM 		if (c == 0) {
28239781SMoriah.Waterland@Sun.COM 			char	*me;
28249781SMoriah.Waterland@Sun.COM 			long	len;
28259781SMoriah.Waterland@Sun.COM 
28269781SMoriah.Waterland@Sun.COM 			/* entry already in list -- merge entries */
28279781SMoriah.Waterland@Sun.COM 
28289781SMoriah.Waterland@Sun.COM 			len = strlen(list[n].fsi_mntOptions) +
28299781SMoriah.Waterland@Sun.COM 				strlen(a_mntOptions) + 2;
28309781SMoriah.Waterland@Sun.COM 			me = (char *)calloc(1, len);
28319781SMoriah.Waterland@Sun.COM 
28329781SMoriah.Waterland@Sun.COM 			/* merge two mount options lists into one */
28339781SMoriah.Waterland@Sun.COM 
28349781SMoriah.Waterland@Sun.COM 			(void) strlcat(me, list[n].fsi_mntOptions, len);
28359781SMoriah.Waterland@Sun.COM 			(void) strlcat(me, ",", len);
28369781SMoriah.Waterland@Sun.COM 			(void) strlcat(me, a_mntOptions, len);
28379781SMoriah.Waterland@Sun.COM 
28389781SMoriah.Waterland@Sun.COM 			/* free old list, replace with merged one */
28399781SMoriah.Waterland@Sun.COM 
28409781SMoriah.Waterland@Sun.COM 			free(list[n].fsi_mntOptions);
28419781SMoriah.Waterland@Sun.COM 			list[n].fsi_mntOptions = me;
28429781SMoriah.Waterland@Sun.COM 
28439781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SORTEDINS_SKIPPED,
28449781SMoriah.Waterland@Sun.COM 				n, list[n].fsi_mntPoint, a_fsType,
28459781SMoriah.Waterland@Sun.COM 				list[n].fsi_fsType, a_mntOptions,
28469781SMoriah.Waterland@Sun.COM 				list[n].fsi_mntOptions);
28479781SMoriah.Waterland@Sun.COM 
28489781SMoriah.Waterland@Sun.COM 			continue;
28499781SMoriah.Waterland@Sun.COM 		} else if (c < 0) {
28509781SMoriah.Waterland@Sun.COM 			/* entry before this one - skip */
28519781SMoriah.Waterland@Sun.COM 			continue;
28529781SMoriah.Waterland@Sun.COM 		}
28539781SMoriah.Waterland@Sun.COM 
28549781SMoriah.Waterland@Sun.COM 		/*
28559781SMoriah.Waterland@Sun.COM 		 * entry after this one - insert new entry
28569781SMoriah.Waterland@Sun.COM 		 */
28579781SMoriah.Waterland@Sun.COM 
28589781SMoriah.Waterland@Sun.COM 		/* allocate one more entry and make space for new entry */
28599781SMoriah.Waterland@Sun.COM 		listSize++;
28609781SMoriah.Waterland@Sun.COM 		list = (FSI_T *)realloc(list,
28619781SMoriah.Waterland@Sun.COM 			sizeof (FSI_T)*(listSize+1));
28629781SMoriah.Waterland@Sun.COM 		(void) memmove(&(list[n+1]), &(list[n]),
28639781SMoriah.Waterland@Sun.COM 			sizeof (FSI_T)*(listSize-n));
28649781SMoriah.Waterland@Sun.COM 
28659781SMoriah.Waterland@Sun.COM 		/* insert this entry into list */
28669781SMoriah.Waterland@Sun.COM 		list[n].fsi_mntPoint = strdup(a_mntPoint);
28679781SMoriah.Waterland@Sun.COM 		list[n].fsi_fsType = strdup(a_fsType);
28689781SMoriah.Waterland@Sun.COM 		list[n].fsi_mntOptions = strdup(a_mntOptions);
28699781SMoriah.Waterland@Sun.COM 
28709781SMoriah.Waterland@Sun.COM 		/* restore list and list size references to caller */
28719781SMoriah.Waterland@Sun.COM 		*a_listSize = listSize;
28729781SMoriah.Waterland@Sun.COM 		*r_list = list;
28739781SMoriah.Waterland@Sun.COM 
28749781SMoriah.Waterland@Sun.COM 		return;
28759781SMoriah.Waterland@Sun.COM 	}
28769781SMoriah.Waterland@Sun.COM 
28779781SMoriah.Waterland@Sun.COM 	/*
28789781SMoriah.Waterland@Sun.COM 	 * all entries are before this one - append to end of list
28799781SMoriah.Waterland@Sun.COM 	 */
28809781SMoriah.Waterland@Sun.COM 
28819781SMoriah.Waterland@Sun.COM 	/* allocate new entry at end of list */
28829781SMoriah.Waterland@Sun.COM 	listSize++;
28839781SMoriah.Waterland@Sun.COM 	list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1));
28849781SMoriah.Waterland@Sun.COM 
28859781SMoriah.Waterland@Sun.COM 	/* append this entry to the end of the list */
28869781SMoriah.Waterland@Sun.COM 	list[listSize-1].fsi_mntPoint = strdup(a_mntPoint);
28879781SMoriah.Waterland@Sun.COM 	list[listSize-1].fsi_fsType = strdup(a_fsType);
28889781SMoriah.Waterland@Sun.COM 	list[listSize-1].fsi_mntOptions = strdup(a_mntOptions);
28899781SMoriah.Waterland@Sun.COM 
28909781SMoriah.Waterland@Sun.COM 	/* restore list and list size references to caller */
28919781SMoriah.Waterland@Sun.COM 	*a_listSize = listSize;
28929781SMoriah.Waterland@Sun.COM 	*r_list = list;
28939781SMoriah.Waterland@Sun.COM }
28949781SMoriah.Waterland@Sun.COM 
28959781SMoriah.Waterland@Sun.COM /*
28969781SMoriah.Waterland@Sun.COM  * Name:	calculateFileSystemConfig
28979781SMoriah.Waterland@Sun.COM  * Description:	generate sorted list of all mounted file systems
28989781SMoriah.Waterland@Sun.COM  * Arguments:	a_gdt - global data structure to place sorted entries into
28999781SMoriah.Waterland@Sun.COM  * Output:	None
29009781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - successfully generated mounted file systems list
29019781SMoriah.Waterland@Sun.COM  *		R_FAILURE - options is not present
29029781SMoriah.Waterland@Sun.COM  *		R_ERROR - unable to determine if option is present or not
29039781SMoriah.Waterland@Sun.COM  */
29049781SMoriah.Waterland@Sun.COM 
29059781SMoriah.Waterland@Sun.COM static int
calculateFileSystemConfig(GLOBALDATA_T * a_gdt)29069781SMoriah.Waterland@Sun.COM calculateFileSystemConfig(GLOBALDATA_T *a_gdt)
29079781SMoriah.Waterland@Sun.COM {
29089781SMoriah.Waterland@Sun.COM 	FILE		*fp;
29099781SMoriah.Waterland@Sun.COM 	struct mnttab	mntbuf;
29109781SMoriah.Waterland@Sun.COM 	FSI_T		*list;
29119781SMoriah.Waterland@Sun.COM 	long		listSize;
29129781SMoriah.Waterland@Sun.COM 
29139781SMoriah.Waterland@Sun.COM 	/* entry assetions */
29149781SMoriah.Waterland@Sun.COM 
29159781SMoriah.Waterland@Sun.COM 	assert(a_gdt != (GLOBALDATA_T *)NULL);
29169781SMoriah.Waterland@Sun.COM 
29179781SMoriah.Waterland@Sun.COM 	/* allocate a list that has one termination entry */
29189781SMoriah.Waterland@Sun.COM 
29199781SMoriah.Waterland@Sun.COM 	list = (FSI_T *)calloc(1, sizeof (FSI_T));
29209781SMoriah.Waterland@Sun.COM 	list[0].fsi_mntPoint = NULL;
29219781SMoriah.Waterland@Sun.COM 	list[0].fsi_fsType = NULL;
29229781SMoriah.Waterland@Sun.COM 	list[0].fsi_mntOptions = NULL;
29239781SMoriah.Waterland@Sun.COM 	listSize = 0;
29249781SMoriah.Waterland@Sun.COM 
29259781SMoriah.Waterland@Sun.COM 	/* open the mount table for reading */
29269781SMoriah.Waterland@Sun.COM 
29279781SMoriah.Waterland@Sun.COM 	fp = fopen(MNTTAB, "r");
29289781SMoriah.Waterland@Sun.COM 	if (fp == (FILE *)NULL) {
29299781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
29309781SMoriah.Waterland@Sun.COM 	}
29319781SMoriah.Waterland@Sun.COM 
29329781SMoriah.Waterland@Sun.COM 	/* debugging info */
29339781SMoriah.Waterland@Sun.COM 
29349781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CALCSCFG_MOUNTED);
29359781SMoriah.Waterland@Sun.COM 
29369781SMoriah.Waterland@Sun.COM 	/* go through all the specials looking for the device */
29379781SMoriah.Waterland@Sun.COM 
29389781SMoriah.Waterland@Sun.COM 	while (getmntent(fp, &mntbuf) == 0) {
29399781SMoriah.Waterland@Sun.COM 		if (mntbuf.mnt_mountp[0] == '/') {
29409781SMoriah.Waterland@Sun.COM 			sortedInsert(&list, &listSize,
29419781SMoriah.Waterland@Sun.COM 			strdup(mntbuf.mnt_mountp),
29429781SMoriah.Waterland@Sun.COM 			strdup(mntbuf.mnt_fstype),
29439781SMoriah.Waterland@Sun.COM 			strdup(mntbuf.mnt_mntopts ? mntbuf.mnt_mntopts : ""));
29449781SMoriah.Waterland@Sun.COM 		}
29459781SMoriah.Waterland@Sun.COM 
29469781SMoriah.Waterland@Sun.COM 		/*
29479781SMoriah.Waterland@Sun.COM 		 * Set flag if we are in a non-global zone and it is in
29489781SMoriah.Waterland@Sun.COM 		 * the mounted state.
29499781SMoriah.Waterland@Sun.COM 		 */
29509781SMoriah.Waterland@Sun.COM 
29519781SMoriah.Waterland@Sun.COM 		if (strcmp(mntbuf.mnt_mountp, "/a") == 0 &&
29529781SMoriah.Waterland@Sun.COM 			strcmp(mntbuf.mnt_special, "/a") == 0 &&
29539781SMoriah.Waterland@Sun.COM 			strcmp(mntbuf.mnt_fstype, "lofs") == 0) {
29549781SMoriah.Waterland@Sun.COM 			a_gdt->inMountedState = B_TRUE;
29559781SMoriah.Waterland@Sun.COM 		}
29569781SMoriah.Waterland@Sun.COM 
29579781SMoriah.Waterland@Sun.COM 	}
29589781SMoriah.Waterland@Sun.COM 
29599781SMoriah.Waterland@Sun.COM 	/* close mount table file */
29609781SMoriah.Waterland@Sun.COM 
29619781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
29629781SMoriah.Waterland@Sun.COM 
29639781SMoriah.Waterland@Sun.COM 	/* store list pointers in global data structure */
29649781SMoriah.Waterland@Sun.COM 
29659781SMoriah.Waterland@Sun.COM 	a_gdt->gd_fileSystemConfig = list;
29669781SMoriah.Waterland@Sun.COM 	a_gdt->gd_fileSystemConfigLen = listSize;
29679781SMoriah.Waterland@Sun.COM 
29689781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
29699781SMoriah.Waterland@Sun.COM }
29709781SMoriah.Waterland@Sun.COM 
29719781SMoriah.Waterland@Sun.COM /*
29729781SMoriah.Waterland@Sun.COM  * Name: 	adjustResults
29739781SMoriah.Waterland@Sun.COM  * Description:	adjust output result code before existing
29749781SMoriah.Waterland@Sun.COM  * Arguments:	a_result - result code to adjust
29759781SMoriah.Waterland@Sun.COM  * Returns:	int - adjusted result code
29769781SMoriah.Waterland@Sun.COM  */
29779781SMoriah.Waterland@Sun.COM 
29789781SMoriah.Waterland@Sun.COM static int
adjustResults(int a_result)29799781SMoriah.Waterland@Sun.COM adjustResults(int a_result)
29809781SMoriah.Waterland@Sun.COM {
29819781SMoriah.Waterland@Sun.COM 	boolean_t	negate = getNegateResults();
29829781SMoriah.Waterland@Sun.COM 	int		realResult;
29839781SMoriah.Waterland@Sun.COM 
29849781SMoriah.Waterland@Sun.COM 	/* adjust code as appropriate */
29859781SMoriah.Waterland@Sun.COM 
29869781SMoriah.Waterland@Sun.COM 	switch (a_result) {
29879781SMoriah.Waterland@Sun.COM 	case R_SUCCESS:		/* condition satisfied */
29889781SMoriah.Waterland@Sun.COM 		realResult = ((negate == B_TRUE) ? 1 : 0);
29899781SMoriah.Waterland@Sun.COM 		break;
29909781SMoriah.Waterland@Sun.COM 	case R_FAILURE:		/* condition not satisfied */
29919781SMoriah.Waterland@Sun.COM 		realResult = ((negate == B_TRUE) ? 0 : 1);
29929781SMoriah.Waterland@Sun.COM 		break;
29939781SMoriah.Waterland@Sun.COM 	case R_USAGE:		/* usage errors */
29949781SMoriah.Waterland@Sun.COM 		realResult = 2;
29959781SMoriah.Waterland@Sun.COM 		break;
29969781SMoriah.Waterland@Sun.COM 	case R_ERROR:		/* condition could not be determined */
29979781SMoriah.Waterland@Sun.COM 	default:
29989781SMoriah.Waterland@Sun.COM 		realResult = 3;
29999781SMoriah.Waterland@Sun.COM 		break;
30009781SMoriah.Waterland@Sun.COM 	}
30019781SMoriah.Waterland@Sun.COM 
30029781SMoriah.Waterland@Sun.COM 	/* debugging output */
30039781SMoriah.Waterland@Sun.COM 
30049781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_ADJUST_RESULTS, a_result, negate,
30059781SMoriah.Waterland@Sun.COM 		realResult);
30069781SMoriah.Waterland@Sun.COM 
30079781SMoriah.Waterland@Sun.COM 	/* return results */
30089781SMoriah.Waterland@Sun.COM 
30099781SMoriah.Waterland@Sun.COM 	return (realResult);
30109781SMoriah.Waterland@Sun.COM }
30119781SMoriah.Waterland@Sun.COM 
30129781SMoriah.Waterland@Sun.COM /*
30139781SMoriah.Waterland@Sun.COM  * Name:        setCmdLinePath
30149781SMoriah.Waterland@Sun.COM  * Description:	set global command line path
30159781SMoriah.Waterland@Sun.COM  * Arguments:   path - path to set from the command line
30169781SMoriah.Waterland@Sun.COM  *              args - command line args
30179781SMoriah.Waterland@Sun.COM  *              num_args - number of command line args
30189781SMoriah.Waterland@Sun.COM  * Returns:     R_SUCCESS - root path successfully set
30199781SMoriah.Waterland@Sun.COM  *              R_FAILURE - root path could not be set
30209781SMoriah.Waterland@Sun.COM  *              R_ERROR - fatal error attempting to set root path
30219781SMoriah.Waterland@Sun.COM  */
30229781SMoriah.Waterland@Sun.COM 
30239781SMoriah.Waterland@Sun.COM static void
setCmdLinePath(char ** path,char ** args,int num_args)30249781SMoriah.Waterland@Sun.COM setCmdLinePath(char **path, char **args, int num_args)
30259781SMoriah.Waterland@Sun.COM {
30269781SMoriah.Waterland@Sun.COM 	char   rp[PATH_MAX] = { '\0' };
30279781SMoriah.Waterland@Sun.COM 	struct stat statbuf;
30289781SMoriah.Waterland@Sun.COM 
30299781SMoriah.Waterland@Sun.COM 	if (*path != NULL) {
30309781SMoriah.Waterland@Sun.COM 		return;
30319781SMoriah.Waterland@Sun.COM 	}
30329781SMoriah.Waterland@Sun.COM 
30339781SMoriah.Waterland@Sun.COM 	/*
30349781SMoriah.Waterland@Sun.COM 	 * If a path "pkgcond is_global_zone [path]" is provided on the
30359781SMoriah.Waterland@Sun.COM 	 * command line it must be the last argument.
30369781SMoriah.Waterland@Sun.COM 	 */
30379781SMoriah.Waterland@Sun.COM 
30389781SMoriah.Waterland@Sun.COM 	if (realpath(args[num_args - 1], rp) != NULL) {
30399781SMoriah.Waterland@Sun.COM 		if (stat(rp, &statbuf) == 0) {
30409781SMoriah.Waterland@Sun.COM 			/* make sure the target is a directory */
30419781SMoriah.Waterland@Sun.COM 			if ((statbuf.st_mode & S_IFDIR)) {
30429781SMoriah.Waterland@Sun.COM 				*path = strdup(rp);
30439781SMoriah.Waterland@Sun.COM 			} else {
30449781SMoriah.Waterland@Sun.COM 				*path = NULL;
30459781SMoriah.Waterland@Sun.COM 			}
30469781SMoriah.Waterland@Sun.COM 		}
30479781SMoriah.Waterland@Sun.COM 	}
30489781SMoriah.Waterland@Sun.COM }
30499781SMoriah.Waterland@Sun.COM 
30509781SMoriah.Waterland@Sun.COM /*
30519781SMoriah.Waterland@Sun.COM  * Name:	setRootPath
30529781SMoriah.Waterland@Sun.COM  * Description:	set global root path returned by getRootPath
30539781SMoriah.Waterland@Sun.COM  * Arguments:	a_path - root path to set
30549781SMoriah.Waterland@Sun.COM  *		a_mustExist - B_TRUE if path must exist (else error)
30559781SMoriah.Waterland@Sun.COM  *			- B_FALSE if path may not exist
30569781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - root path successfully set
30579781SMoriah.Waterland@Sun.COM  *		R_FAILURE - root path could not be set
30589781SMoriah.Waterland@Sun.COM  *		R_ERROR - fatal error attempting to set root path
30599781SMoriah.Waterland@Sun.COM  */
30609781SMoriah.Waterland@Sun.COM 
30619781SMoriah.Waterland@Sun.COM static int
setRootPath(char * a_path,char * a_envVar,boolean_t a_mustExist)30629781SMoriah.Waterland@Sun.COM setRootPath(char *a_path, char *a_envVar, boolean_t a_mustExist)
30639781SMoriah.Waterland@Sun.COM {
30649781SMoriah.Waterland@Sun.COM 	char		rp[PATH_MAX] = { '\0' };
30659781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
30669781SMoriah.Waterland@Sun.COM 
30679781SMoriah.Waterland@Sun.COM 	/* if no data then issue warning and return success */
30689781SMoriah.Waterland@Sun.COM 
30699781SMoriah.Waterland@Sun.COM 	if ((a_path == NULL) || (*a_path == '\0')) {
30709781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_NO_DEFAULT_ROOT_PATH_SET);
30719781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
30729781SMoriah.Waterland@Sun.COM 	}
30739781SMoriah.Waterland@Sun.COM 
30749781SMoriah.Waterland@Sun.COM 	/* path present - resolve to absolute path */
30759781SMoriah.Waterland@Sun.COM 
30769781SMoriah.Waterland@Sun.COM 	if (realpath(a_path, rp) == NULL) {
30779781SMoriah.Waterland@Sun.COM 		if (a_mustExist == B_TRUE) {
30789781SMoriah.Waterland@Sun.COM 			/* must exist ... error */
30799781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID,
30809781SMoriah.Waterland@Sun.COM 				a_path, strerror(errno));
30819781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
30829781SMoriah.Waterland@Sun.COM 		} else {
30839781SMoriah.Waterland@Sun.COM 			/* may not exist - use path as specified */
30849781SMoriah.Waterland@Sun.COM 			(void) strcpy(rp, a_path);
30859781SMoriah.Waterland@Sun.COM 		}
30869781SMoriah.Waterland@Sun.COM 	}
30879781SMoriah.Waterland@Sun.COM 
30889781SMoriah.Waterland@Sun.COM 	/* debugging output */
30899781SMoriah.Waterland@Sun.COM 
30909781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DEFAULT_ROOT_PATH_SET, rp, a_envVar ? a_envVar : "");
30919781SMoriah.Waterland@Sun.COM 
30929781SMoriah.Waterland@Sun.COM 	/* validate path existence if it must exist */
30939781SMoriah.Waterland@Sun.COM 
30949781SMoriah.Waterland@Sun.COM 	if (a_mustExist == B_TRUE) {
30959781SMoriah.Waterland@Sun.COM 
30969781SMoriah.Waterland@Sun.COM 		/* get node status */
30979781SMoriah.Waterland@Sun.COM 
30989781SMoriah.Waterland@Sun.COM 		if (stat(rp, &statbuf) != 0) {
30999781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID,
31009781SMoriah.Waterland@Sun.COM 				rp, strerror(errno));
31019781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
31029781SMoriah.Waterland@Sun.COM 		}
31039781SMoriah.Waterland@Sun.COM 
31049781SMoriah.Waterland@Sun.COM 		/* make sure the target is a directory */
31059781SMoriah.Waterland@Sun.COM 
31069781SMoriah.Waterland@Sun.COM 		if (!(statbuf.st_mode & S_IFDIR)) {
31079781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_NOT_DIR, rp);
31089781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
31099781SMoriah.Waterland@Sun.COM 		}
31109781SMoriah.Waterland@Sun.COM 	}
31119781SMoriah.Waterland@Sun.COM 
31129781SMoriah.Waterland@Sun.COM 	/* target exists and is a directory - set */
31139781SMoriah.Waterland@Sun.COM 
31149781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_SET_ROOT_PATH_TO, rp);
31159781SMoriah.Waterland@Sun.COM 
31169781SMoriah.Waterland@Sun.COM 	/* store copy of resolved root path */
31179781SMoriah.Waterland@Sun.COM 
31189781SMoriah.Waterland@Sun.COM 	_rootPath = strdup(rp);
31199781SMoriah.Waterland@Sun.COM 
31209781SMoriah.Waterland@Sun.COM 	/* success! */
31219781SMoriah.Waterland@Sun.COM 
31229781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
31239781SMoriah.Waterland@Sun.COM }
31249781SMoriah.Waterland@Sun.COM 
31259781SMoriah.Waterland@Sun.COM /*
31269781SMoriah.Waterland@Sun.COM  * Name:	testPath
31279781SMoriah.Waterland@Sun.COM  * Description:	determine if a path meets the specified conditions
31289781SMoriah.Waterland@Sun.COM  * Arguments:	a_tt - conditions to test path against
31299781SMoriah.Waterland@Sun.COM  * 		a_format - format to use to generate path
31309781SMoriah.Waterland@Sun.COM  *		arguments following a_format - as needed for a_format
31319781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - the path meets all of the specified conditions
31329781SMoriah.Waterland@Sun.COM  *		R_FAILURE - the path does not meet all of the conditions
31339781SMoriah.Waterland@Sun.COM  *		R_ERROR - error attempting to test path
31349781SMoriah.Waterland@Sun.COM  */
31359781SMoriah.Waterland@Sun.COM 
31369781SMoriah.Waterland@Sun.COM /*PRINTFLIKE2*/
31379781SMoriah.Waterland@Sun.COM static int
testPath(TEST_TYPES a_tt,char * a_format,...)31389781SMoriah.Waterland@Sun.COM testPath(TEST_TYPES a_tt, char *a_format, ...)
31399781SMoriah.Waterland@Sun.COM {
31409781SMoriah.Waterland@Sun.COM 	char		*mbPath;	/* copy for the path to be returned */
31419781SMoriah.Waterland@Sun.COM 	char		bfr[1];
31429781SMoriah.Waterland@Sun.COM 	int		r;
31439781SMoriah.Waterland@Sun.COM 	size_t		vres = 0;
31449781SMoriah.Waterland@Sun.COM 	struct stat	statbuf;
31459781SMoriah.Waterland@Sun.COM 	va_list		ap;
31469781SMoriah.Waterland@Sun.COM 	int		fd;
31479781SMoriah.Waterland@Sun.COM 
31489781SMoriah.Waterland@Sun.COM 	/* entry assertions */
31499781SMoriah.Waterland@Sun.COM 
31509781SMoriah.Waterland@Sun.COM 	assert(a_format != NULL);
31519781SMoriah.Waterland@Sun.COM 	assert(*a_format != '\0');
31529781SMoriah.Waterland@Sun.COM 
31539781SMoriah.Waterland@Sun.COM 	/* determine size of the message in bytes */
31549781SMoriah.Waterland@Sun.COM 
31559781SMoriah.Waterland@Sun.COM 	va_start(ap, a_format);
31569781SMoriah.Waterland@Sun.COM 	vres = vsnprintf(bfr, 1, a_format, ap);
31579781SMoriah.Waterland@Sun.COM 	va_end(ap);
31589781SMoriah.Waterland@Sun.COM 
31599781SMoriah.Waterland@Sun.COM 	assert(vres > 0);
31609781SMoriah.Waterland@Sun.COM 
31619781SMoriah.Waterland@Sun.COM 	/* allocate storage to hold the message */
31629781SMoriah.Waterland@Sun.COM 
31639781SMoriah.Waterland@Sun.COM 	mbPath = (char *)calloc(1, vres+2);
31649781SMoriah.Waterland@Sun.COM 	assert(mbPath != NULL);
31659781SMoriah.Waterland@Sun.COM 
31669781SMoriah.Waterland@Sun.COM 	/* generate the results of the printf conversion */
31679781SMoriah.Waterland@Sun.COM 
31689781SMoriah.Waterland@Sun.COM 	va_start(ap, a_format);
31699781SMoriah.Waterland@Sun.COM 	vres = vsnprintf(mbPath, vres+1, a_format, ap);
31709781SMoriah.Waterland@Sun.COM 	va_end(ap);
31719781SMoriah.Waterland@Sun.COM 
31729781SMoriah.Waterland@Sun.COM 	assert(vres > 0);
31739781SMoriah.Waterland@Sun.COM 
31749781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_TEST_PATH, mbPath, (unsigned long)a_tt);
31759781SMoriah.Waterland@Sun.COM 
31769781SMoriah.Waterland@Sun.COM 	/*
31779781SMoriah.Waterland@Sun.COM 	 * When a path given to open(2) contains symbolic links, the
31789781SMoriah.Waterland@Sun.COM 	 * open system call first resolves all symbolic links and then
31799781SMoriah.Waterland@Sun.COM 	 * opens that final "resolved" path. As a result, it is not
31809781SMoriah.Waterland@Sun.COM 	 * possible to check the result of an fstat(2) against the
31819781SMoriah.Waterland@Sun.COM 	 * file descriptor returned by open(2) for S_IFLNK (a symbolic
31829781SMoriah.Waterland@Sun.COM 	 * link) since all symbolic links are resolved before the
31839781SMoriah.Waterland@Sun.COM 	 * target is opened.
31849781SMoriah.Waterland@Sun.COM 	 *
31859781SMoriah.Waterland@Sun.COM 	 * When testing the target as being (or not being) a symbolic
31869781SMoriah.Waterland@Sun.COM 	 * link, first use lstat(2) against the target to determine
31879781SMoriah.Waterland@Sun.COM 	 * whether or not the specified target itself is (or is not) a
31889781SMoriah.Waterland@Sun.COM 	 * symbolic link.
31899781SMoriah.Waterland@Sun.COM 	 */
31909781SMoriah.Waterland@Sun.COM 
31919781SMoriah.Waterland@Sun.COM 	if (a_tt & (TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)) {
31929781SMoriah.Waterland@Sun.COM 		/*
31939781SMoriah.Waterland@Sun.COM 		 * testing target is/is not a symbolic link; use lstat
31949781SMoriah.Waterland@Sun.COM 		 * to determine the status of the target itself rather
31959781SMoriah.Waterland@Sun.COM 		 * than what the target might finally address.
31969781SMoriah.Waterland@Sun.COM 		 */
31979781SMoriah.Waterland@Sun.COM 
31989781SMoriah.Waterland@Sun.COM 		if (lstat(mbPath, &statbuf) != 0) {
31999781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CANNOT_LSTAT_PATH, mbPath,
32009781SMoriah.Waterland@Sun.COM 				strerror(errno));
32019781SMoriah.Waterland@Sun.COM 			free(mbPath);
32029781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
32039781SMoriah.Waterland@Sun.COM 		}
32049781SMoriah.Waterland@Sun.COM 
32059781SMoriah.Waterland@Sun.COM 		/* Is the target required to be a symbolic link? */
32069781SMoriah.Waterland@Sun.COM 
32079781SMoriah.Waterland@Sun.COM 		if (a_tt & TEST_IS_SYMBOLIC_LINK) {
32089781SMoriah.Waterland@Sun.COM 			/* target must be a symbolic link */
32099781SMoriah.Waterland@Sun.COM 			if (!(statbuf.st_mode & S_IFLNK)) {
32109781SMoriah.Waterland@Sun.COM 				/* failure: target is not a symbolic link */
32119781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_IS_NOT_A_SYMLINK, mbPath);
32129781SMoriah.Waterland@Sun.COM 				free(mbPath);
32139781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
32149781SMoriah.Waterland@Sun.COM 			}
32159781SMoriah.Waterland@Sun.COM 			/* success: target is a symbolic link */
32169781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SYMLINK_IS, mbPath);
32179781SMoriah.Waterland@Sun.COM 		}
32189781SMoriah.Waterland@Sun.COM 
32199781SMoriah.Waterland@Sun.COM 		/* Is the target required to not be a symbolic link? */
32209781SMoriah.Waterland@Sun.COM 
32219781SMoriah.Waterland@Sun.COM 		if (a_tt & TEST_NOT_SYMBOLIC_LINK) {
32229781SMoriah.Waterland@Sun.COM 			/* target must not be a symbolic link */
32239781SMoriah.Waterland@Sun.COM 			if (statbuf.st_mode & S_IFLNK) {
32249781SMoriah.Waterland@Sun.COM 				/* failure: target is a symbolic link */
32259781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_IS_A_SYMLINK, mbPath);
32269781SMoriah.Waterland@Sun.COM 				free(mbPath);
32279781SMoriah.Waterland@Sun.COM 				return (R_FAILURE);
32289781SMoriah.Waterland@Sun.COM 			}
32299781SMoriah.Waterland@Sun.COM 			/* success: target is not a symbolic link */
32309781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SYMLINK_NOT, mbPath);
32319781SMoriah.Waterland@Sun.COM 		}
32329781SMoriah.Waterland@Sun.COM 
32339781SMoriah.Waterland@Sun.COM 		/*
32349781SMoriah.Waterland@Sun.COM 		 * if only testing is/is not a symbolic link, then
32359781SMoriah.Waterland@Sun.COM 		 * no need to open the target: return success.
32369781SMoriah.Waterland@Sun.COM 		 */
32379781SMoriah.Waterland@Sun.COM 
32389781SMoriah.Waterland@Sun.COM 		if (!(a_tt &
32399781SMoriah.Waterland@Sun.COM 		    (~(TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)))) {
32409781SMoriah.Waterland@Sun.COM 			free(mbPath);
32419781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
32429781SMoriah.Waterland@Sun.COM 		}
32439781SMoriah.Waterland@Sun.COM 	}
32449781SMoriah.Waterland@Sun.COM 
32459781SMoriah.Waterland@Sun.COM 	/* resolve path and remove any whitespace */
32469781SMoriah.Waterland@Sun.COM 
32479781SMoriah.Waterland@Sun.COM 	r = resolvePath(&mbPath);
32489781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
32499781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_TEST_PATH_NO_RESOLVE, mbPath);
32509781SMoriah.Waterland@Sun.COM 		free(mbPath);
32519781SMoriah.Waterland@Sun.COM 		if (a_tt & TEST_NOT_EXISTS) {
32529781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
32539781SMoriah.Waterland@Sun.COM 		}
32549781SMoriah.Waterland@Sun.COM 		return (r);
32559781SMoriah.Waterland@Sun.COM 	}
32569781SMoriah.Waterland@Sun.COM 
32579781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_TEST_PATH_RESOLVE, mbPath);
32589781SMoriah.Waterland@Sun.COM 
32599781SMoriah.Waterland@Sun.COM 	/* open the file - this is the basic existence test */
32609781SMoriah.Waterland@Sun.COM 
32619781SMoriah.Waterland@Sun.COM 	fd = open(mbPath, O_RDONLY|O_LARGEFILE, 0);
32629781SMoriah.Waterland@Sun.COM 
32639781SMoriah.Waterland@Sun.COM 	/* existence test failed if file cannot be opened */
32649781SMoriah.Waterland@Sun.COM 
32659781SMoriah.Waterland@Sun.COM 	if (fd < 0) {
32669781SMoriah.Waterland@Sun.COM 		/*
32679781SMoriah.Waterland@Sun.COM 		 * target could not be opened - if testing for non-existence,
32689781SMoriah.Waterland@Sun.COM 		 * return success, otherwise return failure
32699781SMoriah.Waterland@Sun.COM 		 */
32709781SMoriah.Waterland@Sun.COM 		if (a_tt & TEST_NOT_EXISTS) {
32719781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CANNOT_ACCESS_PATH_OK, mbPath);
32729781SMoriah.Waterland@Sun.COM 			free(mbPath);
32739781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
32749781SMoriah.Waterland@Sun.COM 		}
32759781SMoriah.Waterland@Sun.COM 
32769781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_CANNOT_ACCESS_PATH_BUT_SHOULD,
32779781SMoriah.Waterland@Sun.COM 		    mbPath, strerror(errno));
32789781SMoriah.Waterland@Sun.COM 		free(mbPath);
32799781SMoriah.Waterland@Sun.COM 
32809781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
32819781SMoriah.Waterland@Sun.COM 	}
32829781SMoriah.Waterland@Sun.COM 
32839781SMoriah.Waterland@Sun.COM 	/*
32849781SMoriah.Waterland@Sun.COM 	 * target successfully opened - if testing for non-existence,
32859781SMoriah.Waterland@Sun.COM 	 * return failure, otherwise continue with specified tests
32869781SMoriah.Waterland@Sun.COM 	 */
32879781SMoriah.Waterland@Sun.COM 
32889781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_NOT_EXISTS) {
32899781SMoriah.Waterland@Sun.COM 		/* testing for non-existence: return failure */
32909781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_TEST_EXISTS_SHOULD_NOT, mbPath);
32919781SMoriah.Waterland@Sun.COM 		free(mbPath);
32929781SMoriah.Waterland@Sun.COM 		(void) close(fd);
32939781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
32949781SMoriah.Waterland@Sun.COM 	}
32959781SMoriah.Waterland@Sun.COM 
32969781SMoriah.Waterland@Sun.COM 	/* get the file status */
32979781SMoriah.Waterland@Sun.COM 
32989781SMoriah.Waterland@Sun.COM 	r = fstat(fd, &statbuf);
32999781SMoriah.Waterland@Sun.COM 	if (r != 0) {
33009781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PATH_DOES_NOT_EXIST, mbPath, strerror(errno));
33019781SMoriah.Waterland@Sun.COM 		(void) close(fd);
33029781SMoriah.Waterland@Sun.COM 		free(mbPath);
33039781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
33049781SMoriah.Waterland@Sun.COM 	}
33059781SMoriah.Waterland@Sun.COM 
33069781SMoriah.Waterland@Sun.COM 	/* required to be a directory? */
33079781SMoriah.Waterland@Sun.COM 
33089781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_IS_DIRECTORY) {
33099781SMoriah.Waterland@Sun.COM 		if (!(statbuf.st_mode & S_IFDIR)) {
33109781SMoriah.Waterland@Sun.COM 			/* is not a directory */
33119781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_IS_NOT_A_DIRECTORY, mbPath);
33129781SMoriah.Waterland@Sun.COM 			free(mbPath);
33139781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33149781SMoriah.Waterland@Sun.COM 		}
33159781SMoriah.Waterland@Sun.COM 		/* a directory */
33169781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_DIRECTORY_IS, mbPath);
33179781SMoriah.Waterland@Sun.COM 	}
33189781SMoriah.Waterland@Sun.COM 
33199781SMoriah.Waterland@Sun.COM 	/* required to not be a directory? */
33209781SMoriah.Waterland@Sun.COM 
33219781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_NOT_DIRECTORY) {
33229781SMoriah.Waterland@Sun.COM 		if (statbuf.st_mode & S_IFDIR) {
33239781SMoriah.Waterland@Sun.COM 			/* is a directory */
33249781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_IS_A_DIRECTORY, mbPath);
33259781SMoriah.Waterland@Sun.COM 			free(mbPath);
33269781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33279781SMoriah.Waterland@Sun.COM 		}
33289781SMoriah.Waterland@Sun.COM 		/* not a directory */
33299781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_DIRECTORY_NOT, mbPath);
33309781SMoriah.Waterland@Sun.COM 	}
33319781SMoriah.Waterland@Sun.COM 
33329781SMoriah.Waterland@Sun.COM 	/* required to be a file? */
33339781SMoriah.Waterland@Sun.COM 
33349781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_IS_FILE) {
33359781SMoriah.Waterland@Sun.COM 		if (!(statbuf.st_mode & S_IFREG)) {
33369781SMoriah.Waterland@Sun.COM 			/* is not a regular file */
33379781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_IS_NOT_A_FILE, mbPath);
33389781SMoriah.Waterland@Sun.COM 			free(mbPath);
33399781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33409781SMoriah.Waterland@Sun.COM 		}
33419781SMoriah.Waterland@Sun.COM 		/* a regular file */
33429781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_FILE_IS, mbPath);
33439781SMoriah.Waterland@Sun.COM 	}
33449781SMoriah.Waterland@Sun.COM 
33459781SMoriah.Waterland@Sun.COM 	/* required to not be a file? */
33469781SMoriah.Waterland@Sun.COM 
33479781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_NOT_FILE) {
33489781SMoriah.Waterland@Sun.COM 		if (statbuf.st_mode & S_IFREG) {
33499781SMoriah.Waterland@Sun.COM 			/* is a regular file */
33509781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_IS_A_FILE, mbPath);
33519781SMoriah.Waterland@Sun.COM 			free(mbPath);
33529781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33539781SMoriah.Waterland@Sun.COM 		}
33549781SMoriah.Waterland@Sun.COM 		/* not a regular file */
33559781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_FILE_NOT, mbPath);
33569781SMoriah.Waterland@Sun.COM 	}
33579781SMoriah.Waterland@Sun.COM 
33589781SMoriah.Waterland@Sun.COM 	/*
33599781SMoriah.Waterland@Sun.COM 	 * Find token (global) in file pointed to by mbPath.
33609781SMoriah.Waterland@Sun.COM 	 * token is only compared to first word in mbPath.
33619781SMoriah.Waterland@Sun.COM 	 */
33629781SMoriah.Waterland@Sun.COM 
33639781SMoriah.Waterland@Sun.COM 	if (a_tt & TEST_GLOBAL_TOKEN_IN_FILE) {
33649781SMoriah.Waterland@Sun.COM 		if (!(statbuf.st_mode & S_IFREG)) {
33659781SMoriah.Waterland@Sun.COM 			/* is not a regular file */
33669781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_IS_NOT_A_FILE, mbPath);
33679781SMoriah.Waterland@Sun.COM 			free(mbPath);
33689781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33699781SMoriah.Waterland@Sun.COM 		}
33709781SMoriah.Waterland@Sun.COM 		/* If global exists then we're not in a non-global zone */
33719781SMoriah.Waterland@Sun.COM 		if (findToken(mbPath, GLOBAL_ZONENAME) == R_SUCCESS) {
33729781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_TOKEN__EXISTS, GLOBAL_ZONENAME, mbPath);
33739781SMoriah.Waterland@Sun.COM 			free(mbPath);
33749781SMoriah.Waterland@Sun.COM 			return (R_FAILURE);
33759781SMoriah.Waterland@Sun.COM 		}
33769781SMoriah.Waterland@Sun.COM 	}
33779781SMoriah.Waterland@Sun.COM 
33789781SMoriah.Waterland@Sun.COM 	(void) close(fd);
33799781SMoriah.Waterland@Sun.COM 
33809781SMoriah.Waterland@Sun.COM 	/* success! */
33819781SMoriah.Waterland@Sun.COM 
33829781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_TESTPATH_OK, mbPath);
33839781SMoriah.Waterland@Sun.COM 
33849781SMoriah.Waterland@Sun.COM 	/* free up temp storage used to hold path to test */
33859781SMoriah.Waterland@Sun.COM 
33869781SMoriah.Waterland@Sun.COM 	free(mbPath);
33879781SMoriah.Waterland@Sun.COM 
33889781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
33899781SMoriah.Waterland@Sun.COM }
33909781SMoriah.Waterland@Sun.COM 
33919781SMoriah.Waterland@Sun.COM /*
33929781SMoriah.Waterland@Sun.COM  * Name:        findToken
33939781SMoriah.Waterland@Sun.COM  * Description:	Find first token in file.
33949781SMoriah.Waterland@Sun.COM  * Arguments:
33959781SMoriah.Waterland@Sun.COM  *              path - file to search for token
33969781SMoriah.Waterland@Sun.COM  *              token - string to search for
33979781SMoriah.Waterland@Sun.COM  * Returns:
33989781SMoriah.Waterland@Sun.COM  *              R_SUCCESS - the token exists
33999781SMoriah.Waterland@Sun.COM  *              R_FAILURE - the token does not exist
34009781SMoriah.Waterland@Sun.COM  *              R_ERROR - fatal error attempting to find token
34019781SMoriah.Waterland@Sun.COM  */
34029781SMoriah.Waterland@Sun.COM 
34039781SMoriah.Waterland@Sun.COM static int
findToken(char * path,char * token)34049781SMoriah.Waterland@Sun.COM findToken(char *path, char *token)
34059781SMoriah.Waterland@Sun.COM {
34069781SMoriah.Waterland@Sun.COM 	FILE	*fp;
34079781SMoriah.Waterland@Sun.COM 	char	*cp;
34089781SMoriah.Waterland@Sun.COM 	char	line[MAXPATHLEN];
34099781SMoriah.Waterland@Sun.COM 
34109781SMoriah.Waterland@Sun.COM 	if (path == NULL || token == NULL) {
34119781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
34129781SMoriah.Waterland@Sun.COM 	}
34139781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(path, "r")) == NULL) {
34149781SMoriah.Waterland@Sun.COM 		return (R_ERROR);
34159781SMoriah.Waterland@Sun.COM 	}
34169781SMoriah.Waterland@Sun.COM 
34179781SMoriah.Waterland@Sun.COM 	while (fgets(line, sizeof (line), fp) != NULL) {
34189781SMoriah.Waterland@Sun.COM 		for (cp = line; *cp && isspace(*cp); cp++);
34199781SMoriah.Waterland@Sun.COM 		/* skip comments */
34209781SMoriah.Waterland@Sun.COM 		if (*cp == '#') {
34219781SMoriah.Waterland@Sun.COM 			continue;
34229781SMoriah.Waterland@Sun.COM 		}
34239781SMoriah.Waterland@Sun.COM 		if (pkgstrContainsToken(cp, token, ":")) {
34249781SMoriah.Waterland@Sun.COM 			(void) fclose(fp);
34259781SMoriah.Waterland@Sun.COM 			return (R_SUCCESS);
34269781SMoriah.Waterland@Sun.COM 		}
34279781SMoriah.Waterland@Sun.COM 	}
34289781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
34299781SMoriah.Waterland@Sun.COM 	return (R_FAILURE);
34309781SMoriah.Waterland@Sun.COM }
34319781SMoriah.Waterland@Sun.COM 
34329781SMoriah.Waterland@Sun.COM 
34339781SMoriah.Waterland@Sun.COM /*
34349781SMoriah.Waterland@Sun.COM  * Name:	resolvePath
34359781SMoriah.Waterland@Sun.COM  * Description:	fully resolve a path to an absolute real path
34369781SMoriah.Waterland@Sun.COM  * Arguments:	r_path - pointer to pointer to malloc()ed storage containing
34379781SMoriah.Waterland@Sun.COM  *			the path to resolve - this path may be reallocated
34389781SMoriah.Waterland@Sun.COM  *			as necessary to hold the fully resolved path
34399781SMoriah.Waterland@Sun.COM  * Output:	r_path - is realloc()ed as necessary
34409781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - the path is fully resolved
34419781SMoriah.Waterland@Sun.COM  *		R_FAILURE - the path could not be resolved
34429781SMoriah.Waterland@Sun.COM  *		R_ERROR - fatal error attempting to resolve path
34439781SMoriah.Waterland@Sun.COM  */
34449781SMoriah.Waterland@Sun.COM 
34459781SMoriah.Waterland@Sun.COM static int
resolvePath(char ** r_path)34469781SMoriah.Waterland@Sun.COM resolvePath(char **r_path)
34479781SMoriah.Waterland@Sun.COM {
34489781SMoriah.Waterland@Sun.COM 	int		i;
34499781SMoriah.Waterland@Sun.COM 	char		resolvedPath[MAXPATHLEN+1] = {'\0'};
34509781SMoriah.Waterland@Sun.COM 	size_t		mbPathlen;	/* length of multi-byte path */
34519781SMoriah.Waterland@Sun.COM 	size_t		wcPathlen;	/* length of wide-character path */
34529781SMoriah.Waterland@Sun.COM 	wchar_t		*wcPath;	/* wide-character version of the path */
34539781SMoriah.Waterland@Sun.COM 	wchar_t		*wptr;		/* scratch pointer */
34549781SMoriah.Waterland@Sun.COM 
34559781SMoriah.Waterland@Sun.COM 	/* entry assertions */
34569781SMoriah.Waterland@Sun.COM 
34579781SMoriah.Waterland@Sun.COM 	assert(r_path != (char **)NULL);
34589781SMoriah.Waterland@Sun.COM 
34599781SMoriah.Waterland@Sun.COM 	/* return error if the path is completely empty */
34609781SMoriah.Waterland@Sun.COM 
34619781SMoriah.Waterland@Sun.COM 	if (*r_path == '\0') {
34629781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
34639781SMoriah.Waterland@Sun.COM 	}
34649781SMoriah.Waterland@Sun.COM 
34659781SMoriah.Waterland@Sun.COM 	/* remove all leading whitespace */
34669781SMoriah.Waterland@Sun.COM 
34679781SMoriah.Waterland@Sun.COM 	removeLeadingWhitespace(r_path);
34689781SMoriah.Waterland@Sun.COM 
34699781SMoriah.Waterland@Sun.COM 	/*
34709781SMoriah.Waterland@Sun.COM 	 * convert to real path: an absolute pathname that names the same file,
34719781SMoriah.Waterland@Sun.COM 	 * whose resolution does not involve ".", "..",  or  symbolic links.
34729781SMoriah.Waterland@Sun.COM 	 */
34739781SMoriah.Waterland@Sun.COM 
34749781SMoriah.Waterland@Sun.COM 	if (realpath(*r_path, resolvedPath) != NULL) {
34759781SMoriah.Waterland@Sun.COM 		free(*r_path);
34769781SMoriah.Waterland@Sun.COM 		*r_path = strdup(resolvedPath);
34779781SMoriah.Waterland@Sun.COM 	}
34789781SMoriah.Waterland@Sun.COM 
34799781SMoriah.Waterland@Sun.COM 	/*
34809781SMoriah.Waterland@Sun.COM 	 *  convert the multi-byte version of the path to a
34819781SMoriah.Waterland@Sun.COM 	 *  wide-character rendering, for doing our figuring.
34829781SMoriah.Waterland@Sun.COM 	 */
34839781SMoriah.Waterland@Sun.COM 
34849781SMoriah.Waterland@Sun.COM 	mbPathlen = strlen(*r_path);
34859781SMoriah.Waterland@Sun.COM 
34869781SMoriah.Waterland@Sun.COM 	if ((wcPath = (wchar_t *)
34879781SMoriah.Waterland@Sun.COM 		calloc(1, sizeof (wchar_t)*(mbPathlen+1))) == NULL) {
34889781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
34899781SMoriah.Waterland@Sun.COM 	}
34909781SMoriah.Waterland@Sun.COM 
34919781SMoriah.Waterland@Sun.COM 	/*LINTED*/
34929781SMoriah.Waterland@Sun.COM 	if ((wcPathlen = mbstowcs(wcPath, *r_path, mbPathlen)) == -1) {
34939781SMoriah.Waterland@Sun.COM 		free(wcPath);
34949781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
34959781SMoriah.Waterland@Sun.COM 	}
34969781SMoriah.Waterland@Sun.COM 
34979781SMoriah.Waterland@Sun.COM 	/*
34989781SMoriah.Waterland@Sun.COM 	 *  remove duplicate slashes first ("//../" -> "/")
34999781SMoriah.Waterland@Sun.COM 	 */
35009781SMoriah.Waterland@Sun.COM 
35019781SMoriah.Waterland@Sun.COM 	for (wptr = wcPath, i = 0; i < wcPathlen; i++) {
35029781SMoriah.Waterland@Sun.COM 		*wptr++ = wcPath[i];
35039781SMoriah.Waterland@Sun.COM 
35049781SMoriah.Waterland@Sun.COM 		if (wcPath[i] == '/') {
35059781SMoriah.Waterland@Sun.COM 			i++;
35069781SMoriah.Waterland@Sun.COM 
35079781SMoriah.Waterland@Sun.COM 			while (wcPath[i] == '/') {
35089781SMoriah.Waterland@Sun.COM 				i++;
35099781SMoriah.Waterland@Sun.COM 			}
35109781SMoriah.Waterland@Sun.COM 
35119781SMoriah.Waterland@Sun.COM 			i--;
35129781SMoriah.Waterland@Sun.COM 		}
35139781SMoriah.Waterland@Sun.COM 	}
35149781SMoriah.Waterland@Sun.COM 
35159781SMoriah.Waterland@Sun.COM 	*wptr = '\0';
35169781SMoriah.Waterland@Sun.COM 
35179781SMoriah.Waterland@Sun.COM 	/*
35189781SMoriah.Waterland@Sun.COM 	 *  now convert back to the multi-byte format.
35199781SMoriah.Waterland@Sun.COM 	 */
35209781SMoriah.Waterland@Sun.COM 
35219781SMoriah.Waterland@Sun.COM 	/*LINTED*/
35229781SMoriah.Waterland@Sun.COM 	if (wcstombs(*r_path, wcPath, mbPathlen) == -1) {
35239781SMoriah.Waterland@Sun.COM 		free(wcPath);
35249781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
35259781SMoriah.Waterland@Sun.COM 	}
35269781SMoriah.Waterland@Sun.COM 
35279781SMoriah.Waterland@Sun.COM 	/* at this point have a path */
35289781SMoriah.Waterland@Sun.COM 
35299781SMoriah.Waterland@Sun.COM 	/* free up temporary storage */
35309781SMoriah.Waterland@Sun.COM 
35319781SMoriah.Waterland@Sun.COM 	free(wcPath);
35329781SMoriah.Waterland@Sun.COM 
35339781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
35349781SMoriah.Waterland@Sun.COM }
35359781SMoriah.Waterland@Sun.COM 
35369781SMoriah.Waterland@Sun.COM /*
35379781SMoriah.Waterland@Sun.COM  * Name:	removeLeadingWhitespace
35389781SMoriah.Waterland@Sun.COM  * Synopsis:	Remove leading whitespace from string
35399781SMoriah.Waterland@Sun.COM  * Description:	Remove all leading whitespace characters from a string
35409781SMoriah.Waterland@Sun.COM  * Arguments:	a_str - [RO, *RW] - (char **)
35419781SMoriah.Waterland@Sun.COM  *			Pointer to handle to string (in allocated storage) to
35429781SMoriah.Waterland@Sun.COM  *			remove all leading whitespace from
35439781SMoriah.Waterland@Sun.COM  * Returns:	void
35449781SMoriah.Waterland@Sun.COM  *			The input string is modified as follows:
35459781SMoriah.Waterland@Sun.COM  *			== NULL:
35469781SMoriah.Waterland@Sun.COM  *				- input string was NULL
35479781SMoriah.Waterland@Sun.COM  *				- input string is all whitespace
35489781SMoriah.Waterland@Sun.COM  *			!= NULL:
35499781SMoriah.Waterland@Sun.COM  *				- copy of input string with leading
35509781SMoriah.Waterland@Sun.COM  *				  whitespace removed
35519781SMoriah.Waterland@Sun.COM  * CAUTION:	The input string must be allocated space (via malloc() or
35529781SMoriah.Waterland@Sun.COM  *		strdup()) - it must not be a static or inline character string
35539781SMoriah.Waterland@Sun.COM  * NOTE:	The input string a_str will be freed with 'free'
35549781SMoriah.Waterland@Sun.COM  *		if it is all whitespace, or if it contains any leading
35559781SMoriah.Waterland@Sun.COM  *		whitespace characters
35569781SMoriah.Waterland@Sun.COM  * NOTE:    	Any string returned is placed in new storage for the
35579781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
35589781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
35599781SMoriah.Waterland@Sun.COM  * Errors:	If the string cannot be created, the process exits
35609781SMoriah.Waterland@Sun.COM  */
35619781SMoriah.Waterland@Sun.COM 
35629781SMoriah.Waterland@Sun.COM static void
removeLeadingWhitespace(char ** a_str)35639781SMoriah.Waterland@Sun.COM removeLeadingWhitespace(char **a_str)
35649781SMoriah.Waterland@Sun.COM {
35659781SMoriah.Waterland@Sun.COM 	char	*o_str;
35669781SMoriah.Waterland@Sun.COM 
35679781SMoriah.Waterland@Sun.COM 	/* entry assertions */
35689781SMoriah.Waterland@Sun.COM 
35699781SMoriah.Waterland@Sun.COM 	assert(a_str != (char **)NULL);
35709781SMoriah.Waterland@Sun.COM 
35719781SMoriah.Waterland@Sun.COM 	/* if string is null, just return */
35729781SMoriah.Waterland@Sun.COM 
35739781SMoriah.Waterland@Sun.COM 	if (*a_str == NULL) {
35749781SMoriah.Waterland@Sun.COM 		return;
35759781SMoriah.Waterland@Sun.COM 	}
35769781SMoriah.Waterland@Sun.COM 	o_str = *a_str;
35779781SMoriah.Waterland@Sun.COM 
35789781SMoriah.Waterland@Sun.COM 	/* if string is empty, deallocate and return NULL */
35799781SMoriah.Waterland@Sun.COM 
35809781SMoriah.Waterland@Sun.COM 	if (*o_str == '\0') {
35819781SMoriah.Waterland@Sun.COM 		/* free string */
35829781SMoriah.Waterland@Sun.COM 		free(*a_str);
35839781SMoriah.Waterland@Sun.COM 		*a_str = NULL;
35849781SMoriah.Waterland@Sun.COM 		return;
35859781SMoriah.Waterland@Sun.COM 	}
35869781SMoriah.Waterland@Sun.COM 
35879781SMoriah.Waterland@Sun.COM 	/* if first character is not a space, just return */
35889781SMoriah.Waterland@Sun.COM 
35899781SMoriah.Waterland@Sun.COM 	if (!isspace(*o_str)) {
35909781SMoriah.Waterland@Sun.COM 		return;
35919781SMoriah.Waterland@Sun.COM 	}
35929781SMoriah.Waterland@Sun.COM 
35939781SMoriah.Waterland@Sun.COM 	/* advance past all space characters */
35949781SMoriah.Waterland@Sun.COM 
35959781SMoriah.Waterland@Sun.COM 	while ((*o_str != '\0') && (isspace(*o_str))) {
35969781SMoriah.Waterland@Sun.COM 		o_str++;
35979781SMoriah.Waterland@Sun.COM 	}
35989781SMoriah.Waterland@Sun.COM 
35999781SMoriah.Waterland@Sun.COM 	/* if string was all space characters, deallocate and return NULL */
36009781SMoriah.Waterland@Sun.COM 
36019781SMoriah.Waterland@Sun.COM 	if (*o_str == '\0') {
36029781SMoriah.Waterland@Sun.COM 		/* free string */
36039781SMoriah.Waterland@Sun.COM 		free(*a_str);
36049781SMoriah.Waterland@Sun.COM 		*a_str = NULL;
36059781SMoriah.Waterland@Sun.COM 		return;
36069781SMoriah.Waterland@Sun.COM 	}
36079781SMoriah.Waterland@Sun.COM 
36089781SMoriah.Waterland@Sun.COM 	/* have non-space/null byte, return dup, deallocate original */
36099781SMoriah.Waterland@Sun.COM 
36109781SMoriah.Waterland@Sun.COM 	o_str = strdup(o_str);
36119781SMoriah.Waterland@Sun.COM 	free(*a_str);
36129781SMoriah.Waterland@Sun.COM 	*a_str = o_str;
36139781SMoriah.Waterland@Sun.COM }
36149781SMoriah.Waterland@Sun.COM 
36159781SMoriah.Waterland@Sun.COM /*
36169781SMoriah.Waterland@Sun.COM  * Name:	getZoneName
36179781SMoriah.Waterland@Sun.COM  * Description:	get the name of the zone this process is running in
36189781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneName - pointer to pointer to receive zone name
36199781SMoriah.Waterland@Sun.COM  * Output:	r_zoneName - a pointer to malloc()ed storage containing
36209781SMoriah.Waterland@Sun.COM  *			the zone name this process is running in is stored
36219781SMoriah.Waterland@Sun.COM  *			in the location pointed to by r_zoneName
36229781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - the zone name is successfully returned
36239781SMoriah.Waterland@Sun.COM  *		R_FAILURE - the zone name is not successfully returned
36249781SMoriah.Waterland@Sun.COM  *		R_ERROR - error attempting to get the zone name
36259781SMoriah.Waterland@Sun.COM  */
36269781SMoriah.Waterland@Sun.COM 
36279781SMoriah.Waterland@Sun.COM static int
getZoneName(char ** r_zoneName)36289781SMoriah.Waterland@Sun.COM getZoneName(char **r_zoneName)
36299781SMoriah.Waterland@Sun.COM {
36309781SMoriah.Waterland@Sun.COM static char zoneName[ZONENAME_MAX] = { '\0' };
36319781SMoriah.Waterland@Sun.COM 
36329781SMoriah.Waterland@Sun.COM 	/* if zone name not already present, retrieve and cache name */
36339781SMoriah.Waterland@Sun.COM 
36349781SMoriah.Waterland@Sun.COM 	if (zoneName[0] == '\0') {
36359781SMoriah.Waterland@Sun.COM 		if (getzonenamebyid(getzoneid(), zoneName,
36369781SMoriah.Waterland@Sun.COM 			sizeof (zoneName)) < 0) {
36379781SMoriah.Waterland@Sun.COM 			log_msg(LOG_MSG_ERR, ERR_CANNOT_GET_ZONENAME);
36389781SMoriah.Waterland@Sun.COM 			return (R_ERROR);
36399781SMoriah.Waterland@Sun.COM 		}
36409781SMoriah.Waterland@Sun.COM 	}
36419781SMoriah.Waterland@Sun.COM 
36429781SMoriah.Waterland@Sun.COM 	/* return cached zone name */
36439781SMoriah.Waterland@Sun.COM 
36449781SMoriah.Waterland@Sun.COM 	*r_zoneName = zoneName;
36459781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
36469781SMoriah.Waterland@Sun.COM }
36479781SMoriah.Waterland@Sun.COM 
36489781SMoriah.Waterland@Sun.COM /*
36499781SMoriah.Waterland@Sun.COM  * Name:	getRootPath
36509781SMoriah.Waterland@Sun.COM  * Description:	get the root path being tested by this process
36519781SMoriah.Waterland@Sun.COM  * Arguments:	r_rootPath - pointer to pointer to receive root path
36529781SMoriah.Waterland@Sun.COM  * Output:	r_rootPath - a pointer to malloc()ed storage containing
36539781SMoriah.Waterland@Sun.COM  *			the root path name this process is testing
36549781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - the root path is successfully returned
36559781SMoriah.Waterland@Sun.COM  *		R_FAILURE - the root path is not successfully returned
36569781SMoriah.Waterland@Sun.COM  *		R_ERROR - error attempting to get the root path
36579781SMoriah.Waterland@Sun.COM  */
36589781SMoriah.Waterland@Sun.COM 
36599781SMoriah.Waterland@Sun.COM static int
getRootPath(char ** r_rootPath)36609781SMoriah.Waterland@Sun.COM getRootPath(char **r_rootPath)
36619781SMoriah.Waterland@Sun.COM {
36629781SMoriah.Waterland@Sun.COM 	*r_rootPath = _rootPath;
36639781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
36649781SMoriah.Waterland@Sun.COM }
36659781SMoriah.Waterland@Sun.COM 
36669781SMoriah.Waterland@Sun.COM /*
36679781SMoriah.Waterland@Sun.COM  * Name:	setVerbose
36689781SMoriah.Waterland@Sun.COM  * Description:	Turns on verbose output
36699781SMoriah.Waterland@Sun.COM  * Scope:	public
36709781SMoriah.Waterland@Sun.COM  * Arguments:	verbose = B_TRUE indicates verbose mode
36719781SMoriah.Waterland@Sun.COM  * Returns:	none
36729781SMoriah.Waterland@Sun.COM  */
36739781SMoriah.Waterland@Sun.COM 
36749781SMoriah.Waterland@Sun.COM static void
setVerbose(boolean_t setting)36759781SMoriah.Waterland@Sun.COM setVerbose(boolean_t setting)
36769781SMoriah.Waterland@Sun.COM {
36779781SMoriah.Waterland@Sun.COM 	/* set log verbose messages */
36789781SMoriah.Waterland@Sun.COM 
36799781SMoriah.Waterland@Sun.COM 	log_set_verbose(setting);
36809781SMoriah.Waterland@Sun.COM 
36819781SMoriah.Waterland@Sun.COM 	/* set interactive messages */
36829781SMoriah.Waterland@Sun.COM 
36839781SMoriah.Waterland@Sun.COM 	echoSetFlag(setting);
36849781SMoriah.Waterland@Sun.COM }
36859781SMoriah.Waterland@Sun.COM 
36869781SMoriah.Waterland@Sun.COM /*
36879781SMoriah.Waterland@Sun.COM  * Name:	negate_results
36889781SMoriah.Waterland@Sun.COM  * Description:	control negation of results
36899781SMoriah.Waterland@Sun.COM  * Scope:	public
36909781SMoriah.Waterland@Sun.COM  * Arguments:	setting
36919781SMoriah.Waterland@Sun.COM  *		== B_TRUE indicates negated results mode
36929781SMoriah.Waterland@Sun.COM  *		== B_FALSE indicates non-negated results mode
36939781SMoriah.Waterland@Sun.COM  * Returns:	none
36949781SMoriah.Waterland@Sun.COM  */
36959781SMoriah.Waterland@Sun.COM 
36969781SMoriah.Waterland@Sun.COM static void
setNegateResults(boolean_t setting)36979781SMoriah.Waterland@Sun.COM setNegateResults(boolean_t setting)
36989781SMoriah.Waterland@Sun.COM {
36999781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_SET_NEGATE_RESULTS,
37009781SMoriah.Waterland@Sun.COM 		_negateResults, setting);
37019781SMoriah.Waterland@Sun.COM 
37029781SMoriah.Waterland@Sun.COM 	_negateResults = setting;
37039781SMoriah.Waterland@Sun.COM }
37049781SMoriah.Waterland@Sun.COM 
37059781SMoriah.Waterland@Sun.COM /*
37069781SMoriah.Waterland@Sun.COM  * Name:	getNegateResults
37079781SMoriah.Waterland@Sun.COM  * Description:	Returns whether or not to results are negated
37089781SMoriah.Waterland@Sun.COM  * Scope:	public
37099781SMoriah.Waterland@Sun.COM  * Arguments:	none
37109781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - results are negated
37119781SMoriah.Waterland@Sun.COM  *		B_FALSE - results are not negated
37129781SMoriah.Waterland@Sun.COM  */
37139781SMoriah.Waterland@Sun.COM 
37149781SMoriah.Waterland@Sun.COM static boolean_t
getNegateResults(void)37159781SMoriah.Waterland@Sun.COM getNegateResults(void)
37169781SMoriah.Waterland@Sun.COM {
37179781SMoriah.Waterland@Sun.COM 	return (_negateResults);
37189781SMoriah.Waterland@Sun.COM }
37199781SMoriah.Waterland@Sun.COM 
37209781SMoriah.Waterland@Sun.COM /*
37219781SMoriah.Waterland@Sun.COM  * Name:	usage
37229781SMoriah.Waterland@Sun.COM  * Description:	output usage string
37239781SMoriah.Waterland@Sun.COM  * Arguments:	a_format - format to use to generate message
37249781SMoriah.Waterland@Sun.COM  *		arguments following a_format - as needed for a_format
37259781SMoriah.Waterland@Sun.COM  * Output:	Outputs the usage string to stderr.
37269781SMoriah.Waterland@Sun.COM  * Returns:	R_ERROR
37279781SMoriah.Waterland@Sun.COM  */
37289781SMoriah.Waterland@Sun.COM 
37299781SMoriah.Waterland@Sun.COM static int
usage(char * a_format,...)37309781SMoriah.Waterland@Sun.COM usage(char *a_format, ...)
37319781SMoriah.Waterland@Sun.COM {
37329781SMoriah.Waterland@Sun.COM 	int		cur_cmd;
37339781SMoriah.Waterland@Sun.COM 	char		cmdlst[LINE_MAX+1] = { '\0' };
37349781SMoriah.Waterland@Sun.COM 	char		*message;
37359781SMoriah.Waterland@Sun.COM 	char		bfr[1];
37369781SMoriah.Waterland@Sun.COM 	char		*p = get_prog_name();
37379781SMoriah.Waterland@Sun.COM 	size_t		vres = 0;
37389781SMoriah.Waterland@Sun.COM 	va_list		ap;
37399781SMoriah.Waterland@Sun.COM 
37409781SMoriah.Waterland@Sun.COM 	/* entry assertions */
37419781SMoriah.Waterland@Sun.COM 
37429781SMoriah.Waterland@Sun.COM 	assert(a_format != NULL);
37439781SMoriah.Waterland@Sun.COM 	assert(*a_format != '\0');
37449781SMoriah.Waterland@Sun.COM 
37459781SMoriah.Waterland@Sun.COM 	/* determine size of the message in bytes */
37469781SMoriah.Waterland@Sun.COM 
37479781SMoriah.Waterland@Sun.COM 	va_start(ap, a_format);
37489781SMoriah.Waterland@Sun.COM 	/* LINTED warning: variable format specifier to vsnprintf(); */
37499781SMoriah.Waterland@Sun.COM 	vres = vsnprintf(bfr, 1, a_format, ap);
37509781SMoriah.Waterland@Sun.COM 	va_end(ap);
37519781SMoriah.Waterland@Sun.COM 
37529781SMoriah.Waterland@Sun.COM 	assert(vres > 0);
37539781SMoriah.Waterland@Sun.COM 
37549781SMoriah.Waterland@Sun.COM 	/* allocate storage to hold the message */
37559781SMoriah.Waterland@Sun.COM 
37569781SMoriah.Waterland@Sun.COM 	message = (char *)calloc(1, vres+2);
37579781SMoriah.Waterland@Sun.COM 	assert(message != NULL);
37589781SMoriah.Waterland@Sun.COM 
37599781SMoriah.Waterland@Sun.COM 	/* generate the results of the printf conversion */
37609781SMoriah.Waterland@Sun.COM 
37619781SMoriah.Waterland@Sun.COM 	va_start(ap, a_format);
37629781SMoriah.Waterland@Sun.COM 	/* LINTED warning: variable format specifier to vsnprintf(); */
37639781SMoriah.Waterland@Sun.COM 	vres = vsnprintf(message, vres+1, a_format, ap);
37649781SMoriah.Waterland@Sun.COM 	va_end(ap);
37659781SMoriah.Waterland@Sun.COM 
37669781SMoriah.Waterland@Sun.COM 	assert(vres > 0);
37679781SMoriah.Waterland@Sun.COM 
37689781SMoriah.Waterland@Sun.COM 	/* generate list of all defined conditions */
37699781SMoriah.Waterland@Sun.COM 
37709781SMoriah.Waterland@Sun.COM 	for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) {
37719781SMoriah.Waterland@Sun.COM 		(void) strlcat(cmdlst, "\t", sizeof (cmdlst));
37729781SMoriah.Waterland@Sun.COM 		(void) strlcat(cmdlst, cmds[cur_cmd].c_name, sizeof (cmdlst));
37739781SMoriah.Waterland@Sun.COM 		if (cmds[cur_cmd].c_args != NULL) {
37749781SMoriah.Waterland@Sun.COM 			(void) strlcat(cmdlst, cmds[cur_cmd].c_args,
37759781SMoriah.Waterland@Sun.COM 						sizeof (cmdlst));
37769781SMoriah.Waterland@Sun.COM 		}
37779781SMoriah.Waterland@Sun.COM 		(void) strlcat(cmdlst, "\n", sizeof (cmdlst));
37789781SMoriah.Waterland@Sun.COM 	}
37799781SMoriah.Waterland@Sun.COM 
37809781SMoriah.Waterland@Sun.COM 	/* output usage with conditions */
37819781SMoriah.Waterland@Sun.COM 
37829781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_INFO, MSG_USAGE, message, p ? p : "pkgcond", cmdlst);
37839781SMoriah.Waterland@Sun.COM 
37849781SMoriah.Waterland@Sun.COM 	return (R_ERROR);
37859781SMoriah.Waterland@Sun.COM }
37869781SMoriah.Waterland@Sun.COM 
37879781SMoriah.Waterland@Sun.COM /*
37889781SMoriah.Waterland@Sun.COM  * Name:	parseGlobalData
37899781SMoriah.Waterland@Sun.COM  * Description:	parse environment global data and store in global data structure
37909781SMoriah.Waterland@Sun.COM  * Arguments:	a_envVar - pointer to string representing the name of the
37919781SMoriah.Waterland@Sun.COM  *			environment variable to get and parse
37929781SMoriah.Waterland@Sun.COM  *		r_gdt - pointer to pointer to global data structure to fill in
37939781SMoriah.Waterland@Sun.COM  *			using the parsed data from a_envVar
37949781SMoriah.Waterland@Sun.COM  * Output:	none
37959781SMoriah.Waterland@Sun.COM  * Returns:	R_SUCCESS - the global data is successfully parsed
37969781SMoriah.Waterland@Sun.COM  *		R_FAILURE - problem parsing global data
37979781SMoriah.Waterland@Sun.COM  *		R_ERROR - fatal error attempting to parse global data
37989781SMoriah.Waterland@Sun.COM  */
37999781SMoriah.Waterland@Sun.COM 
38009781SMoriah.Waterland@Sun.COM static int
parseGlobalData(char * a_envVar,GLOBALDATA_T ** r_gdt)38019781SMoriah.Waterland@Sun.COM parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt)
38029781SMoriah.Waterland@Sun.COM {
38039781SMoriah.Waterland@Sun.COM 	int		r;
38049781SMoriah.Waterland@Sun.COM 	int		n;
38059781SMoriah.Waterland@Sun.COM 	char		*a;
38069781SMoriah.Waterland@Sun.COM 	SML_TAG		*tag;
38079781SMoriah.Waterland@Sun.COM 	SML_TAG		*ntag;
38089781SMoriah.Waterland@Sun.COM 
38099781SMoriah.Waterland@Sun.COM 	assert(r_gdt != (GLOBALDATA_T **)NULL);
38109781SMoriah.Waterland@Sun.COM 
38119781SMoriah.Waterland@Sun.COM 	/*
38129781SMoriah.Waterland@Sun.COM 	 * allocate space for global data structure if needed
38139781SMoriah.Waterland@Sun.COM 	 */
38149781SMoriah.Waterland@Sun.COM 
38159781SMoriah.Waterland@Sun.COM 	if (*r_gdt == (GLOBALDATA_T *)NULL) {
38169781SMoriah.Waterland@Sun.COM 		*r_gdt = (GLOBALDATA_T *)calloc(1, sizeof (GLOBALDATA_T));
38179781SMoriah.Waterland@Sun.COM 	}
38189781SMoriah.Waterland@Sun.COM 
38199781SMoriah.Waterland@Sun.COM 	/*
38209781SMoriah.Waterland@Sun.COM 	 * get initial installation indication:
38219781SMoriah.Waterland@Sun.COM 	 * If the initial install variable is set to "true", then an initial
38229781SMoriah.Waterland@Sun.COM 	 * installation of Solaris is underway. When this condition is true:
38239781SMoriah.Waterland@Sun.COM 	 * - if the path being checked is the package install root, then
38249781SMoriah.Waterland@Sun.COM 	 *   the path is considered to be an 'alternative root' which is
38259781SMoriah.Waterland@Sun.COM 	 *   currently being installed.
38269781SMoriah.Waterland@Sun.COM 	 * - if the path being checked is not the package install root, then
38279781SMoriah.Waterland@Sun.COM 	 *   the path needs to be further analyzed to determine what it may
38289781SMoriah.Waterland@Sun.COM 	 *   be referring to.
38299781SMoriah.Waterland@Sun.COM 	 */
38309781SMoriah.Waterland@Sun.COM 
38319781SMoriah.Waterland@Sun.COM 	a = getenv(ENV_VAR_INITIAL_INSTALL);
38329781SMoriah.Waterland@Sun.COM 	if ((a != NULL) && (strcasecmp(a, "true") == 0)) {
38339781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_initialInstall = B_TRUE;
38349781SMoriah.Waterland@Sun.COM 	}
38359781SMoriah.Waterland@Sun.COM 
38369781SMoriah.Waterland@Sun.COM 	/* get current zone name */
38379781SMoriah.Waterland@Sun.COM 
38389781SMoriah.Waterland@Sun.COM 	r = getZoneName(&(*r_gdt)->gd_zoneName);
38399781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
38409781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_zoneName = "";
38419781SMoriah.Waterland@Sun.COM 	}
38429781SMoriah.Waterland@Sun.COM 
38439781SMoriah.Waterland@Sun.COM 	/*
38449781SMoriah.Waterland@Sun.COM 	 * get zone installation status:
38459781SMoriah.Waterland@Sun.COM 	 * - If the package install zone name is not set, then an installation
38469781SMoriah.Waterland@Sun.COM 	 *   of a global zone, or of a non-global zone, is not underway.
38479781SMoriah.Waterland@Sun.COM 	 * - If the package install zone name is set to "global", then an
38489781SMoriah.Waterland@Sun.COM 	 *   installation of a global zone is underway. In this case, no path
38499781SMoriah.Waterland@Sun.COM 	 *   can be a netinstall image, diskless client, mounted miniroot,
38509781SMoriah.Waterland@Sun.COM 	 *   non-global zone, the current running system, alternative root,
38519781SMoriah.Waterland@Sun.COM 	 *   or alternative boot environment.
38529781SMoriah.Waterland@Sun.COM 	 * - If the package install zone name is set to a value other than
38539781SMoriah.Waterland@Sun.COM 	 *   "global", then an installation of a non-global zone with that name
38549781SMoriah.Waterland@Sun.COM 	 *   is underway.  In this case, no path can be a netinstall image,
38559781SMoriah.Waterland@Sun.COM 	 *   diskless client, mounted miniroot, global zone, the current
38569781SMoriah.Waterland@Sun.COM 	 *   running system, alternative root, or alternative boot environment.
38579781SMoriah.Waterland@Sun.COM 	 */
38589781SMoriah.Waterland@Sun.COM 
38599781SMoriah.Waterland@Sun.COM 	a = getenv(ENV_VAR_PKGZONENAME);
38609781SMoriah.Waterland@Sun.COM 	if ((a == NULL) || (*a == '\0')) {
38619781SMoriah.Waterland@Sun.COM 		/* not installing a zone */
38629781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_globalZoneInstall = B_FALSE;
38639781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_nonglobalZoneInstall = B_FALSE;
38649781SMoriah.Waterland@Sun.COM 	} else if (strcmp(a, GLOBAL_ZONENAME) == 0) {
38659781SMoriah.Waterland@Sun.COM 		/* installing a global zone */
38669781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_globalZoneInstall = B_TRUE;
38679781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_nonglobalZoneInstall = B_FALSE;
38689781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_zoneName = a;
38699781SMoriah.Waterland@Sun.COM 	} else {
38709781SMoriah.Waterland@Sun.COM 		/* installing a non-global zone by that name */
38719781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_globalZoneInstall = B_FALSE;
38729781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_nonglobalZoneInstall = B_TRUE;
38739781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_zoneName = a;
38749781SMoriah.Waterland@Sun.COM 	}
38759781SMoriah.Waterland@Sun.COM 
38769781SMoriah.Waterland@Sun.COM 	/*
38779781SMoriah.Waterland@Sun.COM 	 * get package install root. If it doesn't exist check for
38789781SMoriah.Waterland@Sun.COM 	 * patch install root (ROOTDIR)
38799781SMoriah.Waterland@Sun.COM 	 */
38809781SMoriah.Waterland@Sun.COM 
38819781SMoriah.Waterland@Sun.COM 	a = getenv(ENV_VAR_PKGROOT);
38829781SMoriah.Waterland@Sun.COM 	if ((a != NULL) && (*a != '\0')) {
38839781SMoriah.Waterland@Sun.COM 		(*r_gdt)->gd_installRoot = a;
38849781SMoriah.Waterland@Sun.COM 	} else {
38859781SMoriah.Waterland@Sun.COM 		a = getenv(ENV_VAR_PATCHROOT);
38869781SMoriah.Waterland@Sun.COM 		if ((a != NULL) && (*a != '\0')) {
38879781SMoriah.Waterland@Sun.COM 			(*r_gdt)->gd_installRoot = a;
38889781SMoriah.Waterland@Sun.COM 		} else {
38899781SMoriah.Waterland@Sun.COM 			(*r_gdt)->gd_installRoot = "/";
38909781SMoriah.Waterland@Sun.COM 		}
38919781SMoriah.Waterland@Sun.COM 	}
38929781SMoriah.Waterland@Sun.COM 
38939781SMoriah.Waterland@Sun.COM 	/*
38949781SMoriah.Waterland@Sun.COM 	 * get patch client version: always set if $ROOTDIR != / and
38959781SMoriah.Waterland@Sun.COM 	 * the $ROOTDIR/var/sadm/softinfo/INST_RELEASE file exists.
38969781SMoriah.Waterland@Sun.COM 	 */
38979781SMoriah.Waterland@Sun.COM 
38989781SMoriah.Waterland@Sun.COM 	a = getenv(ENV_VAR_PATCH_CLIENTVER);
38999781SMoriah.Waterland@Sun.COM 	(*r_gdt)->gd_patchClientVersion = (a ? a : "");
39009781SMoriah.Waterland@Sun.COM 
39019781SMoriah.Waterland@Sun.COM 	/* get the global data environment variable */
39029781SMoriah.Waterland@Sun.COM 
39039781SMoriah.Waterland@Sun.COM 	a = getenv(a_envVar);
39049781SMoriah.Waterland@Sun.COM 
39059781SMoriah.Waterland@Sun.COM 	/* if no data then issue warning and return success */
39069781SMoriah.Waterland@Sun.COM 
39079781SMoriah.Waterland@Sun.COM 	if ((a == NULL) || (*a_envVar == '\0')) {
39089781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_DEBUG, DBG_NO_GLOBAL_DATA_AVAILABLE, a_envVar);
39099781SMoriah.Waterland@Sun.COM 		return (R_SUCCESS);
39109781SMoriah.Waterland@Sun.COM 	}
39119781SMoriah.Waterland@Sun.COM 
39129781SMoriah.Waterland@Sun.COM 	/* data present - parse into SML structure */
39139781SMoriah.Waterland@Sun.COM 
39149781SMoriah.Waterland@Sun.COM 	log_msg(LOG_MSG_DEBUG, DBG_PARSE_GLOBAL, a);
39159781SMoriah.Waterland@Sun.COM 
39169781SMoriah.Waterland@Sun.COM 	r = smlConvertStringToTag(&tag, a);
39179781SMoriah.Waterland@Sun.COM 	if (r != R_SUCCESS) {
39189781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_ERR, ERR_CANNOT_PARSE_GLOBAL_DATA, a);
39199781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
39209781SMoriah.Waterland@Sun.COM 	}
39219781SMoriah.Waterland@Sun.COM 
39229781SMoriah.Waterland@Sun.COM 	smlDbgPrintTag(tag, DBG_PARSED_ENVIRONMENT, a_envVar);
39239781SMoriah.Waterland@Sun.COM 
39249781SMoriah.Waterland@Sun.COM 	/* fill in global data structure */
39259781SMoriah.Waterland@Sun.COM 
39269781SMoriah.Waterland@Sun.COM 	/* find the environment condition information structure */
39279781SMoriah.Waterland@Sun.COM 
39289781SMoriah.Waterland@Sun.COM 	ntag = smlGetTagByName(tag, 0, TAG_COND_TOPLEVEL);
39299781SMoriah.Waterland@Sun.COM 	if (ntag == SML_TAG__NULL) {
39309781SMoriah.Waterland@Sun.COM 		log_msg(LOG_MSG_WRN, WRN_PARSED_DATA_MISSING,
39319781SMoriah.Waterland@Sun.COM 			TAG_COND_TOPLEVEL);
39329781SMoriah.Waterland@Sun.COM 		return (R_FAILURE);
39339781SMoriah.Waterland@Sun.COM 	}
39349781SMoriah.Waterland@Sun.COM 
39359781SMoriah.Waterland@Sun.COM 	/*
39369781SMoriah.Waterland@Sun.COM 	 * data found - extract what we know about
39379781SMoriah.Waterland@Sun.COM 	 */
39389781SMoriah.Waterland@Sun.COM 
39399781SMoriah.Waterland@Sun.COM 	/* parent zone name */
39409781SMoriah.Waterland@Sun.COM 
39419781SMoriah.Waterland@Sun.COM 	a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_NAME);
39429781SMoriah.Waterland@Sun.COM 	(*r_gdt)->gd_parentZoneName = a;
39439781SMoriah.Waterland@Sun.COM 
39449781SMoriah.Waterland@Sun.COM 	/* parent zone type */
39459781SMoriah.Waterland@Sun.COM 
39469781SMoriah.Waterland@Sun.COM 	a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_TYPE);
39479781SMoriah.Waterland@Sun.COM 	(*r_gdt)->gd_parentZoneType = a;
39489781SMoriah.Waterland@Sun.COM 
39499781SMoriah.Waterland@Sun.COM 	/* current zone name */
39509781SMoriah.Waterland@Sun.COM 
39519781SMoriah.Waterland@Sun.COM 	a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE,
39529781SMoriah.Waterland@Sun.COM 		TAG_COND_ZONE_NAME);
39539781SMoriah.Waterland@Sun.COM 	(*r_gdt)->gd_currentZoneName = a;
39549781SMoriah.Waterland@Sun.COM 
39559781SMoriah.Waterland@Sun.COM 	/* current zone type */
39569781SMoriah.Waterland@Sun.COM 
39579781SMoriah.Waterland@Sun.COM 	a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE,
39589781SMoriah.Waterland@Sun.COM 		TAG_COND_ZONE_TYPE);
39599781SMoriah.Waterland@Sun.COM 	(*r_gdt)->gd_currentZoneType = a;
39609781SMoriah.Waterland@Sun.COM 
39619781SMoriah.Waterland@Sun.COM 	return (R_SUCCESS);
39629781SMoriah.Waterland@Sun.COM }
39639781SMoriah.Waterland@Sun.COM 
39649781SMoriah.Waterland@Sun.COM /*
39659781SMoriah.Waterland@Sun.COM  * Name:	dumpGlobalData
39669781SMoriah.Waterland@Sun.COM  * Description:	dump global data structure using echoDebug
39679781SMoriah.Waterland@Sun.COM  * Arguments:	a_gdt - pointer to global data structure to dump
39689781SMoriah.Waterland@Sun.COM  * Outputs:	echoDebug is called to output global data strucutre information
39699781SMoriah.Waterland@Sun.COM  * Returns:	void
39709781SMoriah.Waterland@Sun.COM  */
39719781SMoriah.Waterland@Sun.COM 
39729781SMoriah.Waterland@Sun.COM static void
dumpGlobalData(GLOBALDATA_T * a_gdt)39739781SMoriah.Waterland@Sun.COM dumpGlobalData(GLOBALDATA_T *a_gdt)
39749781SMoriah.Waterland@Sun.COM {
39759781SMoriah.Waterland@Sun.COM 	/* entry assertions */
39769781SMoriah.Waterland@Sun.COM 
39779781SMoriah.Waterland@Sun.COM 	assert(a_gdt != (GLOBALDATA_T *)NULL);
39789781SMoriah.Waterland@Sun.COM 
39799781SMoriah.Waterland@Sun.COM 	/* debugging enabled, dump the global data structure */
39809781SMoriah.Waterland@Sun.COM 
39819781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DUMP_GLOBAL_ENTRY);
39829781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DUMP_GLOBAL_PARENT_ZONE,
39839781SMoriah.Waterland@Sun.COM 		a_gdt->gd_parentZoneName ? a_gdt->gd_parentZoneName : "",
39849781SMoriah.Waterland@Sun.COM 		a_gdt->gd_parentZoneType ? a_gdt->gd_parentZoneType : "");
39859781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DUMP_GLOBAL_CURRENT_ZONE,
39869781SMoriah.Waterland@Sun.COM 		a_gdt->gd_currentZoneName ? a_gdt->gd_currentZoneName : "",
39879781SMoriah.Waterland@Sun.COM 		a_gdt->gd_currentZoneType ? a_gdt->gd_currentZoneType : "");
39889781SMoriah.Waterland@Sun.COM 
39899781SMoriah.Waterland@Sun.COM }
39909781SMoriah.Waterland@Sun.COM 
39919781SMoriah.Waterland@Sun.COM /*
39929781SMoriah.Waterland@Sun.COM  * Name:	recursionCheck
39939781SMoriah.Waterland@Sun.COM  * Description:	prevent recursive calling of functions
39949781SMoriah.Waterland@Sun.COM  * Arguments:	r_recursion - pointer to int recursion counter
39959781SMoriah.Waterland@Sun.COM  *		a_function - pointer to name of function
39969781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - function is recursively called
39979781SMoriah.Waterland@Sun.COM  *		B_FALSE - function not recursively called
39989781SMoriah.Waterland@Sun.COM  */
39999781SMoriah.Waterland@Sun.COM 
40009781SMoriah.Waterland@Sun.COM static boolean_t
recursionCheck(int * r_recursion,char * a_function)40019781SMoriah.Waterland@Sun.COM recursionCheck(int *r_recursion, char *a_function)
40029781SMoriah.Waterland@Sun.COM {
40039781SMoriah.Waterland@Sun.COM 	/* prevent recursion */
40049781SMoriah.Waterland@Sun.COM 
40059781SMoriah.Waterland@Sun.COM 	(*r_recursion)++;
40069781SMoriah.Waterland@Sun.COM 	if (*r_recursion > 1) {
40079781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_RECURSION, a_function, *r_recursion);
40089781SMoriah.Waterland@Sun.COM 		(*r_recursion)--;
40099781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
40109781SMoriah.Waterland@Sun.COM 	}
40119781SMoriah.Waterland@Sun.COM 
40129781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_NO_RECURSION, a_function);
40139781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
40149781SMoriah.Waterland@Sun.COM }
40159781SMoriah.Waterland@Sun.COM 
40169781SMoriah.Waterland@Sun.COM /*
40179781SMoriah.Waterland@Sun.COM  * Name:	quit
40189781SMoriah.Waterland@Sun.COM  * Description:	cleanup and exit
40199781SMoriah.Waterland@Sun.COM  * Arguments:	a_retcode - the code to use to determine final exit status;
40209781SMoriah.Waterland@Sun.COM  *			if this is NOT "99" and if a "ckreturnFunc" is
40219781SMoriah.Waterland@Sun.COM  *			set, then that function is called with a_retcode
40229781SMoriah.Waterland@Sun.COM  *			to set the final exit status.
40239781SMoriah.Waterland@Sun.COM  *		Valid values are:
40249781SMoriah.Waterland@Sun.COM  *		0 - success
40259781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
40269781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
40279781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
40289781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
40299781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
40309781SMoriah.Waterland@Sun.COM  *		"10" is added to indicate "immediate reboot required"
40319781SMoriah.Waterland@Sun.COM  *		"20" is be added to indicate "reboot after install required"
40329781SMoriah.Waterland@Sun.COM  *		99 - do not interpret the code - just exit "99"
40339781SMoriah.Waterland@Sun.COM  * Returns:	<<this function does not return - calls exit()>>
40349781SMoriah.Waterland@Sun.COM  * NOTE:	This is needed because libinst functions can call "quit(99)"
40359781SMoriah.Waterland@Sun.COM  *		to force an error exit.
40369781SMoriah.Waterland@Sun.COM  */
40379781SMoriah.Waterland@Sun.COM 
40389781SMoriah.Waterland@Sun.COM void
quit(int a_retcode)40399781SMoriah.Waterland@Sun.COM quit(int a_retcode)
40409781SMoriah.Waterland@Sun.COM {
40419781SMoriah.Waterland@Sun.COM 	/* process return code if not quit(99) */
40429781SMoriah.Waterland@Sun.COM 
40439781SMoriah.Waterland@Sun.COM 	if (a_retcode == 99) {
40449781SMoriah.Waterland@Sun.COM 		exit(0x7f);	/* processing error (127) */
40459781SMoriah.Waterland@Sun.COM 	}
40469781SMoriah.Waterland@Sun.COM 
40479781SMoriah.Waterland@Sun.COM 	exit(R_FAILURE);
40489781SMoriah.Waterland@Sun.COM }
4049