xref: /titanic_44/usr/src/cmd/svr4pkg/libinst/pkgops.c (revision 6e1ae2a33c618c4c2b14aec7d2f21743ddea5837)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
225c51f124SMoriah Waterland /*
23*6e1ae2a3SGary Pennington  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
245c51f124SMoriah Waterland  */
255c51f124SMoriah Waterland 
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland #include <stdio.h>
285c51f124SMoriah Waterland #include <limits.h>
295c51f124SMoriah Waterland #include <stdlib.h>
305c51f124SMoriah Waterland #include <unistd.h>
315c51f124SMoriah Waterland #include <string.h>
325c51f124SMoriah Waterland #include <fcntl.h>
335c51f124SMoriah Waterland #include <sys/types.h>
345c51f124SMoriah Waterland #include <sys/stat.h>
355c51f124SMoriah Waterland #include <signal.h>
365c51f124SMoriah Waterland #include <errno.h>
375c51f124SMoriah Waterland #include <assert.h>
385c51f124SMoriah Waterland #include <pkgdev.h>
395c51f124SMoriah Waterland #include <pkginfo.h>
405c51f124SMoriah Waterland #include <pkglocs.h>
415c51f124SMoriah Waterland #include <locale.h>
425c51f124SMoriah Waterland #include <libintl.h>
435c51f124SMoriah Waterland #include <instzones_api.h>
445c51f124SMoriah Waterland #include <pkglib.h>
455c51f124SMoriah Waterland #include <install.h>
465c51f124SMoriah Waterland #include <libinst.h>
475c51f124SMoriah Waterland #include <libadm.h>
485c51f124SMoriah Waterland #include <messages.h>
495c51f124SMoriah Waterland 
505c51f124SMoriah Waterland /* commands to execute */
515c51f124SMoriah Waterland 
525c51f124SMoriah Waterland #define	PKGINFO_CMD	"/usr/bin/pkginfo"
535c51f124SMoriah Waterland 
545c51f124SMoriah Waterland #define	GLOBALZONE_ONLY_PACKAGE_FILE_PATH	\
555c51f124SMoriah Waterland 					"/var/sadm/install/gz-only-packages"
565c51f124SMoriah Waterland 
575c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
585c51f124SMoriah Waterland #define	TEXT_DOMAIN	"SYS_TEST"
595c51f124SMoriah Waterland #endif
605c51f124SMoriah Waterland 
615c51f124SMoriah Waterland /*
625c51f124SMoriah Waterland  * forward declarations
635c51f124SMoriah Waterland  */
645c51f124SMoriah Waterland 
655c51f124SMoriah Waterland static void		_pkginfoInit(struct pkginfo *a_info);
665c51f124SMoriah Waterland static struct pkginfo	*_pkginfoFactory(void);
675c51f124SMoriah Waterland static char		**thisZonePackages;
685c51f124SMoriah Waterland static int		numThisZonePackages;
695c51f124SMoriah Waterland 
705c51f124SMoriah Waterland /*
715c51f124SMoriah Waterland  * *****************************************************************************
725c51f124SMoriah Waterland  * global external (public) functions
735c51f124SMoriah Waterland  * *****************************************************************************
745c51f124SMoriah Waterland  */
755c51f124SMoriah Waterland 
765c51f124SMoriah Waterland /*
775c51f124SMoriah Waterland  * Name:	pkginfoFree
785c51f124SMoriah Waterland  * Description:	free pkginfo structure returned from various functions
795c51f124SMoriah Waterland  * Arguments:	r_info - pointer to pointer to pkginfo structure to free
805c51f124SMoriah Waterland  * Returns:	void
815c51f124SMoriah Waterland  */
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland void
pkginfoFree(struct pkginfo ** r_info)845c51f124SMoriah Waterland pkginfoFree(struct pkginfo **r_info)
855c51f124SMoriah Waterland {
865c51f124SMoriah Waterland 	struct pkginfo	*pinfo;
875c51f124SMoriah Waterland 
885c51f124SMoriah Waterland 	/* entry assertions */
895c51f124SMoriah Waterland 
905c51f124SMoriah Waterland 	assert(r_info != (struct pkginfo **)NULL);
915c51f124SMoriah Waterland 
925c51f124SMoriah Waterland 	/* localize reference to info structure to free */
935c51f124SMoriah Waterland 
945c51f124SMoriah Waterland 	pinfo = *r_info;
955c51f124SMoriah Waterland 
965c51f124SMoriah Waterland 	/* reset callers handle to info structure */
975c51f124SMoriah Waterland 
985c51f124SMoriah Waterland 	*r_info = (struct pkginfo *)NULL;
995c51f124SMoriah Waterland 
1005c51f124SMoriah Waterland 	assert(pinfo != (struct pkginfo *)NULL);
1015c51f124SMoriah Waterland 
1025c51f124SMoriah Waterland 	/* free up contents of the structure */
1035c51f124SMoriah Waterland 
1045c51f124SMoriah Waterland 	_pkginfoInit(pinfo);
1055c51f124SMoriah Waterland 
1065c51f124SMoriah Waterland 	/* free up structure itself */
1075c51f124SMoriah Waterland 
1085c51f124SMoriah Waterland 	(void) free(pinfo);
1095c51f124SMoriah Waterland }
1105c51f124SMoriah Waterland 
1115c51f124SMoriah Waterland /*
1125c51f124SMoriah Waterland  * Name:	pkginfoIsPkgInstalled
1135c51f124SMoriah Waterland  * Description:	determine if specified package is installed, return pkginfo
1145c51f124SMoriah Waterland  *		structure describing package if package is installed
1155c51f124SMoriah Waterland  * Arguments:	r_pinfo - pointer to pointer to pkginfo structure
1165c51f124SMoriah Waterland  *			If this pointer is NOT null:
1175c51f124SMoriah Waterland  *			-On success, this handle is filled in with a pointer
1185c51f124SMoriah Waterland  *			--to a newly allocated pkginfo structure describing
1195c51f124SMoriah Waterland  *			--the package discovered
1205c51f124SMoriah Waterland  *			-On failure, this handle is filled with NULL
1215c51f124SMoriah Waterland  *			If this pointer is NULL:
1225c51f124SMoriah Waterland  *			-no pkginfo structure is returned on success.
1235c51f124SMoriah Waterland  *		a_pkgInst - package instance (name) to lookup
1245c51f124SMoriah Waterland  * Returns:	boolean_t
1255c51f124SMoriah Waterland  *			B_TRUE - package installed, pkginfo returned
1265c51f124SMoriah Waterland  *			B_FALSE - package not installed, no pkginfo returned
1275c51f124SMoriah Waterland  * NOTE:	This function returns the first instance of package that
1285c51f124SMoriah Waterland  *		is installed - see pkginfo() function for details
1295c51f124SMoriah Waterland  * NOTE:    	Any pkginfo structure returned is placed in new storage for the
1305c51f124SMoriah Waterland  *		calling function. The caller must use 'pkginfoFree' to dispose
1315c51f124SMoriah Waterland  *		of the storage once the pkginfo structure is no longer needed.
1325c51f124SMoriah Waterland  */
1335c51f124SMoriah Waterland 
1345c51f124SMoriah Waterland boolean_t
pkginfoIsPkgInstalled(struct pkginfo ** r_pinfo,char * a_pkgInst)1355c51f124SMoriah Waterland pkginfoIsPkgInstalled(struct pkginfo **r_pinfo, char *a_pkgInst)
1365c51f124SMoriah Waterland {
1375c51f124SMoriah Waterland 	int		r;
1385c51f124SMoriah Waterland 	struct pkginfo	*pinf;
1395c51f124SMoriah Waterland 
1405c51f124SMoriah Waterland 	/* entry assertions */
1415c51f124SMoriah Waterland 
1425c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
1435c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
1445c51f124SMoriah Waterland 
1455c51f124SMoriah Waterland 	/* reset returned pkginfo structure handle */
1465c51f124SMoriah Waterland 
1475c51f124SMoriah Waterland 	if (r_pinfo != (struct pkginfo **)NULL) {
1485c51f124SMoriah Waterland 		*r_pinfo = (struct pkginfo *)NULL;
1495c51f124SMoriah Waterland 	}
1505c51f124SMoriah Waterland 
1515c51f124SMoriah Waterland 	/* allocate a new pinfo structure for use in the call to pkginfo */
1525c51f124SMoriah Waterland 
1535c51f124SMoriah Waterland 	pinf = _pkginfoFactory();
1545c51f124SMoriah Waterland 
1555c51f124SMoriah Waterland 	/* lookup the specified package */
1565c51f124SMoriah Waterland 
1575c51f124SMoriah Waterland 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
1585c51f124SMoriah Waterland 	r = pkginfo(pinf, a_pkgInst, NULL, NULL);
1595c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, a_pkgInst, r);
1605c51f124SMoriah Waterland 
1615c51f124SMoriah Waterland 	if (r_pinfo != (struct pkginfo **)NULL) {
1625c51f124SMoriah Waterland 		*r_pinfo = pinf;
1635c51f124SMoriah Waterland 	} else {
1645c51f124SMoriah Waterland 		/* free pkginfo structure */
1655c51f124SMoriah Waterland 		pkginfoFree(&pinf);
1665c51f124SMoriah Waterland 	}
1675c51f124SMoriah Waterland 
1685c51f124SMoriah Waterland 	return (r == 0 ? B_TRUE : B_FALSE);
1695c51f124SMoriah Waterland }
1705c51f124SMoriah Waterland 
1715c51f124SMoriah Waterland /*
1725c51f124SMoriah Waterland  * Name:	pkgOpenInGzOnlyFile
1735c51f124SMoriah Waterland  * Description:	Open the global zone only package list file
1745c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
1755c51f124SMoriah Waterland  *			where the global zone only package list file is
1765c51f124SMoriah Waterland  *			located - NULL is the same as "/"
1775c51f124SMoriah Waterland  * Returns:	FILE *
1785c51f124SMoriah Waterland  *			== NULL - failure - file not open
1795c51f124SMoriah Waterland  *			!= NULL - success - file pointer returned
1805c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
1815c51f124SMoriah Waterland  */
1825c51f124SMoriah Waterland 
1835c51f124SMoriah Waterland FILE *
pkgOpenInGzOnlyFile(char * a_rootPath)1845c51f124SMoriah Waterland pkgOpenInGzOnlyFile(char *a_rootPath)
1855c51f124SMoriah Waterland {
1865c51f124SMoriah Waterland 	FILE	*pkgingzonlyFP;
1875c51f124SMoriah Waterland 	char	pkgingzonlyPath[PATH_MAX];
1885c51f124SMoriah Waterland 	int	len;
1895c51f124SMoriah Waterland 
1905c51f124SMoriah Waterland 	/* normalize root path */
1915c51f124SMoriah Waterland 
1925c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
1935c51f124SMoriah Waterland 		a_rootPath = "";
1945c51f124SMoriah Waterland 	}
1955c51f124SMoriah Waterland 
1965c51f124SMoriah Waterland 	/* generate path to glocal zone only list file */
1975c51f124SMoriah Waterland 
1985c51f124SMoriah Waterland 	len = snprintf(pkgingzonlyPath, sizeof (pkgingzonlyPath), "%s/%s",
1995c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
2005c51f124SMoriah Waterland 	if (len > sizeof (pkgingzonlyPath)) {
2015c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
2025c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
2035c51f124SMoriah Waterland 		return ((FILE *)NULL);
2045c51f124SMoriah Waterland 	}
2055c51f124SMoriah Waterland 
2065c51f124SMoriah Waterland 	/* open global zone only list file */
2075c51f124SMoriah Waterland 
2085c51f124SMoriah Waterland 	pkgingzonlyFP = fopen(pkgingzonlyPath, "r+");
2095c51f124SMoriah Waterland 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno == ENOENT)) {
2105c51f124SMoriah Waterland 		pkgingzonlyFP = fopen(pkgingzonlyPath, "w+");
2115c51f124SMoriah Waterland 	}
2125c51f124SMoriah Waterland 
2135c51f124SMoriah Waterland 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno != ENOENT)) {
2145c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, pkgingzonlyPath,
2155c51f124SMoriah Waterland 				strerror(errno));
2165c51f124SMoriah Waterland 		return ((FILE *)NULL);
2175c51f124SMoriah Waterland 	}
2185c51f124SMoriah Waterland 
2195c51f124SMoriah Waterland 	/* success - return FILE pointer open on global zone only list file */
2205c51f124SMoriah Waterland 
2215c51f124SMoriah Waterland 	return (pkgingzonlyFP);
2225c51f124SMoriah Waterland }
2235c51f124SMoriah Waterland 
2245c51f124SMoriah Waterland /*
2255c51f124SMoriah Waterland  * Name:	pkgIsPkgInGzOnly
2265c51f124SMoriah Waterland  * Description:	determine if package is recorded as "in global zone only"
2275c51f124SMoriah Waterland  *		by opening the appropriate files and searching for the
2285c51f124SMoriah Waterland  *		specified package
2295c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
2305c51f124SMoriah Waterland  *			where the global zone only package list file is
2315c51f124SMoriah Waterland  *			located - NULL is the same as "/"
2325c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
2335c51f124SMoriah Waterland  *			(name) of the package to lookup
2345c51f124SMoriah Waterland  * Returns:	boolean_t
2355c51f124SMoriah Waterland  *			B_TRUE - package is recorded as "in global zone only"
2365c51f124SMoriah Waterland  *			B_FALSE - package is NOT recorded as "in gz only"
2375c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
2385c51f124SMoriah Waterland  */
2395c51f124SMoriah Waterland 
2405c51f124SMoriah Waterland boolean_t
pkgIsPkgInGzOnly(char * a_rootPath,char * a_pkgInst)2415c51f124SMoriah Waterland pkgIsPkgInGzOnly(char *a_rootPath, char *a_pkgInst)
2425c51f124SMoriah Waterland {
2435c51f124SMoriah Waterland 	FILE		*fp;
2445c51f124SMoriah Waterland 	boolean_t	in_gz_only;
2455c51f124SMoriah Waterland 
2465c51f124SMoriah Waterland 	/* normalize root path */
2475c51f124SMoriah Waterland 
2485c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
2495c51f124SMoriah Waterland 		a_rootPath = "";
2505c51f124SMoriah Waterland 	}
2515c51f124SMoriah Waterland 
2525c51f124SMoriah Waterland 	/* open the global zone only package list file */
2535c51f124SMoriah Waterland 
2545c51f124SMoriah Waterland 	fp = pkgOpenInGzOnlyFile(a_rootPath);
2555c51f124SMoriah Waterland 	if (fp == (FILE *)NULL) {
2565c51f124SMoriah Waterland 		echoDebug(ERR_PKGOPS_CANNOT_OPEN_GZONLY,
2575c51f124SMoriah Waterland 				a_rootPath ? a_rootPath : "/");
2585c51f124SMoriah Waterland 		return (B_FALSE);
2595c51f124SMoriah Waterland 	}
2605c51f124SMoriah Waterland 
2615c51f124SMoriah Waterland 	/* is the package recorded as "in global zone only" ? */
2625c51f124SMoriah Waterland 
2635c51f124SMoriah Waterland 	in_gz_only = pkgIsPkgInGzOnlyFP(fp, a_pkgInst);
2645c51f124SMoriah Waterland 
2655c51f124SMoriah Waterland 	/* close the global zone only package list file */
2665c51f124SMoriah Waterland 
2675c51f124SMoriah Waterland 	(void) fclose(fp);
2685c51f124SMoriah Waterland 
2695c51f124SMoriah Waterland 	/* return results */
2705c51f124SMoriah Waterland 
2715c51f124SMoriah Waterland 	return (in_gz_only);
2725c51f124SMoriah Waterland }
2735c51f124SMoriah Waterland 
2745c51f124SMoriah Waterland /*
2755c51f124SMoriah Waterland  * Name:	pkgIsPkgInGzOnly
2765c51f124SMoriah Waterland  * Description:	determine if package is recorded as "in global zone only"
2775c51f124SMoriah Waterland  *		by searching the specified open FILE for the specified package
2785c51f124SMoriah Waterland  * Arguments:	a_fp - pointer to FILE handle open on file to search
2795c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
2805c51f124SMoriah Waterland  *			(name) of the package to lookup
2815c51f124SMoriah Waterland  * Returns:	boolean_t
2825c51f124SMoriah Waterland  *			B_TRUE - package is recorded as "in global zone only"
2835c51f124SMoriah Waterland  *			B_FALSE - package is NOT recorded as "in gz only"
2845c51f124SMoriah Waterland  */
2855c51f124SMoriah Waterland 
2865c51f124SMoriah Waterland boolean_t
pkgIsPkgInGzOnlyFP(FILE * a_fp,char * a_pkgInst)2875c51f124SMoriah Waterland pkgIsPkgInGzOnlyFP(FILE *a_fp, char *a_pkgInst)
2885c51f124SMoriah Waterland {
2895c51f124SMoriah Waterland 	char	line[PATH_MAX+1];
2905c51f124SMoriah Waterland 
2915c51f124SMoriah Waterland 	/* entry assertions */
2925c51f124SMoriah Waterland 
2935c51f124SMoriah Waterland 	assert(a_fp != (FILE *)NULL);
2945c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
2955c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
2965c51f124SMoriah Waterland 
2975c51f124SMoriah Waterland 	/* rewind the file to the beginning */
2985c51f124SMoriah Waterland 
2995c51f124SMoriah Waterland 	rewind(a_fp);
3005c51f124SMoriah Waterland 
3015c51f124SMoriah Waterland 	/* read the file line by line searching for the specified package */
3025c51f124SMoriah Waterland 
3035c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), a_fp) != (char *)NULL) {
3045c51f124SMoriah Waterland 		int	len;
3055c51f124SMoriah Waterland 
3065c51f124SMoriah Waterland 		/* strip off trailing newlines */
3075c51f124SMoriah Waterland 		len = strlen(line);
3085c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
3095c51f124SMoriah Waterland 			line[--len] = '\0';
3105c51f124SMoriah Waterland 		}
3115c51f124SMoriah Waterland 
3125c51f124SMoriah Waterland 		/* ignore blank and comment lines */
3135c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
3145c51f124SMoriah Waterland 			continue;
3155c51f124SMoriah Waterland 		}
3165c51f124SMoriah Waterland 
3175c51f124SMoriah Waterland 		/* return true if this is the package we are looking for */
3185c51f124SMoriah Waterland 		if (strcmp(a_pkgInst, line) == 0) {
3195c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_PKG_IS_GZONLY, a_pkgInst);
3205c51f124SMoriah Waterland 			return (B_TRUE);
3215c51f124SMoriah Waterland 		}
3225c51f124SMoriah Waterland 	}
3235c51f124SMoriah Waterland 
3245c51f124SMoriah Waterland 	/* end of file - package not found */
3255c51f124SMoriah Waterland 
3265c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PKG_NOT_GZONLY, a_pkgInst);
3275c51f124SMoriah Waterland 
3285c51f124SMoriah Waterland 	return (B_FALSE);
3295c51f124SMoriah Waterland }
3305c51f124SMoriah Waterland 
3315c51f124SMoriah Waterland /*
3325c51f124SMoriah Waterland  * Name:	pkgRemovePackageFromGzonlyList
3335c51f124SMoriah Waterland  * Description:	Remove specified package from the global zone only package list
3345c51f124SMoriah Waterland  *		file located at a specified root path
3355c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
3365c51f124SMoriah Waterland  *			where the global zone only package list file is
3375c51f124SMoriah Waterland  *			located - NULL is the same as "/"
3385c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
3395c51f124SMoriah Waterland  *			(name) of the package to remove
3405c51f124SMoriah Waterland  * Returns:	boolean_t
3415c51f124SMoriah Waterland  *			B_TRUE - package is successfully removed
3425c51f124SMoriah Waterland  *			B_FALSE - failed to remove package from file
3435c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
3445c51f124SMoriah Waterland  */
3455c51f124SMoriah Waterland 
3465c51f124SMoriah Waterland boolean_t
pkgRemovePackageFromGzonlyList(char * a_rootPath,char * a_pkgInst)3475c51f124SMoriah Waterland pkgRemovePackageFromGzonlyList(char *a_rootPath, char *a_pkgInst)
3485c51f124SMoriah Waterland {
3495c51f124SMoriah Waterland 	FILE		*destFP;
3505c51f124SMoriah Waterland 	FILE		*srcFP;
3515c51f124SMoriah Waterland 	boolean_t	pkgremoved = B_FALSE;
3525c51f124SMoriah Waterland 	char		destPath[PATH_MAX];
3535c51f124SMoriah Waterland 	char		line[PATH_MAX+1];
3545c51f124SMoriah Waterland 	char		savePath[PATH_MAX];
3555c51f124SMoriah Waterland 	char		srcPath[PATH_MAX];
3565c51f124SMoriah Waterland 	char		timeb[BUFSIZ];
3575c51f124SMoriah Waterland 	int		len;
3585c51f124SMoriah Waterland 	struct tm	*timep;
3595c51f124SMoriah Waterland 	time_t		clock;
3605c51f124SMoriah Waterland 
3615c51f124SMoriah Waterland 	/* entry assertions */
3625c51f124SMoriah Waterland 
3635c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
3645c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
3655c51f124SMoriah Waterland 
3665c51f124SMoriah Waterland 	/* normalize root path */
3675c51f124SMoriah Waterland 
3685c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
3695c51f124SMoriah Waterland 		a_rootPath = "";
3705c51f124SMoriah Waterland 	}
3715c51f124SMoriah Waterland 
3725c51f124SMoriah Waterland 	/*
3735c51f124SMoriah Waterland 	 * calculate paths to various objects
3745c51f124SMoriah Waterland 	 */
3755c51f124SMoriah Waterland 
3765c51f124SMoriah Waterland 	/* path to current "source" ingzonly file */
3775c51f124SMoriah Waterland 
3785c51f124SMoriah Waterland 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
3795c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3805c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
3815c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
3825c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3835c51f124SMoriah Waterland 		return (B_FALSE);
3845c51f124SMoriah Waterland 	}
3855c51f124SMoriah Waterland 
3865c51f124SMoriah Waterland 	/* path to new "destination" ingzonly file */
3875c51f124SMoriah Waterland 
3885c51f124SMoriah Waterland 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
3895c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3905c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
3915c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
3925c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3935c51f124SMoriah Waterland 		return (B_FALSE);
3945c51f124SMoriah Waterland 	}
3955c51f124SMoriah Waterland 
3965c51f124SMoriah Waterland 	/* path to temporary "saved" ingzonly file */
3975c51f124SMoriah Waterland 
3985c51f124SMoriah Waterland 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
3995c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
4005c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
4015c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
4025c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
4035c51f124SMoriah Waterland 		return (B_FALSE);
4045c51f124SMoriah Waterland 	}
4055c51f124SMoriah Waterland 
4065c51f124SMoriah Waterland 	/* open source file, creating if necessary */
4075c51f124SMoriah Waterland 
4085c51f124SMoriah Waterland 	srcFP = fopen(srcPath, "r+");
4095c51f124SMoriah Waterland 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
4105c51f124SMoriah Waterland 		srcFP = fopen(srcPath, "w+");
4115c51f124SMoriah Waterland 	}
4125c51f124SMoriah Waterland 
4135c51f124SMoriah Waterland 	/* error if could not open/create file */
4145c51f124SMoriah Waterland 
4155c51f124SMoriah Waterland 	if (srcFP == (FILE *)NULL) {
4165c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
4175c51f124SMoriah Waterland 		return (B_FALSE);
4185c51f124SMoriah Waterland 	}
4195c51f124SMoriah Waterland 
4205c51f124SMoriah Waterland 	/* open/create new destination file */
4215c51f124SMoriah Waterland 
4225c51f124SMoriah Waterland 	(void) remove(destPath);
4235c51f124SMoriah Waterland 	destFP = fopen(destPath, "w");
4245c51f124SMoriah Waterland 	if (destFP == (FILE *)NULL) {
4255c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
4265c51f124SMoriah Waterland 		if (srcFP != (FILE *)NULL) {
4275c51f124SMoriah Waterland 			(void) fclose(srcFP);
4285c51f124SMoriah Waterland 		}
4295c51f124SMoriah Waterland 		return (B_FALSE);
4305c51f124SMoriah Waterland 	}
4315c51f124SMoriah Waterland 
4325c51f124SMoriah Waterland 	/* add standard comment to beginning of file */
4335c51f124SMoriah Waterland 
4345c51f124SMoriah Waterland 	(void) time(&clock);
4355c51f124SMoriah Waterland 	timep = localtime(&clock);
4365c51f124SMoriah Waterland 
4375c51f124SMoriah Waterland 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
4385c51f124SMoriah Waterland 
4395c51f124SMoriah Waterland 	/* put standard header at the beginning of the file */
4405c51f124SMoriah Waterland 
4415c51f124SMoriah Waterland 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
4425c51f124SMoriah Waterland 			get_prog_name(), "remove", a_pkgInst, timeb);
4435c51f124SMoriah Waterland 
4445c51f124SMoriah Waterland 	/* read source/write destination - removing specified package */
4455c51f124SMoriah Waterland 
4465c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
4475c51f124SMoriah Waterland 		int	len;
4485c51f124SMoriah Waterland 
4495c51f124SMoriah Waterland 		/* strip off trailing newlines */
4505c51f124SMoriah Waterland 		len = strlen(line);
4515c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
4525c51f124SMoriah Waterland 			line[--len] = '\0';
4535c51f124SMoriah Waterland 		}
4545c51f124SMoriah Waterland 
4555c51f124SMoriah Waterland 		/* ignore blank and comment lines */
4565c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
4575c51f124SMoriah Waterland 			continue;
4585c51f124SMoriah Waterland 		}
4595c51f124SMoriah Waterland 
4605c51f124SMoriah Waterland 		/* add pkg if yet to add and pkg <= line */
4615c51f124SMoriah Waterland 		if ((pkgremoved == B_FALSE) && (strcmp(a_pkgInst, line) == 0)) {
4625c51f124SMoriah Waterland 			pkgremoved = B_TRUE;
4635c51f124SMoriah Waterland 		} else {
4645c51f124SMoriah Waterland 			(void) fprintf(destFP, "%s\n", line);
4655c51f124SMoriah Waterland 		}
4665c51f124SMoriah Waterland 	}
4675c51f124SMoriah Waterland 
4685c51f124SMoriah Waterland 	/* close both files */
4695c51f124SMoriah Waterland 
4705c51f124SMoriah Waterland 	(void) fclose(srcFP);
4715c51f124SMoriah Waterland 
4725c51f124SMoriah Waterland 	(void) fclose(destFP);
4735c51f124SMoriah Waterland 
4745c51f124SMoriah Waterland 	/*
4755c51f124SMoriah Waterland 	 * if package not found there is no need to update the original file
4765c51f124SMoriah Waterland 	 */
4775c51f124SMoriah Waterland 
4785c51f124SMoriah Waterland 	if (pkgremoved == B_FALSE) {
4795c51f124SMoriah Waterland 		(void) unlink(destPath);
4805c51f124SMoriah Waterland 		return (B_TRUE);
4815c51f124SMoriah Waterland 	}
4825c51f124SMoriah Waterland 
4835c51f124SMoriah Waterland 	/*
4845c51f124SMoriah Waterland 	 * Now we want to make a copy of the old gzonly file as a
4855c51f124SMoriah Waterland 	 * fail-safe.
4865c51f124SMoriah Waterland 	 */
4875c51f124SMoriah Waterland 
4885c51f124SMoriah Waterland 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
4895c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
4905c51f124SMoriah Waterland 		(void) remove(destPath);
4915c51f124SMoriah Waterland 		return (B_FALSE);
4925c51f124SMoriah Waterland 	}
4935c51f124SMoriah Waterland 
4945c51f124SMoriah Waterland 	if (link(srcPath, savePath) != 0) {
4955c51f124SMoriah Waterland 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
4965c51f124SMoriah Waterland 		(void) remove(destPath);
4975c51f124SMoriah Waterland 		return (B_FALSE);
4985c51f124SMoriah Waterland 	}
4995c51f124SMoriah Waterland 
5005c51f124SMoriah Waterland 	if (rename(destPath, srcPath) != 0) {
5015c51f124SMoriah Waterland 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
5025c51f124SMoriah Waterland 		if (rename(savePath, srcPath)) {
5035c51f124SMoriah Waterland 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
5045c51f124SMoriah Waterland 		}
5055c51f124SMoriah Waterland 		(void) remove(destPath);
5065c51f124SMoriah Waterland 		return (B_FALSE);
5075c51f124SMoriah Waterland 	}
5085c51f124SMoriah Waterland 
5095c51f124SMoriah Waterland 	if (remove(savePath) != 0) {
5105c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
5115c51f124SMoriah Waterland 	}
5125c51f124SMoriah Waterland 
5135c51f124SMoriah Waterland 	/* successfully removed package */
5145c51f124SMoriah Waterland 
5155c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_REMOVED_GZPKG, a_pkgInst);
5165c51f124SMoriah Waterland 
5175c51f124SMoriah Waterland 	return (B_TRUE);
5185c51f124SMoriah Waterland }
5195c51f124SMoriah Waterland 
5205c51f124SMoriah Waterland /*
5215c51f124SMoriah Waterland  * Name:	pkgAddPackageFromGzonlyList
5225c51f124SMoriah Waterland  * Description:	Add specified package to the global zone only package list
5235c51f124SMoriah Waterland  *		file located at a specified root path
5245c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
5255c51f124SMoriah Waterland  *			where the global zone only package list file is
5265c51f124SMoriah Waterland  *			located - NULL is the same as "/"
5275c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
5285c51f124SMoriah Waterland  *			(name) of the package to add
5295c51f124SMoriah Waterland  * Returns:	boolean_t
5305c51f124SMoriah Waterland  *			B_TRUE - package is successfully added
5315c51f124SMoriah Waterland  *			B_FALSE - failed to add package to the file
5325c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
5335c51f124SMoriah Waterland  */
5345c51f124SMoriah Waterland 
5355c51f124SMoriah Waterland boolean_t
pkgAddPackageToGzonlyList(char * a_pkgInst,char * a_rootPath)5365c51f124SMoriah Waterland pkgAddPackageToGzonlyList(char *a_pkgInst, char *a_rootPath)
5375c51f124SMoriah Waterland {
5385c51f124SMoriah Waterland 	FILE		*destFP;
5395c51f124SMoriah Waterland 	FILE		*srcFP;
5405c51f124SMoriah Waterland 	boolean_t	pkgadded = B_FALSE;
5415c51f124SMoriah Waterland 	char		destPath[PATH_MAX];
5425c51f124SMoriah Waterland 	char		line[PATH_MAX+1];
5435c51f124SMoriah Waterland 	char		savePath[PATH_MAX];
5445c51f124SMoriah Waterland 	char		srcPath[PATH_MAX];
5455c51f124SMoriah Waterland 	char		timeb[BUFSIZ];
5465c51f124SMoriah Waterland 	int		len;
5475c51f124SMoriah Waterland 	struct tm	*timep;
5485c51f124SMoriah Waterland 	time_t		clock;
5495c51f124SMoriah Waterland 
5505c51f124SMoriah Waterland 	/* entry assertions */
5515c51f124SMoriah Waterland 
5525c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
5535c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
5545c51f124SMoriah Waterland 
5555c51f124SMoriah Waterland 	/* normalize root path */
5565c51f124SMoriah Waterland 
5575c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
5585c51f124SMoriah Waterland 		a_rootPath = "";
5595c51f124SMoriah Waterland 	}
5605c51f124SMoriah Waterland 
5615c51f124SMoriah Waterland 	/* entry debugging info */
5625c51f124SMoriah Waterland 
5635c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADDGZPKG, a_pkgInst, a_rootPath);
5645c51f124SMoriah Waterland 
5655c51f124SMoriah Waterland 	/*
5665c51f124SMoriah Waterland 	 * calculate paths to various objects
5675c51f124SMoriah Waterland 	 */
5685c51f124SMoriah Waterland 
5695c51f124SMoriah Waterland 	/* path to current "source" ingzonly file */
5705c51f124SMoriah Waterland 
5715c51f124SMoriah Waterland 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
5725c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5735c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
5745c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5755c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5765c51f124SMoriah Waterland 		return (B_FALSE);
5775c51f124SMoriah Waterland 	}
5785c51f124SMoriah Waterland 
5795c51f124SMoriah Waterland 	/* path to new "destination" ingzonly file */
5805c51f124SMoriah Waterland 
5815c51f124SMoriah Waterland 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
5825c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5835c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
5845c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5855c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5865c51f124SMoriah Waterland 		return (B_FALSE);
5875c51f124SMoriah Waterland 	}
5885c51f124SMoriah Waterland 
5895c51f124SMoriah Waterland 	/* path to temporary "saved" ingzonly file */
5905c51f124SMoriah Waterland 
5915c51f124SMoriah Waterland 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
5925c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5935c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
5945c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5955c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5965c51f124SMoriah Waterland 		return (B_FALSE);
5975c51f124SMoriah Waterland 	}
5985c51f124SMoriah Waterland 
5995c51f124SMoriah Waterland 	/* open source file, creating if necessary */
6005c51f124SMoriah Waterland 
6015c51f124SMoriah Waterland 	srcFP = fopen(srcPath, "r+");
6025c51f124SMoriah Waterland 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
6035c51f124SMoriah Waterland 		srcFP = fopen(srcPath, "w+");
6045c51f124SMoriah Waterland 	}
6055c51f124SMoriah Waterland 
6065c51f124SMoriah Waterland 	/* error if could not open/create file */
6075c51f124SMoriah Waterland 
6085c51f124SMoriah Waterland 	if (srcFP == (FILE *)NULL) {
6095c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
6105c51f124SMoriah Waterland 		return (B_FALSE);
6115c51f124SMoriah Waterland 	}
6125c51f124SMoriah Waterland 
6135c51f124SMoriah Waterland 	/* open/create new destination file */
6145c51f124SMoriah Waterland 
6155c51f124SMoriah Waterland 	(void) remove(destPath);
6165c51f124SMoriah Waterland 	destFP = fopen(destPath, "w");
6175c51f124SMoriah Waterland 	if (destFP == (FILE *)NULL) {
6185c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
6195c51f124SMoriah Waterland 		if (srcFP != (FILE *)NULL) {
6205c51f124SMoriah Waterland 			(void) fclose(srcFP);
6215c51f124SMoriah Waterland 		}
6225c51f124SMoriah Waterland 		return (B_FALSE);
6235c51f124SMoriah Waterland 	}
6245c51f124SMoriah Waterland 
6255c51f124SMoriah Waterland 	/* add standard comment to beginning of file */
6265c51f124SMoriah Waterland 
6275c51f124SMoriah Waterland 	(void) time(&clock);
6285c51f124SMoriah Waterland 	timep = localtime(&clock);
6295c51f124SMoriah Waterland 
6305c51f124SMoriah Waterland 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
6315c51f124SMoriah Waterland 
6325c51f124SMoriah Waterland 	/* put standard header at the beginning of the file */
6335c51f124SMoriah Waterland 
6345c51f124SMoriah Waterland 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
6355c51f124SMoriah Waterland 			get_prog_name(), "add", a_pkgInst, timeb);
6365c51f124SMoriah Waterland 
6375c51f124SMoriah Waterland 	/* read source/write destination; add package at appropriate location */
6385c51f124SMoriah Waterland 
6395c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
6405c51f124SMoriah Waterland 		int	len;
6415c51f124SMoriah Waterland 
6425c51f124SMoriah Waterland 		/* strip off trailing newlines */
6435c51f124SMoriah Waterland 		len = strlen(line);
6445c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
6455c51f124SMoriah Waterland 			line[--len] = '\0';
6465c51f124SMoriah Waterland 		}
6475c51f124SMoriah Waterland 
6485c51f124SMoriah Waterland 		/* ignore blank and comment lines */
6495c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
6505c51f124SMoriah Waterland 			continue;
6515c51f124SMoriah Waterland 		}
6525c51f124SMoriah Waterland 
6535c51f124SMoriah Waterland 		/* add pkg if yet to add and pkg <= line */
6545c51f124SMoriah Waterland 		if ((pkgadded == B_FALSE) && (strcmp(a_pkgInst, line) <= 0)) {
6555c51f124SMoriah Waterland 			if (strcmp(a_pkgInst, line) != 0) {
6565c51f124SMoriah Waterland 				(void) fprintf(destFP, "%s\n", a_pkgInst);
6575c51f124SMoriah Waterland 			}
6585c51f124SMoriah Waterland 			pkgadded = B_TRUE;
6595c51f124SMoriah Waterland 		}
6605c51f124SMoriah Waterland 
6615c51f124SMoriah Waterland 		(void) fprintf(destFP, "%s\n", line);
6625c51f124SMoriah Waterland 	}
6635c51f124SMoriah Waterland 
6645c51f124SMoriah Waterland 	/* if package not added yet, add to end of the file */
6655c51f124SMoriah Waterland 
6665c51f124SMoriah Waterland 	if (pkgadded == B_FALSE) {
6675c51f124SMoriah Waterland 		(void) fprintf(destFP, "%s\n", a_pkgInst);
6685c51f124SMoriah Waterland 	}
6695c51f124SMoriah Waterland 
6705c51f124SMoriah Waterland 	/* close both files */
6715c51f124SMoriah Waterland 
6725c51f124SMoriah Waterland 	(void) fclose(srcFP);
6735c51f124SMoriah Waterland 
6745c51f124SMoriah Waterland 	(void) fclose(destFP);
6755c51f124SMoriah Waterland 
6765c51f124SMoriah Waterland 	/*
6775c51f124SMoriah Waterland 	 * Now we want to make a copy of the old gzonly file as a
6785c51f124SMoriah Waterland 	 * fail-safe.
6795c51f124SMoriah Waterland 	 */
6805c51f124SMoriah Waterland 
6815c51f124SMoriah Waterland 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
6825c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
6835c51f124SMoriah Waterland 		(void) remove(destPath);
6845c51f124SMoriah Waterland 		return (B_FALSE);
6855c51f124SMoriah Waterland 	}
6865c51f124SMoriah Waterland 
6875c51f124SMoriah Waterland 	if (link(srcPath, savePath) != 0) {
6885c51f124SMoriah Waterland 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
6895c51f124SMoriah Waterland 		(void) remove(destPath);
6905c51f124SMoriah Waterland 		return (B_FALSE);
6915c51f124SMoriah Waterland 	}
6925c51f124SMoriah Waterland 
6935c51f124SMoriah Waterland 	if (rename(destPath, srcPath) != 0) {
6945c51f124SMoriah Waterland 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
6955c51f124SMoriah Waterland 		if (rename(savePath, srcPath)) {
6965c51f124SMoriah Waterland 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
6975c51f124SMoriah Waterland 		}
6985c51f124SMoriah Waterland 		(void) remove(destPath);
6995c51f124SMoriah Waterland 		return (B_FALSE);
7005c51f124SMoriah Waterland 	}
7015c51f124SMoriah Waterland 
7025c51f124SMoriah Waterland 	if (remove(savePath) != 0) {
7035c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
7045c51f124SMoriah Waterland 	}
7055c51f124SMoriah Waterland 
7065c51f124SMoriah Waterland 	/* successfully added package */
7075c51f124SMoriah Waterland 
7085c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADDED_GZPKG, a_pkgInst);
7095c51f124SMoriah Waterland 
7105c51f124SMoriah Waterland 	return (B_TRUE);
7115c51f124SMoriah Waterland }
7125c51f124SMoriah Waterland 
7135c51f124SMoriah Waterland /*
7145c51f124SMoriah Waterland  * Name:	pkginfoParamTruth
7155c51f124SMoriah Waterland  * Description:	Search pkginfo file for specified parameter/value pair
7165c51f124SMoriah Waterland  * Arguments:	a_fp - Pointer to FILE handle open on pkginfo file to search
7175c51f124SMoriah Waterland  *		a_param - Pointer to string representing the parameter name
7185c51f124SMoriah Waterland  *			to search for
7195c51f124SMoriah Waterland  *		a_value - Pointer to string representing the "success" value
7205c51f124SMoriah Waterland  *			being searched for
7215c51f124SMoriah Waterland  *		a_default - determine results if parameter NOT found
7225c51f124SMoriah Waterland  *			B_TRUE - parameter is TRUE if not found
7235c51f124SMoriah Waterland  *			B_FALSE - parameter is FALSE if not found
7245c51f124SMoriah Waterland  * Returns:	boolean_t
7255c51f124SMoriah Waterland  *		B_TRUE - the parameter was found and matched the specified value
7265c51f124SMoriah Waterland  *			OR the paramter was not found and a_default == B_TRUE
7275c51f124SMoriah Waterland  *		B_FALSE - the parameter was found and did NOT match the value
7285c51f124SMoriah Waterland  *			OR the paramter was not found and a_default == B_FALSE
7295c51f124SMoriah Waterland  */
7305c51f124SMoriah Waterland 
7315c51f124SMoriah Waterland boolean_t
pkginfoParamTruth(FILE * a_fp,char * a_param,char * a_value,boolean_t a_default)7325c51f124SMoriah Waterland pkginfoParamTruth(FILE *a_fp, char *a_param, char *a_value, boolean_t a_default)
7335c51f124SMoriah Waterland {
7345c51f124SMoriah Waterland 	char		*param;
7355c51f124SMoriah Waterland 	boolean_t	result;
7365c51f124SMoriah Waterland 
7375c51f124SMoriah Waterland 	/* entry assertions */
7385c51f124SMoriah Waterland 
7395c51f124SMoriah Waterland 	assert(a_fp != (FILE *)NULL);
7405c51f124SMoriah Waterland 	assert(a_param != (char *)NULL);
7415c51f124SMoriah Waterland 	assert(*a_param != '\0');
7425c51f124SMoriah Waterland 	assert(a_value != (char *)NULL);
7435c51f124SMoriah Waterland 	assert(*a_value != '\0');
7445c51f124SMoriah Waterland 
7455c51f124SMoriah Waterland 	/* rewind the file to the beginning */
7465c51f124SMoriah Waterland 
7475c51f124SMoriah Waterland 	rewind(a_fp);
7485c51f124SMoriah Waterland 
7495c51f124SMoriah Waterland 	/* search pkginfo file for the specified parameter */
7505c51f124SMoriah Waterland 
7515c51f124SMoriah Waterland 	param = fpkgparam(a_fp, a_param);
7525c51f124SMoriah Waterland 
7535c51f124SMoriah Waterland 	if (param == (char *)NULL) {
7545c51f124SMoriah Waterland 		/* parameter not found - return default */
7555c51f124SMoriah Waterland 		result = a_default;
7565c51f124SMoriah Waterland 	} else if (*param == '\0') {
7575c51f124SMoriah Waterland 		/* parameter found but no value - return default */
7585c51f124SMoriah Waterland 		result = a_default;
7595c51f124SMoriah Waterland 	} else if (strcasecmp(param, a_value) == 0) {
7605c51f124SMoriah Waterland 		/* paramter found - matches value */
7615c51f124SMoriah Waterland 		result = B_TRUE;
7625c51f124SMoriah Waterland 	} else {
7635c51f124SMoriah Waterland 		/* parameter found - does not match value */
7645c51f124SMoriah Waterland 		result = B_FALSE;
7655c51f124SMoriah Waterland 	}
7665c51f124SMoriah Waterland 
7675c51f124SMoriah Waterland 	/* exit debugging info */
7685c51f124SMoriah Waterland 
7695c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PARAMTRUTH_RESULTS,
7705c51f124SMoriah Waterland 		a_param, a_value, a_default == B_TRUE ? "true" : "false",
7715c51f124SMoriah Waterland 		param ? param : "?", result == B_TRUE ? "true" : "false");
7725c51f124SMoriah Waterland 
7735c51f124SMoriah Waterland 	/* if parameter value found, free results */
7745c51f124SMoriah Waterland 
7755c51f124SMoriah Waterland 	if (param != (char *)NULL) {
7765c51f124SMoriah Waterland 		(void) free(param);
7775c51f124SMoriah Waterland 	}
7785c51f124SMoriah Waterland 
7795c51f124SMoriah Waterland 	/* return results of search */
7805c51f124SMoriah Waterland 
7815c51f124SMoriah Waterland 	return (result);
7825c51f124SMoriah Waterland }
7835c51f124SMoriah Waterland 
7845c51f124SMoriah Waterland /*
7855c51f124SMoriah Waterland  * Name:	pkgGetPackageList
7865c51f124SMoriah Waterland  * Description:	Determine list of packages based on list of packages that are
7875c51f124SMoriah Waterland  *		available, category of packages to select, and list of packages
7885c51f124SMoriah Waterland  *		to select.
7895c51f124SMoriah Waterland  * Arguments:	r_pkgList - pointer to pointer to string array where the list
7905c51f124SMoriah Waterland  *			of selected packages will be returned
7915c51f124SMoriah Waterland  *		a_argv - pointer to string array containing list of packages
7925c51f124SMoriah Waterland  *			to select
7935c51f124SMoriah Waterland  *		a_optind - index into string array of first package to select
7945c51f124SMoriah Waterland  *		a_categories - pointer to string representing the categories of
7955c51f124SMoriah Waterland  *			packages to select
7965c51f124SMoriah Waterland  *		a_categoryList - pointer to string array representing a list
7975c51f124SMoriah Waterland  *			of categories to select
7985c51f124SMoriah Waterland  *		a_pkgdev - package dev containing packages that can be selected
7995c51f124SMoriah Waterland  * Returns:	int
8005c51f124SMoriah Waterland  *	== 0  - packages found r_pkgList contains results package list retrieved
8015c51f124SMoriah Waterland  *	== -1 - no packages found (errno == ENOPKG)
8025c51f124SMoriah Waterland  *	!= 0 - "quit" value entered by user
8035c51f124SMoriah Waterland  * NOTE:	If both a category and a list of packages to select are provided
8045c51f124SMoriah Waterland  *		the category is used over the list of packages provided
8055c51f124SMoriah Waterland  * NOTE:	If neither a category nor a list of packages to select are
8065c51f124SMoriah Waterland  *		provided, an error is returned
8075c51f124SMoriah Waterland  */
8085c51f124SMoriah Waterland 
8095c51f124SMoriah Waterland int
pkgGetPackageList(char *** r_pkgList,char ** a_argv,int a_optind,char * a_categories,char ** a_categoryList,struct pkgdev * a_pkgdev)8105c51f124SMoriah Waterland pkgGetPackageList(char ***r_pkgList, char **a_argv, int a_optind,
8115c51f124SMoriah Waterland 	char *a_categories, char **a_categoryList, struct pkgdev *a_pkgdev)
8125c51f124SMoriah Waterland {
8135c51f124SMoriah Waterland 	char	*all_pkgs[4] = {"all", NULL};
8145c51f124SMoriah Waterland 
8155c51f124SMoriah Waterland 	/* entry assertions */
8165c51f124SMoriah Waterland 
8175c51f124SMoriah Waterland 	assert(a_pkgdev != (struct pkgdev *)NULL);
8185c51f124SMoriah Waterland 	assert(a_pkgdev->dirname != (char *)NULL);
8195c51f124SMoriah Waterland 	assert(*a_pkgdev->dirname != '\0');
8205c51f124SMoriah Waterland 	assert(r_pkgList != (char ***)NULL);
8215c51f124SMoriah Waterland 	assert(a_argv != (char **)NULL);
8225c51f124SMoriah Waterland 
8235c51f124SMoriah Waterland 	/* entry debugging info */
8245c51f124SMoriah Waterland 
8255c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_GETPKGLIST_ENTRY);
8265c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_GETPKGLIST_ARGS, a_pkgdev->dirname,
8275c51f124SMoriah Waterland 			a_categories ? a_categories : "?");
8285c51f124SMoriah Waterland 
8295c51f124SMoriah Waterland 	/* reset returned package list handle */
8305c51f124SMoriah Waterland 
8315c51f124SMoriah Waterland 	*r_pkgList = (char **)NULL;
8325c51f124SMoriah Waterland 
8335c51f124SMoriah Waterland 	/*
8345c51f124SMoriah Waterland 	 * generate list of packages to be removed: if removing by category,
8355c51f124SMoriah Waterland 	 * then generate package list based on all packages by category,
8365c51f124SMoriah Waterland 	 * else generate package list based on all packages specified.
8375c51f124SMoriah Waterland 	 */
8385c51f124SMoriah Waterland 
8395c51f124SMoriah Waterland 	if (a_categories != NULL) {
8405c51f124SMoriah Waterland 		/* generate package list from all packages in given category */
8415c51f124SMoriah Waterland 
8425c51f124SMoriah Waterland 		*r_pkgList = gpkglist(a_pkgdev->dirname, &all_pkgs[0],
8435c51f124SMoriah Waterland 					a_categoryList);
8445c51f124SMoriah Waterland 
8455c51f124SMoriah Waterland 		if (*r_pkgList == NULL) {
8465c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_GPKGLIST_CATFAILED, a_categories);
8475c51f124SMoriah Waterland 			progerr(ERR_CAT_FND, a_categories);
8485c51f124SMoriah Waterland 			return (1);
8495c51f124SMoriah Waterland 		}
8505c51f124SMoriah Waterland 
8515c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_CATOK, a_categories);
8525c51f124SMoriah Waterland 
8535c51f124SMoriah Waterland 		return (0);
8545c51f124SMoriah Waterland 	}
8555c51f124SMoriah Waterland 
8565c51f124SMoriah Waterland 	/* generate package list from specified packages */
8575c51f124SMoriah Waterland 
8585c51f124SMoriah Waterland 	*r_pkgList = gpkglist(a_pkgdev->dirname, &a_argv[a_optind], NULL);
8595c51f124SMoriah Waterland 
8605c51f124SMoriah Waterland 	/* if list generated return results */
8615c51f124SMoriah Waterland 
8625c51f124SMoriah Waterland 	if (*r_pkgList != NULL) {
8635c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_OK);
8645c51f124SMoriah Waterland 		return (0);
8655c51f124SMoriah Waterland 	}
8665c51f124SMoriah Waterland 
8675c51f124SMoriah Waterland 	/* handle error from gpkglist */
8685c51f124SMoriah Waterland 
8695c51f124SMoriah Waterland 	switch (errno) {
8705c51f124SMoriah Waterland 	    case ENOPKG:	/* no packages */
8715c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_ENOPKG);
8725c51f124SMoriah Waterland 		return (-1);
8735c51f124SMoriah Waterland 
8745c51f124SMoriah Waterland 	    case ESRCH:
8755c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_ESRCH);
8765c51f124SMoriah Waterland 		return (1);
8775c51f124SMoriah Waterland 
8785c51f124SMoriah Waterland 	    case EINTR:
8795c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_EINTR);
8805c51f124SMoriah Waterland 		return (3);
8815c51f124SMoriah Waterland 
8825c51f124SMoriah Waterland 	    default:
8835c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_UNKNOWN, errno);
8845c51f124SMoriah Waterland 		progerr(ERR_GPKGLIST_ERROR);
8855c51f124SMoriah Waterland 		return (99);
8865c51f124SMoriah Waterland 	}
8875c51f124SMoriah Waterland }
8885c51f124SMoriah Waterland 
8895c51f124SMoriah Waterland /*
8905c51f124SMoriah Waterland  * return string representing path to "global zone only file"
8915c51f124SMoriah Waterland  */
8925c51f124SMoriah Waterland 
8935c51f124SMoriah Waterland char *
pkgGetGzOnlyPath(void)8945c51f124SMoriah Waterland pkgGetGzOnlyPath(void)
8955c51f124SMoriah Waterland {
8965c51f124SMoriah Waterland 	return (GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
8975c51f124SMoriah Waterland }
8985c51f124SMoriah Waterland 
8995c51f124SMoriah Waterland /*
9005c51f124SMoriah Waterland  * Name:	pkgAddThisZonePackage
9015c51f124SMoriah Waterland  * Description:	Add specified package to internal list of "this zone only" pkgs
9025c51f124SMoriah Waterland  * Arguments:	a_pkgInst - name of package to add to list
9035c51f124SMoriah Waterland  * Returns:	void
9045c51f124SMoriah Waterland  */
9055c51f124SMoriah Waterland 
9065c51f124SMoriah Waterland void
pkgAddThisZonePackage(char * a_pkgInst)9075c51f124SMoriah Waterland pkgAddThisZonePackage(char *a_pkgInst)
9085c51f124SMoriah Waterland {
9095c51f124SMoriah Waterland 	/* entry assertions */
9105c51f124SMoriah Waterland 
9115c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
9125c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
9135c51f124SMoriah Waterland 
9145c51f124SMoriah Waterland 	/* do not duplicate entries */
9155c51f124SMoriah Waterland 
9165c51f124SMoriah Waterland 	if (pkgPackageIsThisZone(a_pkgInst) == B_TRUE) {
9175c51f124SMoriah Waterland 		return;
9185c51f124SMoriah Waterland 	}
9195c51f124SMoriah Waterland 
9205c51f124SMoriah Waterland 	/* add package name to internal list */
9215c51f124SMoriah Waterland 
9225c51f124SMoriah Waterland 	if (thisZonePackages == (char **)NULL) {
9235c51f124SMoriah Waterland 		thisZonePackages =
9245c51f124SMoriah Waterland 				(char **)calloc(2, sizeof (char **));
9255c51f124SMoriah Waterland 	} else {
9265c51f124SMoriah Waterland 		thisZonePackages =
9275c51f124SMoriah Waterland 				(char **)realloc(thisZonePackages,
9285c51f124SMoriah Waterland 				sizeof (char **)*(numThisZonePackages+2));
9295c51f124SMoriah Waterland 	}
9305c51f124SMoriah Waterland 
9315c51f124SMoriah Waterland 	/* handle out of memory error */
9325c51f124SMoriah Waterland 
9335c51f124SMoriah Waterland 	if (thisZonePackages == (char **)NULL) {
9345c51f124SMoriah Waterland 		progerr(ERR_MEMORY, errno);
9355c51f124SMoriah Waterland 		quit(99);
9365c51f124SMoriah Waterland 	}
9375c51f124SMoriah Waterland 
9385c51f124SMoriah Waterland 	/* add this entry to the end of the list */
9395c51f124SMoriah Waterland 
9405c51f124SMoriah Waterland 	thisZonePackages[numThisZonePackages] = strdup(a_pkgInst);
9415c51f124SMoriah Waterland 	if (thisZonePackages[numThisZonePackages] == (char *)NULL) {
9425c51f124SMoriah Waterland 		progerr(ERR_MEMORY, errno);
9435c51f124SMoriah Waterland 		quit(99);
9445c51f124SMoriah Waterland 	}
9455c51f124SMoriah Waterland 
9465c51f124SMoriah Waterland 	numThisZonePackages++;
9475c51f124SMoriah Waterland 
9485c51f124SMoriah Waterland 	/* make sure end of the list is properly terminated */
9495c51f124SMoriah Waterland 
9505c51f124SMoriah Waterland 	thisZonePackages[numThisZonePackages] = (char *)NULL;
9515c51f124SMoriah Waterland 
9525c51f124SMoriah Waterland 	/* exit debugging info */
9535c51f124SMoriah Waterland 
9545c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADD_TZP, numThisZonePackages,
9555c51f124SMoriah Waterland 			thisZonePackages[numThisZonePackages-1]);
9565c51f124SMoriah Waterland }
9575c51f124SMoriah Waterland 
9585c51f124SMoriah Waterland /*
9595c51f124SMoriah Waterland  * Name:	pkgPackageIsThisZone
9605c51f124SMoriah Waterland  * Description:	Determine if the specified package is marked to be installed
9615c51f124SMoriah Waterland  *		in this zone only
9625c51f124SMoriah Waterland  * Arguments:	a_pkgInst - pointer to string representing package name to check
9635c51f124SMoriah Waterland  * Returns:	boolean_t
9645c51f124SMoriah Waterland  *			B_TRUE - the package IS "this zone only"
9655c51f124SMoriah Waterland  *			B_FALSE - the paackage is NOT "this zone only"
9665c51f124SMoriah Waterland  */
9675c51f124SMoriah Waterland 
9685c51f124SMoriah Waterland boolean_t
pkgPackageIsThisZone(char * a_pkgInst)9695c51f124SMoriah Waterland pkgPackageIsThisZone(char *a_pkgInst)
9705c51f124SMoriah Waterland {
9715c51f124SMoriah Waterland 	int		n;
9725c51f124SMoriah Waterland 
9735c51f124SMoriah Waterland 	/* entry assertions */
9745c51f124SMoriah Waterland 
9755c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
9765c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
9775c51f124SMoriah Waterland 
9785c51f124SMoriah Waterland 	/*
9795c51f124SMoriah Waterland 	 * see if this package is in the "this zone only" list
9805c51f124SMoriah Waterland 	 */
9815c51f124SMoriah Waterland 
9825c51f124SMoriah Waterland 	for (n = 0; n < numThisZonePackages; n++) {
9835c51f124SMoriah Waterland 		if (strcmp(a_pkgInst, thisZonePackages[n]) == 0) {
9845c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_IS_THISZONE, a_pkgInst);
9855c51f124SMoriah Waterland 			return (B_TRUE);
9865c51f124SMoriah Waterland 		}
9875c51f124SMoriah Waterland 	}
9885c51f124SMoriah Waterland 
9895c51f124SMoriah Waterland 	/* path is not in "this zone only" list */
9905c51f124SMoriah Waterland 
9915c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_IS_NOT_THISZONE, a_pkgInst);
9925c51f124SMoriah Waterland 
9935c51f124SMoriah Waterland 	return (B_FALSE);
9945c51f124SMoriah Waterland }
9955c51f124SMoriah Waterland 
9965c51f124SMoriah Waterland /*
9975c51f124SMoriah Waterland  * Name:	pkgLocateHighestInst
9985c51f124SMoriah Waterland  * Description:	Locate the highest installed instance of a package
9995c51f124SMoriah Waterland  * Arguments:	r_path - [RO, *RW] - (char *)
10005c51f124SMoriah Waterland  *			Pointer to buffer where the full path to the top level
10015c51f124SMoriah Waterland  *			directory containing the latest instance of the
10025c51f124SMoriah Waterland  *			specified package is located is placed.
10035c51f124SMoriah Waterland  *		r_pathLen - [RO, *RO] - (int)
10045c51f124SMoriah Waterland  *			Integer representing the size of r_path in bytes.
10055c51f124SMoriah Waterland  *		r_pkgInst - [RO, *RW] - (char *)
10065c51f124SMoriah Waterland  *			Pointer to buffer where the package instance name of the
10075c51f124SMoriah Waterland  *			latest instance of the specified package is placed.
10085c51f124SMoriah Waterland  *		r_pkgInstLen - [RO, *RO] - (int)
10095c51f124SMoriah Waterland  *			Integer representing the size of r_pkgInst in bytes.
10105c51f124SMoriah Waterland  *		a_rootPath - [RO, *RO] - (char *)
10115c51f124SMoriah Waterland  *			Pointer to string representing the root path to look
10125c51f124SMoriah Waterland  *			for the latest instance of the specified package.
10135c51f124SMoriah Waterland  *		a_pkgInst - [RO, *RO] - (char *)
10145c51f124SMoriah Waterland  *			Pointer to string representing the name of the package
10155c51f124SMoriah Waterland  *			to locate the latest installed instance of.
10165c51f124SMoriah Waterland  */
10175c51f124SMoriah Waterland 
10185c51f124SMoriah Waterland void
pkgLocateHighestInst(char * r_path,int r_pathLen,char * r_pkgInst,int r_pkgInstLen,char * a_rootPath,char * a_pkgInst)10195c51f124SMoriah Waterland pkgLocateHighestInst(char *r_path, int r_pathLen, char *r_pkgInst,
10205c51f124SMoriah Waterland 	int r_pkgInstLen, char *a_rootPath, char *a_pkgInst)
10215c51f124SMoriah Waterland {
10225c51f124SMoriah Waterland 	char		pkgInstPath[PATH_MAX] = {'\0'};
10235c51f124SMoriah Waterland 	char		pkgWild[PKGSIZ+1] = {'\0'};
10245c51f124SMoriah Waterland 	char		pkgName[PKGSIZ+1] = {'\0'};
10255c51f124SMoriah Waterland 	int		npkgs;
10265c51f124SMoriah Waterland 	struct pkginfo	*pinf = (struct pkginfo *)NULL;
10275c51f124SMoriah Waterland 
10285c51f124SMoriah Waterland 	/* entry assertions */
10295c51f124SMoriah Waterland 
10305c51f124SMoriah Waterland 	assert(r_path != (char *)NULL);
10315c51f124SMoriah Waterland 	assert(r_pathLen > 0);
10325c51f124SMoriah Waterland 	assert(r_pkgInst != (char *)NULL);
10335c51f124SMoriah Waterland 	assert(r_pkgInstLen > 0);
10345c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
10355c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
10365c51f124SMoriah Waterland 
10375c51f124SMoriah Waterland 	/* normalize root path */
10385c51f124SMoriah Waterland 
10395c51f124SMoriah Waterland 	if ((a_rootPath == (char *)NULL) || (strcmp(a_rootPath, "/") == 0)) {
10405c51f124SMoriah Waterland 		a_rootPath = "";
10415c51f124SMoriah Waterland 	}
10425c51f124SMoriah Waterland 
10435c51f124SMoriah Waterland 	/* construct path to package repository directory (eg. /var/sadm/pkg) */
10445c51f124SMoriah Waterland 
10455c51f124SMoriah Waterland 	(void) snprintf(pkgInstPath, sizeof (pkgInstPath), "%s%s", a_rootPath,
10465c51f124SMoriah Waterland 		PKGLOC);
10475c51f124SMoriah Waterland 
10485c51f124SMoriah Waterland 	/* entry debugging info */
10495c51f124SMoriah Waterland 
10505c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_ENTRY);
10515c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_ARGS, pkgInstPath, a_pkgInst);
10525c51f124SMoriah Waterland 
10535c51f124SMoriah Waterland 	/* reset returned path/package instance so both ares empty */
10545c51f124SMoriah Waterland 
10555c51f124SMoriah Waterland 	*r_path = '\0';
10565c51f124SMoriah Waterland 	*r_pkgInst = '\0';
10575c51f124SMoriah Waterland 
10585c51f124SMoriah Waterland 	/* remove any architecture extension */
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 	pkgstrGetToken_r((char *)NULL, a_pkgInst, 0, ".",
10615c51f124SMoriah Waterland 		pkgName, sizeof (pkgName));
10625c51f124SMoriah Waterland 
10635c51f124SMoriah Waterland 	/* make sure that the package name is valid and can be wild carded */
10645c51f124SMoriah Waterland 
10655c51f124SMoriah Waterland 	if (pkgnmchk(pkgName, NULL, 0) || strchr(pkgName, '.')) {
10665c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_LOCHIGH_BAD_PKGNAME, pkgName);
10675c51f124SMoriah Waterland 		quit(99);
10685c51f124SMoriah Waterland 	}
10695c51f124SMoriah Waterland 
10705c51f124SMoriah Waterland 	/* create wild card specification for this package instance */
10715c51f124SMoriah Waterland 
10725c51f124SMoriah Waterland 	(void) snprintf(pkgWild, sizeof (pkgWild), "%s.*", pkgName);
10735c51f124SMoriah Waterland 
10745c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_WILDCARD, pkgName, pkgWild);
10755c51f124SMoriah Waterland 
10765c51f124SMoriah Waterland 	/*
10775c51f124SMoriah Waterland 	 * inspect the system to determine if any instances of the
10785c51f124SMoriah Waterland 	 * package being installed already exist on the system
10795c51f124SMoriah Waterland 	 */
10805c51f124SMoriah Waterland 
10815c51f124SMoriah Waterland 	for (npkgs = 0; ; npkgs++) {
10825c51f124SMoriah Waterland 		char	*savePkgdir;
10835c51f124SMoriah Waterland 		int	r;
10845c51f124SMoriah Waterland 
10855c51f124SMoriah Waterland 		/* allocate new pinfo structure for use in the pkginfo call */
10865c51f124SMoriah Waterland 
10875c51f124SMoriah Waterland 		pinf = _pkginfoFactory();
10885c51f124SMoriah Waterland 
10895c51f124SMoriah Waterland 		/*
10905c51f124SMoriah Waterland 		 * lookup the specified package; the first call will cause the
10915c51f124SMoriah Waterland 		 * pkgdir directory to be opened - it will be closed when the
10925c51f124SMoriah Waterland 		 * end of directory is read and pkginfo() returns != 0. You must
10935c51f124SMoriah Waterland 		 * cycle through all instances until pkginfo() returns != 0.
10945c51f124SMoriah Waterland 		 * NOTE: pkginfo() requires the global variable 'pkgdir' be set
10955c51f124SMoriah Waterland 		 * to the package installed directory (<root>/var/sadm/pkg).
10965c51f124SMoriah Waterland 		 */
10975c51f124SMoriah Waterland 
10985c51f124SMoriah Waterland 		savePkgdir = pkgdir;
10995c51f124SMoriah Waterland 		pkgdir = pkgInstPath;
11005c51f124SMoriah Waterland 
11015c51f124SMoriah Waterland 		r = pkginfo(pinf, pkgWild, NULL, NULL);
11025c51f124SMoriah Waterland 
11035c51f124SMoriah Waterland 		pkgdir = savePkgdir;
11045c51f124SMoriah Waterland 
11055c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, pkgName, r);
11065c51f124SMoriah Waterland 
11075c51f124SMoriah Waterland 		/* break out of loop of no package found */
11085c51f124SMoriah Waterland 
11095c51f124SMoriah Waterland 		if (r != 0) {
11105c51f124SMoriah Waterland 			pkginfoFree(&pinf);
11115c51f124SMoriah Waterland 			break;
11125c51f124SMoriah Waterland 		}
11135c51f124SMoriah Waterland 
11145c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_LOCHIGH_INSTANCE, npkgs,
11155c51f124SMoriah Waterland 			pinf->pkginst ? pinf->pkginst : "",
11165c51f124SMoriah Waterland 			pinf->name ? pinf->name : "",
11175c51f124SMoriah Waterland 			pinf->arch ? pinf->arch : "",
11185c51f124SMoriah Waterland 			pinf->version ? pinf->version : "",
11195c51f124SMoriah Waterland 			pinf->vendor ? pinf->vendor : "",
11205c51f124SMoriah Waterland 			pinf->basedir ? pinf->basedir : "",
11215c51f124SMoriah Waterland 			pinf->catg ? pinf->catg : "",
11225c51f124SMoriah Waterland 			pinf->status);
11235c51f124SMoriah Waterland 
11245c51f124SMoriah Waterland 		/* save path/instance name for this instance found */
11255c51f124SMoriah Waterland 
11265c51f124SMoriah Waterland 		(void) strlcpy(r_pkgInst, pinf->pkginst, r_pkgInstLen);
11275c51f124SMoriah Waterland 		pkgstrPrintf_r(r_path, r_pathLen, "%s%s/%s", a_rootPath,
11285c51f124SMoriah Waterland 			PKGLOC, pinf->pkginst);
11295c51f124SMoriah Waterland 
11305c51f124SMoriah Waterland 		pkginfoFree(&pinf);
11315c51f124SMoriah Waterland 	}
11325c51f124SMoriah Waterland 
11335c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_RETURN, npkgs, r_pkgInst, r_path);
11345c51f124SMoriah Waterland }
11355c51f124SMoriah Waterland 
11365c51f124SMoriah Waterland /*
11375c51f124SMoriah Waterland  * Name:	pkgTestInstalled
11385c51f124SMoriah Waterland  * Description:	determine if package is installed at specified root path
11395c51f124SMoriah Waterland  * Arguments:	a_packageName - name of package to test
11405c51f124SMoriah Waterland  * 		a_rootPath - root path of alternative root to test
11415c51f124SMoriah Waterland  * Returns:	B_TRUE - package is installed
11425c51f124SMoriah Waterland  *		B_FALSE - package is not installed
11435c51f124SMoriah Waterland  */
11445c51f124SMoriah Waterland 
11455c51f124SMoriah Waterland boolean_t
pkgTestInstalled(char * a_packageName,char * a_rootPath)11465c51f124SMoriah Waterland pkgTestInstalled(char *a_packageName, char *a_rootPath)
11475c51f124SMoriah Waterland {
11485c51f124SMoriah Waterland 	char	cmd[MAXPATHLEN+1];
11495c51f124SMoriah Waterland 	int	rc;
11505c51f124SMoriah Waterland 
11515c51f124SMoriah Waterland 	/* entry assertions */
11525c51f124SMoriah Waterland 
11535c51f124SMoriah Waterland 	assert(a_packageName != (char *)NULL);
11545c51f124SMoriah Waterland 	assert(*a_packageName != '\0');
11555c51f124SMoriah Waterland 	assert(a_rootPath != (char *)NULL);
11565c51f124SMoriah Waterland 	assert(a_rootPath != '\0');
11575c51f124SMoriah Waterland 
11585c51f124SMoriah Waterland 	/* entry debugging info */
11595c51f124SMoriah Waterland 
11605c51f124SMoriah Waterland 	echoDebug(DBG_PKG_TEST_EXISTENCE, a_packageName, a_rootPath);
11615c51f124SMoriah Waterland 
11625c51f124SMoriah Waterland 	/*
11635c51f124SMoriah Waterland 	 * create pkginfo command to execute:
11645c51f124SMoriah Waterland 	 * /usr/bin/pkginfo -q <packageName>
11655c51f124SMoriah Waterland 	 */
11665c51f124SMoriah Waterland 	(void) snprintf(cmd, sizeof (cmd),
11675c51f124SMoriah Waterland 		"%s -q %s", PKGINFO_CMD, a_packageName);
11685c51f124SMoriah Waterland 
11695c51f124SMoriah Waterland 	/* execute command */
11705c51f124SMoriah Waterland 
11715c51f124SMoriah Waterland 	rc = system(cmd);
11725c51f124SMoriah Waterland 
11735c51f124SMoriah Waterland 	/* return success if pkginfo returns "0" */
11745c51f124SMoriah Waterland 
11755c51f124SMoriah Waterland 	if (rc == 0) {
11765c51f124SMoriah Waterland 		echoDebug(DBG_PKG_INSTALLED, a_packageName, a_rootPath);
11775c51f124SMoriah Waterland 		return (B_TRUE);
11785c51f124SMoriah Waterland 	}
11795c51f124SMoriah Waterland 
11805c51f124SMoriah Waterland 	/* package not installed */
11815c51f124SMoriah Waterland 
11825c51f124SMoriah Waterland 	echoDebug(DBG_PKG_NOT_INSTALLED, a_packageName, a_rootPath);
11835c51f124SMoriah Waterland 
11845c51f124SMoriah Waterland 	return (B_FALSE);
11855c51f124SMoriah Waterland }
11865c51f124SMoriah Waterland 
11875c51f124SMoriah Waterland /*
11885c51f124SMoriah Waterland  * *****************************************************************************
11895c51f124SMoriah Waterland  * static internal (private) functions
11905c51f124SMoriah Waterland  * *****************************************************************************
11915c51f124SMoriah Waterland  */
11925c51f124SMoriah Waterland 
11935c51f124SMoriah Waterland static void
_pkginfoInit(struct pkginfo * a_info)11945c51f124SMoriah Waterland _pkginfoInit(struct pkginfo *a_info)
11955c51f124SMoriah Waterland {
11965c51f124SMoriah Waterland 	/* entry assertions */
11975c51f124SMoriah Waterland 
11985c51f124SMoriah Waterland 	assert(a_info != (struct pkginfo *)NULL);
11995c51f124SMoriah Waterland 
12005c51f124SMoriah Waterland 	/* free previously allocated space */
12015c51f124SMoriah Waterland 
12025c51f124SMoriah Waterland 	if (a_info->pkginst) {
12035c51f124SMoriah Waterland 		free(a_info->pkginst);
12045c51f124SMoriah Waterland 		if (a_info->arch)
12055c51f124SMoriah Waterland 			free(a_info->arch);
12065c51f124SMoriah Waterland 		if (a_info->version)
12075c51f124SMoriah Waterland 			free(a_info->version);
12085c51f124SMoriah Waterland 		if (a_info->basedir)
12095c51f124SMoriah Waterland 			free(a_info->basedir);
12105c51f124SMoriah Waterland 		if (a_info->name)
12115c51f124SMoriah Waterland 			free(a_info->name);
12125c51f124SMoriah Waterland 		if (a_info->vendor)
12135c51f124SMoriah Waterland 			free(a_info->vendor);
12145c51f124SMoriah Waterland 		if (a_info->catg)
12155c51f124SMoriah Waterland 			free(a_info->catg);
12165c51f124SMoriah Waterland 	}
12175c51f124SMoriah Waterland 
12185c51f124SMoriah Waterland 	a_info->pkginst = NULL;
12195c51f124SMoriah Waterland 	a_info->arch = a_info->version = NULL;
12205c51f124SMoriah Waterland 	a_info->basedir = a_info->name = NULL;
12215c51f124SMoriah Waterland 	a_info->vendor = a_info->catg = NULL;
12225c51f124SMoriah Waterland 	a_info->status = PI_UNKNOWN;
12235c51f124SMoriah Waterland }
12245c51f124SMoriah Waterland 
12255c51f124SMoriah Waterland static struct pkginfo *
_pkginfoFactory(void)12265c51f124SMoriah Waterland _pkginfoFactory(void)
12275c51f124SMoriah Waterland {
12285c51f124SMoriah Waterland 	struct pkginfo *pinf;
12295c51f124SMoriah Waterland 
12305c51f124SMoriah Waterland 	pinf = (struct pkginfo *)calloc(1, sizeof (struct pkginfo));
12315c51f124SMoriah Waterland 	if (pinf == (struct pkginfo *)NULL) {
12325c51f124SMoriah Waterland 		progerr(ERR_MEM);
12335c51f124SMoriah Waterland 		exit(1);
12345c51f124SMoriah Waterland 	}
12355c51f124SMoriah Waterland 
12365c51f124SMoriah Waterland 	_pkginfoInit(pinf);
12375c51f124SMoriah Waterland 	return (pinf);
12385c51f124SMoriah Waterland }
1239