xref: /onnv-gate/usr/src/cmd/svr4pkg/libinst/pkgops.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) 2004, 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 #include <stdio.h>
289781SMoriah.Waterland@Sun.COM #include <limits.h>
299781SMoriah.Waterland@Sun.COM #include <stdlib.h>
309781SMoriah.Waterland@Sun.COM #include <unistd.h>
319781SMoriah.Waterland@Sun.COM #include <string.h>
329781SMoriah.Waterland@Sun.COM #include <fcntl.h>
339781SMoriah.Waterland@Sun.COM #include <sys/types.h>
349781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
359781SMoriah.Waterland@Sun.COM #include <signal.h>
369781SMoriah.Waterland@Sun.COM #include <errno.h>
379781SMoriah.Waterland@Sun.COM #include <assert.h>
389781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
399781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
409781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
419781SMoriah.Waterland@Sun.COM #include <locale.h>
429781SMoriah.Waterland@Sun.COM #include <libintl.h>
439781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
449781SMoriah.Waterland@Sun.COM #include <pkglib.h>
459781SMoriah.Waterland@Sun.COM #include <install.h>
469781SMoriah.Waterland@Sun.COM #include <libinst.h>
479781SMoriah.Waterland@Sun.COM #include <libadm.h>
489781SMoriah.Waterland@Sun.COM #include <messages.h>
499781SMoriah.Waterland@Sun.COM 
509781SMoriah.Waterland@Sun.COM /* commands to execute */
519781SMoriah.Waterland@Sun.COM 
529781SMoriah.Waterland@Sun.COM #define	PKGINFO_CMD	"/usr/bin/pkginfo"
539781SMoriah.Waterland@Sun.COM 
549781SMoriah.Waterland@Sun.COM #define	GLOBALZONE_ONLY_PACKAGE_FILE_PATH	\
559781SMoriah.Waterland@Sun.COM 					"/var/sadm/install/gz-only-packages"
569781SMoriah.Waterland@Sun.COM 
579781SMoriah.Waterland@Sun.COM #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
589781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"
599781SMoriah.Waterland@Sun.COM #endif
609781SMoriah.Waterland@Sun.COM 
619781SMoriah.Waterland@Sun.COM /*
629781SMoriah.Waterland@Sun.COM  * forward declarations
639781SMoriah.Waterland@Sun.COM  */
649781SMoriah.Waterland@Sun.COM 
659781SMoriah.Waterland@Sun.COM static void		_pkginfoInit(struct pkginfo *a_info);
669781SMoriah.Waterland@Sun.COM static struct pkginfo	*_pkginfoFactory(void);
679781SMoriah.Waterland@Sun.COM static char		**thisZonePackages;
689781SMoriah.Waterland@Sun.COM static int		numThisZonePackages;
699781SMoriah.Waterland@Sun.COM 
709781SMoriah.Waterland@Sun.COM /*
719781SMoriah.Waterland@Sun.COM  * *****************************************************************************
729781SMoriah.Waterland@Sun.COM  * global external (public) functions
739781SMoriah.Waterland@Sun.COM  * *****************************************************************************
749781SMoriah.Waterland@Sun.COM  */
759781SMoriah.Waterland@Sun.COM 
769781SMoriah.Waterland@Sun.COM /*
779781SMoriah.Waterland@Sun.COM  * Name:	pkginfoFree
789781SMoriah.Waterland@Sun.COM  * Description:	free pkginfo structure returned from various functions
799781SMoriah.Waterland@Sun.COM  * Arguments:	r_info - pointer to pointer to pkginfo structure to free
809781SMoriah.Waterland@Sun.COM  * Returns:	void
819781SMoriah.Waterland@Sun.COM  */
829781SMoriah.Waterland@Sun.COM 
839781SMoriah.Waterland@Sun.COM void
pkginfoFree(struct pkginfo ** r_info)849781SMoriah.Waterland@Sun.COM pkginfoFree(struct pkginfo **r_info)
859781SMoriah.Waterland@Sun.COM {
869781SMoriah.Waterland@Sun.COM 	struct pkginfo	*pinfo;
879781SMoriah.Waterland@Sun.COM 
889781SMoriah.Waterland@Sun.COM 	/* entry assertions */
899781SMoriah.Waterland@Sun.COM 
909781SMoriah.Waterland@Sun.COM 	assert(r_info != (struct pkginfo **)NULL);
919781SMoriah.Waterland@Sun.COM 
929781SMoriah.Waterland@Sun.COM 	/* localize reference to info structure to free */
939781SMoriah.Waterland@Sun.COM 
949781SMoriah.Waterland@Sun.COM 	pinfo = *r_info;
959781SMoriah.Waterland@Sun.COM 
969781SMoriah.Waterland@Sun.COM 	/* reset callers handle to info structure */
979781SMoriah.Waterland@Sun.COM 
989781SMoriah.Waterland@Sun.COM 	*r_info = (struct pkginfo *)NULL;
999781SMoriah.Waterland@Sun.COM 
1009781SMoriah.Waterland@Sun.COM 	assert(pinfo != (struct pkginfo *)NULL);
1019781SMoriah.Waterland@Sun.COM 
1029781SMoriah.Waterland@Sun.COM 	/* free up contents of the structure */
1039781SMoriah.Waterland@Sun.COM 
1049781SMoriah.Waterland@Sun.COM 	_pkginfoInit(pinfo);
1059781SMoriah.Waterland@Sun.COM 
1069781SMoriah.Waterland@Sun.COM 	/* free up structure itself */
1079781SMoriah.Waterland@Sun.COM 
1089781SMoriah.Waterland@Sun.COM 	(void) free(pinfo);
1099781SMoriah.Waterland@Sun.COM }
1109781SMoriah.Waterland@Sun.COM 
1119781SMoriah.Waterland@Sun.COM /*
1129781SMoriah.Waterland@Sun.COM  * Name:	pkginfoIsPkgInstalled
1139781SMoriah.Waterland@Sun.COM  * Description:	determine if specified package is installed, return pkginfo
1149781SMoriah.Waterland@Sun.COM  *		structure describing package if package is installed
1159781SMoriah.Waterland@Sun.COM  * Arguments:	r_pinfo - pointer to pointer to pkginfo structure
1169781SMoriah.Waterland@Sun.COM  *			If this pointer is NOT null:
1179781SMoriah.Waterland@Sun.COM  *			-On success, this handle is filled in with a pointer
1189781SMoriah.Waterland@Sun.COM  *			--to a newly allocated pkginfo structure describing
1199781SMoriah.Waterland@Sun.COM  *			--the package discovered
1209781SMoriah.Waterland@Sun.COM  *			-On failure, this handle is filled with NULL
1219781SMoriah.Waterland@Sun.COM  *			If this pointer is NULL:
1229781SMoriah.Waterland@Sun.COM  *			-no pkginfo structure is returned on success.
1239781SMoriah.Waterland@Sun.COM  *		a_pkgInst - package instance (name) to lookup
1249781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
1259781SMoriah.Waterland@Sun.COM  *			B_TRUE - package installed, pkginfo returned
1269781SMoriah.Waterland@Sun.COM  *			B_FALSE - package not installed, no pkginfo returned
1279781SMoriah.Waterland@Sun.COM  * NOTE:	This function returns the first instance of package that
1289781SMoriah.Waterland@Sun.COM  *		is installed - see pkginfo() function for details
1299781SMoriah.Waterland@Sun.COM  * NOTE:    	Any pkginfo structure returned is placed in new storage for the
1309781SMoriah.Waterland@Sun.COM  *		calling function. The caller must use 'pkginfoFree' to dispose
1319781SMoriah.Waterland@Sun.COM  *		of the storage once the pkginfo structure is no longer needed.
1329781SMoriah.Waterland@Sun.COM  */
1339781SMoriah.Waterland@Sun.COM 
1349781SMoriah.Waterland@Sun.COM boolean_t
pkginfoIsPkgInstalled(struct pkginfo ** r_pinfo,char * a_pkgInst)1359781SMoriah.Waterland@Sun.COM pkginfoIsPkgInstalled(struct pkginfo **r_pinfo, char *a_pkgInst)
1369781SMoriah.Waterland@Sun.COM {
1379781SMoriah.Waterland@Sun.COM 	int		r;
1389781SMoriah.Waterland@Sun.COM 	struct pkginfo	*pinf;
1399781SMoriah.Waterland@Sun.COM 
1409781SMoriah.Waterland@Sun.COM 	/* entry assertions */
1419781SMoriah.Waterland@Sun.COM 
1429781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
1439781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
1449781SMoriah.Waterland@Sun.COM 
1459781SMoriah.Waterland@Sun.COM 	/* reset returned pkginfo structure handle */
1469781SMoriah.Waterland@Sun.COM 
1479781SMoriah.Waterland@Sun.COM 	if (r_pinfo != (struct pkginfo **)NULL) {
1489781SMoriah.Waterland@Sun.COM 		*r_pinfo = (struct pkginfo *)NULL;
1499781SMoriah.Waterland@Sun.COM 	}
1509781SMoriah.Waterland@Sun.COM 
1519781SMoriah.Waterland@Sun.COM 	/* allocate a new pinfo structure for use in the call to pkginfo */
1529781SMoriah.Waterland@Sun.COM 
1539781SMoriah.Waterland@Sun.COM 	pinf = _pkginfoFactory();
1549781SMoriah.Waterland@Sun.COM 
1559781SMoriah.Waterland@Sun.COM 	/* lookup the specified package */
1569781SMoriah.Waterland@Sun.COM 
1579781SMoriah.Waterland@Sun.COM 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
1589781SMoriah.Waterland@Sun.COM 	r = pkginfo(pinf, a_pkgInst, NULL, NULL);
1599781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, a_pkgInst, r);
1609781SMoriah.Waterland@Sun.COM 
1619781SMoriah.Waterland@Sun.COM 	if (r_pinfo != (struct pkginfo **)NULL) {
1629781SMoriah.Waterland@Sun.COM 		*r_pinfo = pinf;
1639781SMoriah.Waterland@Sun.COM 	} else {
1649781SMoriah.Waterland@Sun.COM 		/* free pkginfo structure */
1659781SMoriah.Waterland@Sun.COM 		pkginfoFree(&pinf);
1669781SMoriah.Waterland@Sun.COM 	}
1679781SMoriah.Waterland@Sun.COM 
1689781SMoriah.Waterland@Sun.COM 	return (r == 0 ? B_TRUE : B_FALSE);
1699781SMoriah.Waterland@Sun.COM }
1709781SMoriah.Waterland@Sun.COM 
1719781SMoriah.Waterland@Sun.COM /*
1729781SMoriah.Waterland@Sun.COM  * Name:	pkgOpenInGzOnlyFile
1739781SMoriah.Waterland@Sun.COM  * Description:	Open the global zone only package list file
1749781SMoriah.Waterland@Sun.COM  * Arguments:	a_rootPath - pointer to string representing the root path
1759781SMoriah.Waterland@Sun.COM  *			where the global zone only package list file is
1769781SMoriah.Waterland@Sun.COM  *			located - NULL is the same as "/"
1779781SMoriah.Waterland@Sun.COM  * Returns:	FILE *
1789781SMoriah.Waterland@Sun.COM  *			== NULL - failure - file not open
1799781SMoriah.Waterland@Sun.COM  *			!= NULL - success - file pointer returned
1809781SMoriah.Waterland@Sun.COM  * NOTE:	This function will create the file if it does not exist.
1819781SMoriah.Waterland@Sun.COM  */
1829781SMoriah.Waterland@Sun.COM 
1839781SMoriah.Waterland@Sun.COM FILE *
pkgOpenInGzOnlyFile(char * a_rootPath)1849781SMoriah.Waterland@Sun.COM pkgOpenInGzOnlyFile(char *a_rootPath)
1859781SMoriah.Waterland@Sun.COM {
1869781SMoriah.Waterland@Sun.COM 	FILE	*pkgingzonlyFP;
1879781SMoriah.Waterland@Sun.COM 	char	pkgingzonlyPath[PATH_MAX];
1889781SMoriah.Waterland@Sun.COM 	int	len;
1899781SMoriah.Waterland@Sun.COM 
1909781SMoriah.Waterland@Sun.COM 	/* normalize root path */
1919781SMoriah.Waterland@Sun.COM 
1929781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
1939781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
1949781SMoriah.Waterland@Sun.COM 	}
1959781SMoriah.Waterland@Sun.COM 
1969781SMoriah.Waterland@Sun.COM 	/* generate path to glocal zone only list file */
1979781SMoriah.Waterland@Sun.COM 
1989781SMoriah.Waterland@Sun.COM 	len = snprintf(pkgingzonlyPath, sizeof (pkgingzonlyPath), "%s/%s",
1999781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
2009781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkgingzonlyPath)) {
2019781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
2029781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
2039781SMoriah.Waterland@Sun.COM 		return ((FILE *)NULL);
2049781SMoriah.Waterland@Sun.COM 	}
2059781SMoriah.Waterland@Sun.COM 
2069781SMoriah.Waterland@Sun.COM 	/* open global zone only list file */
2079781SMoriah.Waterland@Sun.COM 
2089781SMoriah.Waterland@Sun.COM 	pkgingzonlyFP = fopen(pkgingzonlyPath, "r+");
2099781SMoriah.Waterland@Sun.COM 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno == ENOENT)) {
2109781SMoriah.Waterland@Sun.COM 		pkgingzonlyFP = fopen(pkgingzonlyPath, "w+");
2119781SMoriah.Waterland@Sun.COM 	}
2129781SMoriah.Waterland@Sun.COM 
2139781SMoriah.Waterland@Sun.COM 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno != ENOENT)) {
2149781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_OPEN_GZONLY, pkgingzonlyPath,
2159781SMoriah.Waterland@Sun.COM 				strerror(errno));
2169781SMoriah.Waterland@Sun.COM 		return ((FILE *)NULL);
2179781SMoriah.Waterland@Sun.COM 	}
2189781SMoriah.Waterland@Sun.COM 
2199781SMoriah.Waterland@Sun.COM 	/* success - return FILE pointer open on global zone only list file */
2209781SMoriah.Waterland@Sun.COM 
2219781SMoriah.Waterland@Sun.COM 	return (pkgingzonlyFP);
2229781SMoriah.Waterland@Sun.COM }
2239781SMoriah.Waterland@Sun.COM 
2249781SMoriah.Waterland@Sun.COM /*
2259781SMoriah.Waterland@Sun.COM  * Name:	pkgIsPkgInGzOnly
2269781SMoriah.Waterland@Sun.COM  * Description:	determine if package is recorded as "in global zone only"
2279781SMoriah.Waterland@Sun.COM  *		by opening the appropriate files and searching for the
2289781SMoriah.Waterland@Sun.COM  *		specified package
2299781SMoriah.Waterland@Sun.COM  * Arguments:	a_rootPath - pointer to string representing the root path
2309781SMoriah.Waterland@Sun.COM  *			where the global zone only package list file is
2319781SMoriah.Waterland@Sun.COM  *			located - NULL is the same as "/"
2329781SMoriah.Waterland@Sun.COM  *		a_pkgInst - pointer to string representing the package instance
2339781SMoriah.Waterland@Sun.COM  *			(name) of the package to lookup
2349781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
2359781SMoriah.Waterland@Sun.COM  *			B_TRUE - package is recorded as "in global zone only"
2369781SMoriah.Waterland@Sun.COM  *			B_FALSE - package is NOT recorded as "in gz only"
2379781SMoriah.Waterland@Sun.COM  * NOTE:	This function will create the file if it does not exist.
2389781SMoriah.Waterland@Sun.COM  */
2399781SMoriah.Waterland@Sun.COM 
2409781SMoriah.Waterland@Sun.COM boolean_t
pkgIsPkgInGzOnly(char * a_rootPath,char * a_pkgInst)2419781SMoriah.Waterland@Sun.COM pkgIsPkgInGzOnly(char *a_rootPath, char *a_pkgInst)
2429781SMoriah.Waterland@Sun.COM {
2439781SMoriah.Waterland@Sun.COM 	FILE		*fp;
2449781SMoriah.Waterland@Sun.COM 	boolean_t	in_gz_only;
2459781SMoriah.Waterland@Sun.COM 
2469781SMoriah.Waterland@Sun.COM 	/* normalize root path */
2479781SMoriah.Waterland@Sun.COM 
2489781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
2499781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
2509781SMoriah.Waterland@Sun.COM 	}
2519781SMoriah.Waterland@Sun.COM 
2529781SMoriah.Waterland@Sun.COM 	/* open the global zone only package list file */
2539781SMoriah.Waterland@Sun.COM 
2549781SMoriah.Waterland@Sun.COM 	fp = pkgOpenInGzOnlyFile(a_rootPath);
2559781SMoriah.Waterland@Sun.COM 	if (fp == (FILE *)NULL) {
2569781SMoriah.Waterland@Sun.COM 		echoDebug(ERR_PKGOPS_CANNOT_OPEN_GZONLY,
2579781SMoriah.Waterland@Sun.COM 				a_rootPath ? a_rootPath : "/");
2589781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2599781SMoriah.Waterland@Sun.COM 	}
2609781SMoriah.Waterland@Sun.COM 
2619781SMoriah.Waterland@Sun.COM 	/* is the package recorded as "in global zone only" ? */
2629781SMoriah.Waterland@Sun.COM 
2639781SMoriah.Waterland@Sun.COM 	in_gz_only = pkgIsPkgInGzOnlyFP(fp, a_pkgInst);
2649781SMoriah.Waterland@Sun.COM 
2659781SMoriah.Waterland@Sun.COM 	/* close the global zone only package list file */
2669781SMoriah.Waterland@Sun.COM 
2679781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
2689781SMoriah.Waterland@Sun.COM 
2699781SMoriah.Waterland@Sun.COM 	/* return results */
2709781SMoriah.Waterland@Sun.COM 
2719781SMoriah.Waterland@Sun.COM 	return (in_gz_only);
2729781SMoriah.Waterland@Sun.COM }
2739781SMoriah.Waterland@Sun.COM 
2749781SMoriah.Waterland@Sun.COM /*
2759781SMoriah.Waterland@Sun.COM  * Name:	pkgIsPkgInGzOnly
2769781SMoriah.Waterland@Sun.COM  * Description:	determine if package is recorded as "in global zone only"
2779781SMoriah.Waterland@Sun.COM  *		by searching the specified open FILE for the specified package
2789781SMoriah.Waterland@Sun.COM  * Arguments:	a_fp - pointer to FILE handle open on file to search
2799781SMoriah.Waterland@Sun.COM  *		a_pkgInst - pointer to string representing the package instance
2809781SMoriah.Waterland@Sun.COM  *			(name) of the package to lookup
2819781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
2829781SMoriah.Waterland@Sun.COM  *			B_TRUE - package is recorded as "in global zone only"
2839781SMoriah.Waterland@Sun.COM  *			B_FALSE - package is NOT recorded as "in gz only"
2849781SMoriah.Waterland@Sun.COM  */
2859781SMoriah.Waterland@Sun.COM 
2869781SMoriah.Waterland@Sun.COM boolean_t
pkgIsPkgInGzOnlyFP(FILE * a_fp,char * a_pkgInst)2879781SMoriah.Waterland@Sun.COM pkgIsPkgInGzOnlyFP(FILE *a_fp, char *a_pkgInst)
2889781SMoriah.Waterland@Sun.COM {
2899781SMoriah.Waterland@Sun.COM 	char	line[PATH_MAX+1];
2909781SMoriah.Waterland@Sun.COM 
2919781SMoriah.Waterland@Sun.COM 	/* entry assertions */
2929781SMoriah.Waterland@Sun.COM 
2939781SMoriah.Waterland@Sun.COM 	assert(a_fp != (FILE *)NULL);
2949781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
2959781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
2969781SMoriah.Waterland@Sun.COM 
2979781SMoriah.Waterland@Sun.COM 	/* rewind the file to the beginning */
2989781SMoriah.Waterland@Sun.COM 
2999781SMoriah.Waterland@Sun.COM 	rewind(a_fp);
3009781SMoriah.Waterland@Sun.COM 
3019781SMoriah.Waterland@Sun.COM 	/* read the file line by line searching for the specified package */
3029781SMoriah.Waterland@Sun.COM 
3039781SMoriah.Waterland@Sun.COM 	while (fgets(line, sizeof (line), a_fp) != (char *)NULL) {
3049781SMoriah.Waterland@Sun.COM 		int	len;
3059781SMoriah.Waterland@Sun.COM 
3069781SMoriah.Waterland@Sun.COM 		/* strip off trailing newlines */
3079781SMoriah.Waterland@Sun.COM 		len = strlen(line);
3089781SMoriah.Waterland@Sun.COM 		while ((len > 0) && (line[len-1] == '\n')) {
3099781SMoriah.Waterland@Sun.COM 			line[--len] = '\0';
3109781SMoriah.Waterland@Sun.COM 		}
3119781SMoriah.Waterland@Sun.COM 
3129781SMoriah.Waterland@Sun.COM 		/* ignore blank and comment lines */
3139781SMoriah.Waterland@Sun.COM 		if ((line[0] == '#') || (line[0] == '\0')) {
3149781SMoriah.Waterland@Sun.COM 			continue;
3159781SMoriah.Waterland@Sun.COM 		}
3169781SMoriah.Waterland@Sun.COM 
3179781SMoriah.Waterland@Sun.COM 		/* return true if this is the package we are looking for */
3189781SMoriah.Waterland@Sun.COM 		if (strcmp(a_pkgInst, line) == 0) {
3199781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGOPS_PKG_IS_GZONLY, a_pkgInst);
3209781SMoriah.Waterland@Sun.COM 			return (B_TRUE);
3219781SMoriah.Waterland@Sun.COM 		}
3229781SMoriah.Waterland@Sun.COM 	}
3239781SMoriah.Waterland@Sun.COM 
3249781SMoriah.Waterland@Sun.COM 	/* end of file - package not found */
3259781SMoriah.Waterland@Sun.COM 
3269781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_PKG_NOT_GZONLY, a_pkgInst);
3279781SMoriah.Waterland@Sun.COM 
3289781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
3299781SMoriah.Waterland@Sun.COM }
3309781SMoriah.Waterland@Sun.COM 
3319781SMoriah.Waterland@Sun.COM /*
3329781SMoriah.Waterland@Sun.COM  * Name:	pkgRemovePackageFromGzonlyList
3339781SMoriah.Waterland@Sun.COM  * Description:	Remove specified package from the global zone only package list
3349781SMoriah.Waterland@Sun.COM  *		file located at a specified root path
3359781SMoriah.Waterland@Sun.COM  * Arguments:	a_rootPath - pointer to string representing the root path
3369781SMoriah.Waterland@Sun.COM  *			where the global zone only package list file is
3379781SMoriah.Waterland@Sun.COM  *			located - NULL is the same as "/"
3389781SMoriah.Waterland@Sun.COM  *		a_pkgInst - pointer to string representing the package instance
3399781SMoriah.Waterland@Sun.COM  *			(name) of the package to remove
3409781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
3419781SMoriah.Waterland@Sun.COM  *			B_TRUE - package is successfully removed
3429781SMoriah.Waterland@Sun.COM  *			B_FALSE - failed to remove package from file
3439781SMoriah.Waterland@Sun.COM  * NOTE:	This function will create the file if it does not exist.
3449781SMoriah.Waterland@Sun.COM  */
3459781SMoriah.Waterland@Sun.COM 
3469781SMoriah.Waterland@Sun.COM boolean_t
pkgRemovePackageFromGzonlyList(char * a_rootPath,char * a_pkgInst)3479781SMoriah.Waterland@Sun.COM pkgRemovePackageFromGzonlyList(char *a_rootPath, char *a_pkgInst)
3489781SMoriah.Waterland@Sun.COM {
3499781SMoriah.Waterland@Sun.COM 	FILE		*destFP;
3509781SMoriah.Waterland@Sun.COM 	FILE		*srcFP;
3519781SMoriah.Waterland@Sun.COM 	boolean_t	pkgremoved = B_FALSE;
3529781SMoriah.Waterland@Sun.COM 	char		destPath[PATH_MAX];
3539781SMoriah.Waterland@Sun.COM 	char		line[PATH_MAX+1];
3549781SMoriah.Waterland@Sun.COM 	char		savePath[PATH_MAX];
3559781SMoriah.Waterland@Sun.COM 	char		srcPath[PATH_MAX];
3569781SMoriah.Waterland@Sun.COM 	char		timeb[BUFSIZ];
3579781SMoriah.Waterland@Sun.COM 	int		len;
3589781SMoriah.Waterland@Sun.COM 	struct tm	*timep;
3599781SMoriah.Waterland@Sun.COM 	time_t		clock;
3609781SMoriah.Waterland@Sun.COM 
3619781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3629781SMoriah.Waterland@Sun.COM 
3639781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
3649781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
3659781SMoriah.Waterland@Sun.COM 
3669781SMoriah.Waterland@Sun.COM 	/* normalize root path */
3679781SMoriah.Waterland@Sun.COM 
3689781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
3699781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
3709781SMoriah.Waterland@Sun.COM 	}
3719781SMoriah.Waterland@Sun.COM 
3729781SMoriah.Waterland@Sun.COM 	/*
3739781SMoriah.Waterland@Sun.COM 	 * calculate paths to various objects
3749781SMoriah.Waterland@Sun.COM 	 */
3759781SMoriah.Waterland@Sun.COM 
3769781SMoriah.Waterland@Sun.COM 	/* path to current "source" ingzonly file */
3779781SMoriah.Waterland@Sun.COM 
3789781SMoriah.Waterland@Sun.COM 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
3799781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3809781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
3819781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
3829781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3839781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
3849781SMoriah.Waterland@Sun.COM 	}
3859781SMoriah.Waterland@Sun.COM 
3869781SMoriah.Waterland@Sun.COM 	/* path to new "destination" ingzonly file */
3879781SMoriah.Waterland@Sun.COM 
3889781SMoriah.Waterland@Sun.COM 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
3899781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3909781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
3919781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
3929781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
3939781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
3949781SMoriah.Waterland@Sun.COM 	}
3959781SMoriah.Waterland@Sun.COM 
3969781SMoriah.Waterland@Sun.COM 	/* path to temporary "saved" ingzonly file */
3979781SMoriah.Waterland@Sun.COM 
3989781SMoriah.Waterland@Sun.COM 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
3999781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
4009781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
4019781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
4029781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
4039781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4049781SMoriah.Waterland@Sun.COM 	}
4059781SMoriah.Waterland@Sun.COM 
4069781SMoriah.Waterland@Sun.COM 	/* open source file, creating if necessary */
4079781SMoriah.Waterland@Sun.COM 
4089781SMoriah.Waterland@Sun.COM 	srcFP = fopen(srcPath, "r+");
4099781SMoriah.Waterland@Sun.COM 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
4109781SMoriah.Waterland@Sun.COM 		srcFP = fopen(srcPath, "w+");
4119781SMoriah.Waterland@Sun.COM 	}
4129781SMoriah.Waterland@Sun.COM 
4139781SMoriah.Waterland@Sun.COM 	/* error if could not open/create file */
4149781SMoriah.Waterland@Sun.COM 
4159781SMoriah.Waterland@Sun.COM 	if (srcFP == (FILE *)NULL) {
4169781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
4179781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4189781SMoriah.Waterland@Sun.COM 	}
4199781SMoriah.Waterland@Sun.COM 
4209781SMoriah.Waterland@Sun.COM 	/* open/create new destination file */
4219781SMoriah.Waterland@Sun.COM 
4229781SMoriah.Waterland@Sun.COM 	(void) remove(destPath);
4239781SMoriah.Waterland@Sun.COM 	destFP = fopen(destPath, "w");
4249781SMoriah.Waterland@Sun.COM 	if (destFP == (FILE *)NULL) {
4259781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
4269781SMoriah.Waterland@Sun.COM 		if (srcFP != (FILE *)NULL) {
4279781SMoriah.Waterland@Sun.COM 			(void) fclose(srcFP);
4289781SMoriah.Waterland@Sun.COM 		}
4299781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4309781SMoriah.Waterland@Sun.COM 	}
4319781SMoriah.Waterland@Sun.COM 
4329781SMoriah.Waterland@Sun.COM 	/* add standard comment to beginning of file */
4339781SMoriah.Waterland@Sun.COM 
4349781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
4359781SMoriah.Waterland@Sun.COM 	timep = localtime(&clock);
4369781SMoriah.Waterland@Sun.COM 
4379781SMoriah.Waterland@Sun.COM 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
4389781SMoriah.Waterland@Sun.COM 
4399781SMoriah.Waterland@Sun.COM 	/* put standard header at the beginning of the file */
4409781SMoriah.Waterland@Sun.COM 
4419781SMoriah.Waterland@Sun.COM 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
4429781SMoriah.Waterland@Sun.COM 			get_prog_name(), "remove", a_pkgInst, timeb);
4439781SMoriah.Waterland@Sun.COM 
4449781SMoriah.Waterland@Sun.COM 	/* read source/write destination - removing specified package */
4459781SMoriah.Waterland@Sun.COM 
4469781SMoriah.Waterland@Sun.COM 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
4479781SMoriah.Waterland@Sun.COM 		int	len;
4489781SMoriah.Waterland@Sun.COM 
4499781SMoriah.Waterland@Sun.COM 		/* strip off trailing newlines */
4509781SMoriah.Waterland@Sun.COM 		len = strlen(line);
4519781SMoriah.Waterland@Sun.COM 		while ((len > 0) && (line[len-1] == '\n')) {
4529781SMoriah.Waterland@Sun.COM 			line[--len] = '\0';
4539781SMoriah.Waterland@Sun.COM 		}
4549781SMoriah.Waterland@Sun.COM 
4559781SMoriah.Waterland@Sun.COM 		/* ignore blank and comment lines */
4569781SMoriah.Waterland@Sun.COM 		if ((line[0] == '#') || (line[0] == '\0')) {
4579781SMoriah.Waterland@Sun.COM 			continue;
4589781SMoriah.Waterland@Sun.COM 		}
4599781SMoriah.Waterland@Sun.COM 
4609781SMoriah.Waterland@Sun.COM 		/* add pkg if yet to add and pkg <= line */
4619781SMoriah.Waterland@Sun.COM 		if ((pkgremoved == B_FALSE) && (strcmp(a_pkgInst, line) == 0)) {
4629781SMoriah.Waterland@Sun.COM 			pkgremoved = B_TRUE;
4639781SMoriah.Waterland@Sun.COM 		} else {
4649781SMoriah.Waterland@Sun.COM 			(void) fprintf(destFP, "%s\n", line);
4659781SMoriah.Waterland@Sun.COM 		}
4669781SMoriah.Waterland@Sun.COM 	}
4679781SMoriah.Waterland@Sun.COM 
4689781SMoriah.Waterland@Sun.COM 	/* close both files */
4699781SMoriah.Waterland@Sun.COM 
4709781SMoriah.Waterland@Sun.COM 	(void) fclose(srcFP);
4719781SMoriah.Waterland@Sun.COM 
4729781SMoriah.Waterland@Sun.COM 	(void) fclose(destFP);
4739781SMoriah.Waterland@Sun.COM 
4749781SMoriah.Waterland@Sun.COM 	/*
4759781SMoriah.Waterland@Sun.COM 	 * if package not found there is no need to update the original file
4769781SMoriah.Waterland@Sun.COM 	 */
4779781SMoriah.Waterland@Sun.COM 
4789781SMoriah.Waterland@Sun.COM 	if (pkgremoved == B_FALSE) {
4799781SMoriah.Waterland@Sun.COM 		(void) unlink(destPath);
4809781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
4819781SMoriah.Waterland@Sun.COM 	}
4829781SMoriah.Waterland@Sun.COM 
4839781SMoriah.Waterland@Sun.COM 	/*
4849781SMoriah.Waterland@Sun.COM 	 * Now we want to make a copy of the old gzonly file as a
4859781SMoriah.Waterland@Sun.COM 	 * fail-safe.
4869781SMoriah.Waterland@Sun.COM 	 */
4879781SMoriah.Waterland@Sun.COM 
4889781SMoriah.Waterland@Sun.COM 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
4899781SMoriah.Waterland@Sun.COM 		progerr(ERR_REMOVE, savePath, strerror(errno));
4909781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
4919781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4929781SMoriah.Waterland@Sun.COM 	}
4939781SMoriah.Waterland@Sun.COM 
4949781SMoriah.Waterland@Sun.COM 	if (link(srcPath, savePath) != 0) {
4959781SMoriah.Waterland@Sun.COM 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
4969781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
4979781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4989781SMoriah.Waterland@Sun.COM 	}
4999781SMoriah.Waterland@Sun.COM 
5009781SMoriah.Waterland@Sun.COM 	if (rename(destPath, srcPath) != 0) {
5019781SMoriah.Waterland@Sun.COM 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
5029781SMoriah.Waterland@Sun.COM 		if (rename(savePath, srcPath)) {
5039781SMoriah.Waterland@Sun.COM 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
5049781SMoriah.Waterland@Sun.COM 		}
5059781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
5069781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
5079781SMoriah.Waterland@Sun.COM 	}
5089781SMoriah.Waterland@Sun.COM 
5099781SMoriah.Waterland@Sun.COM 	if (remove(savePath) != 0) {
5109781SMoriah.Waterland@Sun.COM 		progerr(ERR_REMOVE, savePath, strerror(errno));
5119781SMoriah.Waterland@Sun.COM 	}
5129781SMoriah.Waterland@Sun.COM 
5139781SMoriah.Waterland@Sun.COM 	/* successfully removed package */
5149781SMoriah.Waterland@Sun.COM 
5159781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_REMOVED_GZPKG, a_pkgInst);
5169781SMoriah.Waterland@Sun.COM 
5179781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
5189781SMoriah.Waterland@Sun.COM }
5199781SMoriah.Waterland@Sun.COM 
5209781SMoriah.Waterland@Sun.COM /*
5219781SMoriah.Waterland@Sun.COM  * Name:	pkgAddPackageFromGzonlyList
5229781SMoriah.Waterland@Sun.COM  * Description:	Add specified package to the global zone only package list
5239781SMoriah.Waterland@Sun.COM  *		file located at a specified root path
5249781SMoriah.Waterland@Sun.COM  * Arguments:	a_rootPath - pointer to string representing the root path
5259781SMoriah.Waterland@Sun.COM  *			where the global zone only package list file is
5269781SMoriah.Waterland@Sun.COM  *			located - NULL is the same as "/"
5279781SMoriah.Waterland@Sun.COM  *		a_pkgInst - pointer to string representing the package instance
5289781SMoriah.Waterland@Sun.COM  *			(name) of the package to add
5299781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
5309781SMoriah.Waterland@Sun.COM  *			B_TRUE - package is successfully added
5319781SMoriah.Waterland@Sun.COM  *			B_FALSE - failed to add package to the file
5329781SMoriah.Waterland@Sun.COM  * NOTE:	This function will create the file if it does not exist.
5339781SMoriah.Waterland@Sun.COM  */
5349781SMoriah.Waterland@Sun.COM 
5359781SMoriah.Waterland@Sun.COM boolean_t
pkgAddPackageToGzonlyList(char * a_pkgInst,char * a_rootPath)5369781SMoriah.Waterland@Sun.COM pkgAddPackageToGzonlyList(char *a_pkgInst, char *a_rootPath)
5379781SMoriah.Waterland@Sun.COM {
5389781SMoriah.Waterland@Sun.COM 	FILE		*destFP;
5399781SMoriah.Waterland@Sun.COM 	FILE		*srcFP;
5409781SMoriah.Waterland@Sun.COM 	boolean_t	pkgadded = B_FALSE;
5419781SMoriah.Waterland@Sun.COM 	char		destPath[PATH_MAX];
5429781SMoriah.Waterland@Sun.COM 	char		line[PATH_MAX+1];
5439781SMoriah.Waterland@Sun.COM 	char		savePath[PATH_MAX];
5449781SMoriah.Waterland@Sun.COM 	char		srcPath[PATH_MAX];
5459781SMoriah.Waterland@Sun.COM 	char		timeb[BUFSIZ];
5469781SMoriah.Waterland@Sun.COM 	int		len;
5479781SMoriah.Waterland@Sun.COM 	struct tm	*timep;
5489781SMoriah.Waterland@Sun.COM 	time_t		clock;
5499781SMoriah.Waterland@Sun.COM 
5509781SMoriah.Waterland@Sun.COM 	/* entry assertions */
5519781SMoriah.Waterland@Sun.COM 
5529781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
5539781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
5549781SMoriah.Waterland@Sun.COM 
5559781SMoriah.Waterland@Sun.COM 	/* normalize root path */
5569781SMoriah.Waterland@Sun.COM 
5579781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
5589781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
5599781SMoriah.Waterland@Sun.COM 	}
5609781SMoriah.Waterland@Sun.COM 
5619781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
5629781SMoriah.Waterland@Sun.COM 
5639781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_ADDGZPKG, a_pkgInst, a_rootPath);
5649781SMoriah.Waterland@Sun.COM 
5659781SMoriah.Waterland@Sun.COM 	/*
5669781SMoriah.Waterland@Sun.COM 	 * calculate paths to various objects
5679781SMoriah.Waterland@Sun.COM 	 */
5689781SMoriah.Waterland@Sun.COM 
5699781SMoriah.Waterland@Sun.COM 	/* path to current "source" ingzonly file */
5709781SMoriah.Waterland@Sun.COM 
5719781SMoriah.Waterland@Sun.COM 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
5729781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5739781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
5749781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5759781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5769781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
5779781SMoriah.Waterland@Sun.COM 	}
5789781SMoriah.Waterland@Sun.COM 
5799781SMoriah.Waterland@Sun.COM 	/* path to new "destination" ingzonly file */
5809781SMoriah.Waterland@Sun.COM 
5819781SMoriah.Waterland@Sun.COM 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
5829781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5839781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
5849781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5859781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5869781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
5879781SMoriah.Waterland@Sun.COM 	}
5889781SMoriah.Waterland@Sun.COM 
5899781SMoriah.Waterland@Sun.COM 	/* path to temporary "saved" ingzonly file */
5909781SMoriah.Waterland@Sun.COM 
5919781SMoriah.Waterland@Sun.COM 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
5929781SMoriah.Waterland@Sun.COM 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5939781SMoriah.Waterland@Sun.COM 	if (len > sizeof (srcPath)) {
5949781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_rootPath,
5959781SMoriah.Waterland@Sun.COM 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
5969781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
5979781SMoriah.Waterland@Sun.COM 	}
5989781SMoriah.Waterland@Sun.COM 
5999781SMoriah.Waterland@Sun.COM 	/* open source file, creating if necessary */
6009781SMoriah.Waterland@Sun.COM 
6019781SMoriah.Waterland@Sun.COM 	srcFP = fopen(srcPath, "r+");
6029781SMoriah.Waterland@Sun.COM 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
6039781SMoriah.Waterland@Sun.COM 		srcFP = fopen(srcPath, "w+");
6049781SMoriah.Waterland@Sun.COM 	}
6059781SMoriah.Waterland@Sun.COM 
6069781SMoriah.Waterland@Sun.COM 	/* error if could not open/create file */
6079781SMoriah.Waterland@Sun.COM 
6089781SMoriah.Waterland@Sun.COM 	if (srcFP == (FILE *)NULL) {
6099781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
6109781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
6119781SMoriah.Waterland@Sun.COM 	}
6129781SMoriah.Waterland@Sun.COM 
6139781SMoriah.Waterland@Sun.COM 	/* open/create new destination file */
6149781SMoriah.Waterland@Sun.COM 
6159781SMoriah.Waterland@Sun.COM 	(void) remove(destPath);
6169781SMoriah.Waterland@Sun.COM 	destFP = fopen(destPath, "w");
6179781SMoriah.Waterland@Sun.COM 	if (destFP == (FILE *)NULL) {
6189781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
6199781SMoriah.Waterland@Sun.COM 		if (srcFP != (FILE *)NULL) {
6209781SMoriah.Waterland@Sun.COM 			(void) fclose(srcFP);
6219781SMoriah.Waterland@Sun.COM 		}
6229781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
6239781SMoriah.Waterland@Sun.COM 	}
6249781SMoriah.Waterland@Sun.COM 
6259781SMoriah.Waterland@Sun.COM 	/* add standard comment to beginning of file */
6269781SMoriah.Waterland@Sun.COM 
6279781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
6289781SMoriah.Waterland@Sun.COM 	timep = localtime(&clock);
6299781SMoriah.Waterland@Sun.COM 
6309781SMoriah.Waterland@Sun.COM 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
6319781SMoriah.Waterland@Sun.COM 
6329781SMoriah.Waterland@Sun.COM 	/* put standard header at the beginning of the file */
6339781SMoriah.Waterland@Sun.COM 
6349781SMoriah.Waterland@Sun.COM 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
6359781SMoriah.Waterland@Sun.COM 			get_prog_name(), "add", a_pkgInst, timeb);
6369781SMoriah.Waterland@Sun.COM 
6379781SMoriah.Waterland@Sun.COM 	/* read source/write destination; add package at appropriate location */
6389781SMoriah.Waterland@Sun.COM 
6399781SMoriah.Waterland@Sun.COM 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
6409781SMoriah.Waterland@Sun.COM 		int	len;
6419781SMoriah.Waterland@Sun.COM 
6429781SMoriah.Waterland@Sun.COM 		/* strip off trailing newlines */
6439781SMoriah.Waterland@Sun.COM 		len = strlen(line);
6449781SMoriah.Waterland@Sun.COM 		while ((len > 0) && (line[len-1] == '\n')) {
6459781SMoriah.Waterland@Sun.COM 			line[--len] = '\0';
6469781SMoriah.Waterland@Sun.COM 		}
6479781SMoriah.Waterland@Sun.COM 
6489781SMoriah.Waterland@Sun.COM 		/* ignore blank and comment lines */
6499781SMoriah.Waterland@Sun.COM 		if ((line[0] == '#') || (line[0] == '\0')) {
6509781SMoriah.Waterland@Sun.COM 			continue;
6519781SMoriah.Waterland@Sun.COM 		}
6529781SMoriah.Waterland@Sun.COM 
6539781SMoriah.Waterland@Sun.COM 		/* add pkg if yet to add and pkg <= line */
6549781SMoriah.Waterland@Sun.COM 		if ((pkgadded == B_FALSE) && (strcmp(a_pkgInst, line) <= 0)) {
6559781SMoriah.Waterland@Sun.COM 			if (strcmp(a_pkgInst, line) != 0) {
6569781SMoriah.Waterland@Sun.COM 				(void) fprintf(destFP, "%s\n", a_pkgInst);
6579781SMoriah.Waterland@Sun.COM 			}
6589781SMoriah.Waterland@Sun.COM 			pkgadded = B_TRUE;
6599781SMoriah.Waterland@Sun.COM 		}
6609781SMoriah.Waterland@Sun.COM 
6619781SMoriah.Waterland@Sun.COM 		(void) fprintf(destFP, "%s\n", line);
6629781SMoriah.Waterland@Sun.COM 	}
6639781SMoriah.Waterland@Sun.COM 
6649781SMoriah.Waterland@Sun.COM 	/* if package not added yet, add to end of the file */
6659781SMoriah.Waterland@Sun.COM 
6669781SMoriah.Waterland@Sun.COM 	if (pkgadded == B_FALSE) {
6679781SMoriah.Waterland@Sun.COM 		(void) fprintf(destFP, "%s\n", a_pkgInst);
6689781SMoriah.Waterland@Sun.COM 	}
6699781SMoriah.Waterland@Sun.COM 
6709781SMoriah.Waterland@Sun.COM 	/* close both files */
6719781SMoriah.Waterland@Sun.COM 
6729781SMoriah.Waterland@Sun.COM 	(void) fclose(srcFP);
6739781SMoriah.Waterland@Sun.COM 
6749781SMoriah.Waterland@Sun.COM 	(void) fclose(destFP);
6759781SMoriah.Waterland@Sun.COM 
6769781SMoriah.Waterland@Sun.COM 	/*
6779781SMoriah.Waterland@Sun.COM 	 * Now we want to make a copy of the old gzonly file as a
6789781SMoriah.Waterland@Sun.COM 	 * fail-safe.
6799781SMoriah.Waterland@Sun.COM 	 */
6809781SMoriah.Waterland@Sun.COM 
6819781SMoriah.Waterland@Sun.COM 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
6829781SMoriah.Waterland@Sun.COM 		progerr(ERR_REMOVE, savePath, strerror(errno));
6839781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
6849781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
6859781SMoriah.Waterland@Sun.COM 	}
6869781SMoriah.Waterland@Sun.COM 
6879781SMoriah.Waterland@Sun.COM 	if (link(srcPath, savePath) != 0) {
6889781SMoriah.Waterland@Sun.COM 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
6899781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
6909781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
6919781SMoriah.Waterland@Sun.COM 	}
6929781SMoriah.Waterland@Sun.COM 
6939781SMoriah.Waterland@Sun.COM 	if (rename(destPath, srcPath) != 0) {
6949781SMoriah.Waterland@Sun.COM 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
6959781SMoriah.Waterland@Sun.COM 		if (rename(savePath, srcPath)) {
6969781SMoriah.Waterland@Sun.COM 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
6979781SMoriah.Waterland@Sun.COM 		}
6989781SMoriah.Waterland@Sun.COM 		(void) remove(destPath);
6999781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
7009781SMoriah.Waterland@Sun.COM 	}
7019781SMoriah.Waterland@Sun.COM 
7029781SMoriah.Waterland@Sun.COM 	if (remove(savePath) != 0) {
7039781SMoriah.Waterland@Sun.COM 		progerr(ERR_REMOVE, savePath, strerror(errno));
7049781SMoriah.Waterland@Sun.COM 	}
7059781SMoriah.Waterland@Sun.COM 
7069781SMoriah.Waterland@Sun.COM 	/* successfully added package */
7079781SMoriah.Waterland@Sun.COM 
7089781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_ADDED_GZPKG, a_pkgInst);
7099781SMoriah.Waterland@Sun.COM 
7109781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
7119781SMoriah.Waterland@Sun.COM }
7129781SMoriah.Waterland@Sun.COM 
7139781SMoriah.Waterland@Sun.COM /*
7149781SMoriah.Waterland@Sun.COM  * Name:	pkginfoParamTruth
7159781SMoriah.Waterland@Sun.COM  * Description:	Search pkginfo file for specified parameter/value pair
7169781SMoriah.Waterland@Sun.COM  * Arguments:	a_fp - Pointer to FILE handle open on pkginfo file to search
7179781SMoriah.Waterland@Sun.COM  *		a_param - Pointer to string representing the parameter name
7189781SMoriah.Waterland@Sun.COM  *			to search for
7199781SMoriah.Waterland@Sun.COM  *		a_value - Pointer to string representing the "success" value
7209781SMoriah.Waterland@Sun.COM  *			being searched for
7219781SMoriah.Waterland@Sun.COM  *		a_default - determine results if parameter NOT found
7229781SMoriah.Waterland@Sun.COM  *			B_TRUE - parameter is TRUE if not found
7239781SMoriah.Waterland@Sun.COM  *			B_FALSE - parameter is FALSE if not found
7249781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
7259781SMoriah.Waterland@Sun.COM  *		B_TRUE - the parameter was found and matched the specified value
7269781SMoriah.Waterland@Sun.COM  *			OR the paramter was not found and a_default == B_TRUE
7279781SMoriah.Waterland@Sun.COM  *		B_FALSE - the parameter was found and did NOT match the value
7289781SMoriah.Waterland@Sun.COM  *			OR the paramter was not found and a_default == B_FALSE
7299781SMoriah.Waterland@Sun.COM  */
7309781SMoriah.Waterland@Sun.COM 
7319781SMoriah.Waterland@Sun.COM boolean_t
pkginfoParamTruth(FILE * a_fp,char * a_param,char * a_value,boolean_t a_default)7329781SMoriah.Waterland@Sun.COM pkginfoParamTruth(FILE *a_fp, char *a_param, char *a_value, boolean_t a_default)
7339781SMoriah.Waterland@Sun.COM {
7349781SMoriah.Waterland@Sun.COM 	char		*param;
7359781SMoriah.Waterland@Sun.COM 	boolean_t	result;
7369781SMoriah.Waterland@Sun.COM 
7379781SMoriah.Waterland@Sun.COM 	/* entry assertions */
7389781SMoriah.Waterland@Sun.COM 
7399781SMoriah.Waterland@Sun.COM 	assert(a_fp != (FILE *)NULL);
7409781SMoriah.Waterland@Sun.COM 	assert(a_param != (char *)NULL);
7419781SMoriah.Waterland@Sun.COM 	assert(*a_param != '\0');
7429781SMoriah.Waterland@Sun.COM 	assert(a_value != (char *)NULL);
7439781SMoriah.Waterland@Sun.COM 	assert(*a_value != '\0');
7449781SMoriah.Waterland@Sun.COM 
7459781SMoriah.Waterland@Sun.COM 	/* rewind the file to the beginning */
7469781SMoriah.Waterland@Sun.COM 
7479781SMoriah.Waterland@Sun.COM 	rewind(a_fp);
7489781SMoriah.Waterland@Sun.COM 
7499781SMoriah.Waterland@Sun.COM 	/* search pkginfo file for the specified parameter */
7509781SMoriah.Waterland@Sun.COM 
7519781SMoriah.Waterland@Sun.COM 	param = fpkgparam(a_fp, a_param);
7529781SMoriah.Waterland@Sun.COM 
7539781SMoriah.Waterland@Sun.COM 	if (param == (char *)NULL) {
7549781SMoriah.Waterland@Sun.COM 		/* parameter not found - return default */
7559781SMoriah.Waterland@Sun.COM 		result = a_default;
7569781SMoriah.Waterland@Sun.COM 	} else if (*param == '\0') {
7579781SMoriah.Waterland@Sun.COM 		/* parameter found but no value - return default */
7589781SMoriah.Waterland@Sun.COM 		result = a_default;
7599781SMoriah.Waterland@Sun.COM 	} else if (strcasecmp(param, a_value) == 0) {
7609781SMoriah.Waterland@Sun.COM 		/* paramter found - matches value */
7619781SMoriah.Waterland@Sun.COM 		result = B_TRUE;
7629781SMoriah.Waterland@Sun.COM 	} else {
7639781SMoriah.Waterland@Sun.COM 		/* parameter found - does not match value */
7649781SMoriah.Waterland@Sun.COM 		result = B_FALSE;
7659781SMoriah.Waterland@Sun.COM 	}
7669781SMoriah.Waterland@Sun.COM 
7679781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
7689781SMoriah.Waterland@Sun.COM 
7699781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_PARAMTRUTH_RESULTS,
7709781SMoriah.Waterland@Sun.COM 		a_param, a_value, a_default == B_TRUE ? "true" : "false",
7719781SMoriah.Waterland@Sun.COM 		param ? param : "?", result == B_TRUE ? "true" : "false");
7729781SMoriah.Waterland@Sun.COM 
7739781SMoriah.Waterland@Sun.COM 	/* if parameter value found, free results */
7749781SMoriah.Waterland@Sun.COM 
7759781SMoriah.Waterland@Sun.COM 	if (param != (char *)NULL) {
7769781SMoriah.Waterland@Sun.COM 		(void) free(param);
7779781SMoriah.Waterland@Sun.COM 	}
7789781SMoriah.Waterland@Sun.COM 
7799781SMoriah.Waterland@Sun.COM 	/* return results of search */
7809781SMoriah.Waterland@Sun.COM 
7819781SMoriah.Waterland@Sun.COM 	return (result);
7829781SMoriah.Waterland@Sun.COM }
7839781SMoriah.Waterland@Sun.COM 
7849781SMoriah.Waterland@Sun.COM /*
7859781SMoriah.Waterland@Sun.COM  * Name:	pkgGetPackageList
7869781SMoriah.Waterland@Sun.COM  * Description:	Determine list of packages based on list of packages that are
7879781SMoriah.Waterland@Sun.COM  *		available, category of packages to select, and list of packages
7889781SMoriah.Waterland@Sun.COM  *		to select.
7899781SMoriah.Waterland@Sun.COM  * Arguments:	r_pkgList - pointer to pointer to string array where the list
7909781SMoriah.Waterland@Sun.COM  *			of selected packages will be returned
7919781SMoriah.Waterland@Sun.COM  *		a_argv - pointer to string array containing list of packages
7929781SMoriah.Waterland@Sun.COM  *			to select
7939781SMoriah.Waterland@Sun.COM  *		a_optind - index into string array of first package to select
7949781SMoriah.Waterland@Sun.COM  *		a_categories - pointer to string representing the categories of
7959781SMoriah.Waterland@Sun.COM  *			packages to select
7969781SMoriah.Waterland@Sun.COM  *		a_categoryList - pointer to string array representing a list
7979781SMoriah.Waterland@Sun.COM  *			of categories to select
7989781SMoriah.Waterland@Sun.COM  *		a_pkgdev - package dev containing packages that can be selected
7999781SMoriah.Waterland@Sun.COM  * Returns:	int
8009781SMoriah.Waterland@Sun.COM  *	== 0  - packages found r_pkgList contains results package list retrieved
8019781SMoriah.Waterland@Sun.COM  *	== -1 - no packages found (errno == ENOPKG)
8029781SMoriah.Waterland@Sun.COM  *	!= 0 - "quit" value entered by user
8039781SMoriah.Waterland@Sun.COM  * NOTE:	If both a category and a list of packages to select are provided
8049781SMoriah.Waterland@Sun.COM  *		the category is used over the list of packages provided
8059781SMoriah.Waterland@Sun.COM  * NOTE:	If neither a category nor a list of packages to select are
8069781SMoriah.Waterland@Sun.COM  *		provided, an error is returned
8079781SMoriah.Waterland@Sun.COM  */
8089781SMoriah.Waterland@Sun.COM 
8099781SMoriah.Waterland@Sun.COM int
pkgGetPackageList(char *** r_pkgList,char ** a_argv,int a_optind,char * a_categories,char ** a_categoryList,struct pkgdev * a_pkgdev)8109781SMoriah.Waterland@Sun.COM pkgGetPackageList(char ***r_pkgList, char **a_argv, int a_optind,
8119781SMoriah.Waterland@Sun.COM 	char *a_categories, char **a_categoryList, struct pkgdev *a_pkgdev)
8129781SMoriah.Waterland@Sun.COM {
8139781SMoriah.Waterland@Sun.COM 	char	*all_pkgs[4] = {"all", NULL};
8149781SMoriah.Waterland@Sun.COM 
8159781SMoriah.Waterland@Sun.COM 	/* entry assertions */
8169781SMoriah.Waterland@Sun.COM 
8179781SMoriah.Waterland@Sun.COM 	assert(a_pkgdev != (struct pkgdev *)NULL);
8189781SMoriah.Waterland@Sun.COM 	assert(a_pkgdev->dirname != (char *)NULL);
8199781SMoriah.Waterland@Sun.COM 	assert(*a_pkgdev->dirname != '\0');
8209781SMoriah.Waterland@Sun.COM 	assert(r_pkgList != (char ***)NULL);
8219781SMoriah.Waterland@Sun.COM 	assert(a_argv != (char **)NULL);
8229781SMoriah.Waterland@Sun.COM 
8239781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
8249781SMoriah.Waterland@Sun.COM 
8259781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_GETPKGLIST_ENTRY);
8269781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_GETPKGLIST_ARGS, a_pkgdev->dirname,
8279781SMoriah.Waterland@Sun.COM 			a_categories ? a_categories : "?");
8289781SMoriah.Waterland@Sun.COM 
8299781SMoriah.Waterland@Sun.COM 	/* reset returned package list handle */
8309781SMoriah.Waterland@Sun.COM 
8319781SMoriah.Waterland@Sun.COM 	*r_pkgList = (char **)NULL;
8329781SMoriah.Waterland@Sun.COM 
8339781SMoriah.Waterland@Sun.COM 	/*
8349781SMoriah.Waterland@Sun.COM 	 * generate list of packages to be removed: if removing by category,
8359781SMoriah.Waterland@Sun.COM 	 * then generate package list based on all packages by category,
8369781SMoriah.Waterland@Sun.COM 	 * else generate package list based on all packages specified.
8379781SMoriah.Waterland@Sun.COM 	 */
8389781SMoriah.Waterland@Sun.COM 
8399781SMoriah.Waterland@Sun.COM 	if (a_categories != NULL) {
8409781SMoriah.Waterland@Sun.COM 		/* generate package list from all packages in given category */
8419781SMoriah.Waterland@Sun.COM 
8429781SMoriah.Waterland@Sun.COM 		*r_pkgList = gpkglist(a_pkgdev->dirname, &all_pkgs[0],
8439781SMoriah.Waterland@Sun.COM 					a_categoryList);
8449781SMoriah.Waterland@Sun.COM 
8459781SMoriah.Waterland@Sun.COM 		if (*r_pkgList == NULL) {
8469781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGOPS_GPKGLIST_CATFAILED, a_categories);
8479781SMoriah.Waterland@Sun.COM 			progerr(ERR_CAT_FND, a_categories);
8489781SMoriah.Waterland@Sun.COM 			return (1);
8499781SMoriah.Waterland@Sun.COM 		}
8509781SMoriah.Waterland@Sun.COM 
8519781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_CATOK, a_categories);
8529781SMoriah.Waterland@Sun.COM 
8539781SMoriah.Waterland@Sun.COM 		return (0);
8549781SMoriah.Waterland@Sun.COM 	}
8559781SMoriah.Waterland@Sun.COM 
8569781SMoriah.Waterland@Sun.COM 	/* generate package list from specified packages */
8579781SMoriah.Waterland@Sun.COM 
8589781SMoriah.Waterland@Sun.COM 	*r_pkgList = gpkglist(a_pkgdev->dirname, &a_argv[a_optind], NULL);
8599781SMoriah.Waterland@Sun.COM 
8609781SMoriah.Waterland@Sun.COM 	/* if list generated return results */
8619781SMoriah.Waterland@Sun.COM 
8629781SMoriah.Waterland@Sun.COM 	if (*r_pkgList != NULL) {
8639781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_OK);
8649781SMoriah.Waterland@Sun.COM 		return (0);
8659781SMoriah.Waterland@Sun.COM 	}
8669781SMoriah.Waterland@Sun.COM 
8679781SMoriah.Waterland@Sun.COM 	/* handle error from gpkglist */
8689781SMoriah.Waterland@Sun.COM 
8699781SMoriah.Waterland@Sun.COM 	switch (errno) {
8709781SMoriah.Waterland@Sun.COM 	    case ENOPKG:	/* no packages */
8719781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_ENOPKG);
8729781SMoriah.Waterland@Sun.COM 		return (-1);
8739781SMoriah.Waterland@Sun.COM 
8749781SMoriah.Waterland@Sun.COM 	    case ESRCH:
8759781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_ESRCH);
8769781SMoriah.Waterland@Sun.COM 		return (1);
8779781SMoriah.Waterland@Sun.COM 
8789781SMoriah.Waterland@Sun.COM 	    case EINTR:
8799781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_EINTR);
8809781SMoriah.Waterland@Sun.COM 		return (3);
8819781SMoriah.Waterland@Sun.COM 
8829781SMoriah.Waterland@Sun.COM 	    default:
8839781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_GPKGLIST_UNKNOWN, errno);
8849781SMoriah.Waterland@Sun.COM 		progerr(ERR_GPKGLIST_ERROR);
8859781SMoriah.Waterland@Sun.COM 		return (99);
8869781SMoriah.Waterland@Sun.COM 	}
8879781SMoriah.Waterland@Sun.COM }
8889781SMoriah.Waterland@Sun.COM 
8899781SMoriah.Waterland@Sun.COM /*
8909781SMoriah.Waterland@Sun.COM  * return string representing path to "global zone only file"
8919781SMoriah.Waterland@Sun.COM  */
8929781SMoriah.Waterland@Sun.COM 
8939781SMoriah.Waterland@Sun.COM char *
pkgGetGzOnlyPath(void)8949781SMoriah.Waterland@Sun.COM pkgGetGzOnlyPath(void)
8959781SMoriah.Waterland@Sun.COM {
8969781SMoriah.Waterland@Sun.COM 	return (GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
8979781SMoriah.Waterland@Sun.COM }
8989781SMoriah.Waterland@Sun.COM 
8999781SMoriah.Waterland@Sun.COM /*
9009781SMoriah.Waterland@Sun.COM  * Name:	pkgAddThisZonePackage
9019781SMoriah.Waterland@Sun.COM  * Description:	Add specified package to internal list of "this zone only" pkgs
9029781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgInst - name of package to add to list
9039781SMoriah.Waterland@Sun.COM  * Returns:	void
9049781SMoriah.Waterland@Sun.COM  */
9059781SMoriah.Waterland@Sun.COM 
9069781SMoriah.Waterland@Sun.COM void
pkgAddThisZonePackage(char * a_pkgInst)9079781SMoriah.Waterland@Sun.COM pkgAddThisZonePackage(char *a_pkgInst)
9089781SMoriah.Waterland@Sun.COM {
9099781SMoriah.Waterland@Sun.COM 	/* entry assertions */
9109781SMoriah.Waterland@Sun.COM 
9119781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
9129781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
9139781SMoriah.Waterland@Sun.COM 
9149781SMoriah.Waterland@Sun.COM 	/* do not duplicate entries */
9159781SMoriah.Waterland@Sun.COM 
9169781SMoriah.Waterland@Sun.COM 	if (pkgPackageIsThisZone(a_pkgInst) == B_TRUE) {
9179781SMoriah.Waterland@Sun.COM 		return;
9189781SMoriah.Waterland@Sun.COM 	}
9199781SMoriah.Waterland@Sun.COM 
9209781SMoriah.Waterland@Sun.COM 	/* add package name to internal list */
9219781SMoriah.Waterland@Sun.COM 
9229781SMoriah.Waterland@Sun.COM 	if (thisZonePackages == (char **)NULL) {
9239781SMoriah.Waterland@Sun.COM 		thisZonePackages =
9249781SMoriah.Waterland@Sun.COM 				(char **)calloc(2, sizeof (char **));
9259781SMoriah.Waterland@Sun.COM 	} else {
9269781SMoriah.Waterland@Sun.COM 		thisZonePackages =
9279781SMoriah.Waterland@Sun.COM 				(char **)realloc(thisZonePackages,
9289781SMoriah.Waterland@Sun.COM 				sizeof (char **)*(numThisZonePackages+2));
9299781SMoriah.Waterland@Sun.COM 	}
9309781SMoriah.Waterland@Sun.COM 
9319781SMoriah.Waterland@Sun.COM 	/* handle out of memory error */
9329781SMoriah.Waterland@Sun.COM 
9339781SMoriah.Waterland@Sun.COM 	if (thisZonePackages == (char **)NULL) {
9349781SMoriah.Waterland@Sun.COM 		progerr(ERR_MEMORY, errno);
9359781SMoriah.Waterland@Sun.COM 		quit(99);
9369781SMoriah.Waterland@Sun.COM 	}
9379781SMoriah.Waterland@Sun.COM 
9389781SMoriah.Waterland@Sun.COM 	/* add this entry to the end of the list */
9399781SMoriah.Waterland@Sun.COM 
9409781SMoriah.Waterland@Sun.COM 	thisZonePackages[numThisZonePackages] = strdup(a_pkgInst);
9419781SMoriah.Waterland@Sun.COM 	if (thisZonePackages[numThisZonePackages] == (char *)NULL) {
9429781SMoriah.Waterland@Sun.COM 		progerr(ERR_MEMORY, errno);
9439781SMoriah.Waterland@Sun.COM 		quit(99);
9449781SMoriah.Waterland@Sun.COM 	}
9459781SMoriah.Waterland@Sun.COM 
9469781SMoriah.Waterland@Sun.COM 	numThisZonePackages++;
9479781SMoriah.Waterland@Sun.COM 
9489781SMoriah.Waterland@Sun.COM 	/* make sure end of the list is properly terminated */
9499781SMoriah.Waterland@Sun.COM 
9509781SMoriah.Waterland@Sun.COM 	thisZonePackages[numThisZonePackages] = (char *)NULL;
9519781SMoriah.Waterland@Sun.COM 
9529781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
9539781SMoriah.Waterland@Sun.COM 
9549781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_ADD_TZP, numThisZonePackages,
9559781SMoriah.Waterland@Sun.COM 			thisZonePackages[numThisZonePackages-1]);
9569781SMoriah.Waterland@Sun.COM }
9579781SMoriah.Waterland@Sun.COM 
9589781SMoriah.Waterland@Sun.COM /*
9599781SMoriah.Waterland@Sun.COM  * Name:	pkgPackageIsThisZone
9609781SMoriah.Waterland@Sun.COM  * Description:	Determine if the specified package is marked to be installed
9619781SMoriah.Waterland@Sun.COM  *		in this zone only
9629781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgInst - pointer to string representing package name to check
9639781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
9649781SMoriah.Waterland@Sun.COM  *			B_TRUE - the package IS "this zone only"
9659781SMoriah.Waterland@Sun.COM  *			B_FALSE - the paackage is NOT "this zone only"
9669781SMoriah.Waterland@Sun.COM  */
9679781SMoriah.Waterland@Sun.COM 
9689781SMoriah.Waterland@Sun.COM boolean_t
pkgPackageIsThisZone(char * a_pkgInst)9699781SMoriah.Waterland@Sun.COM pkgPackageIsThisZone(char *a_pkgInst)
9709781SMoriah.Waterland@Sun.COM {
9719781SMoriah.Waterland@Sun.COM 	int		n;
9729781SMoriah.Waterland@Sun.COM 
9739781SMoriah.Waterland@Sun.COM 	/* entry assertions */
9749781SMoriah.Waterland@Sun.COM 
9759781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
9769781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
9779781SMoriah.Waterland@Sun.COM 
9789781SMoriah.Waterland@Sun.COM 	/*
9799781SMoriah.Waterland@Sun.COM 	 * see if this package is in the "this zone only" list
9809781SMoriah.Waterland@Sun.COM 	 */
9819781SMoriah.Waterland@Sun.COM 
9829781SMoriah.Waterland@Sun.COM 	for (n = 0; n < numThisZonePackages; n++) {
9839781SMoriah.Waterland@Sun.COM 		if (strcmp(a_pkgInst, thisZonePackages[n]) == 0) {
9849781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGOPS_IS_THISZONE, a_pkgInst);
9859781SMoriah.Waterland@Sun.COM 			return (B_TRUE);
9869781SMoriah.Waterland@Sun.COM 		}
9879781SMoriah.Waterland@Sun.COM 	}
9889781SMoriah.Waterland@Sun.COM 
9899781SMoriah.Waterland@Sun.COM 	/* path is not in "this zone only" list */
9909781SMoriah.Waterland@Sun.COM 
9919781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_IS_NOT_THISZONE, a_pkgInst);
9929781SMoriah.Waterland@Sun.COM 
9939781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
9949781SMoriah.Waterland@Sun.COM }
9959781SMoriah.Waterland@Sun.COM 
9969781SMoriah.Waterland@Sun.COM /*
9979781SMoriah.Waterland@Sun.COM  * Name:	pkgLocateHighestInst
9989781SMoriah.Waterland@Sun.COM  * Description:	Locate the highest installed instance of a package
9999781SMoriah.Waterland@Sun.COM  * Arguments:	r_path - [RO, *RW] - (char *)
10009781SMoriah.Waterland@Sun.COM  *			Pointer to buffer where the full path to the top level
10019781SMoriah.Waterland@Sun.COM  *			directory containing the latest instance of the
10029781SMoriah.Waterland@Sun.COM  *			specified package is located is placed.
10039781SMoriah.Waterland@Sun.COM  *		r_pathLen - [RO, *RO] - (int)
10049781SMoriah.Waterland@Sun.COM  *			Integer representing the size of r_path in bytes.
10059781SMoriah.Waterland@Sun.COM  *		r_pkgInst - [RO, *RW] - (char *)
10069781SMoriah.Waterland@Sun.COM  *			Pointer to buffer where the package instance name of the
10079781SMoriah.Waterland@Sun.COM  *			latest instance of the specified package is placed.
10089781SMoriah.Waterland@Sun.COM  *		r_pkgInstLen - [RO, *RO] - (int)
10099781SMoriah.Waterland@Sun.COM  *			Integer representing the size of r_pkgInst in bytes.
10109781SMoriah.Waterland@Sun.COM  *		a_rootPath - [RO, *RO] - (char *)
10119781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the root path to look
10129781SMoriah.Waterland@Sun.COM  *			for the latest instance of the specified package.
10139781SMoriah.Waterland@Sun.COM  *		a_pkgInst - [RO, *RO] - (char *)
10149781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the name of the package
10159781SMoriah.Waterland@Sun.COM  *			to locate the latest installed instance of.
10169781SMoriah.Waterland@Sun.COM  */
10179781SMoriah.Waterland@Sun.COM 
10189781SMoriah.Waterland@Sun.COM void
pkgLocateHighestInst(char * r_path,int r_pathLen,char * r_pkgInst,int r_pkgInstLen,char * a_rootPath,char * a_pkgInst)10199781SMoriah.Waterland@Sun.COM pkgLocateHighestInst(char *r_path, int r_pathLen, char *r_pkgInst,
10209781SMoriah.Waterland@Sun.COM 	int r_pkgInstLen, char *a_rootPath, char *a_pkgInst)
10219781SMoriah.Waterland@Sun.COM {
10229781SMoriah.Waterland@Sun.COM 	char		pkgInstPath[PATH_MAX] = {'\0'};
10239781SMoriah.Waterland@Sun.COM 	char		pkgWild[PKGSIZ+1] = {'\0'};
10249781SMoriah.Waterland@Sun.COM 	char		pkgName[PKGSIZ+1] = {'\0'};
10259781SMoriah.Waterland@Sun.COM 	int		npkgs;
10269781SMoriah.Waterland@Sun.COM 	struct pkginfo	*pinf = (struct pkginfo *)NULL;
10279781SMoriah.Waterland@Sun.COM 
10289781SMoriah.Waterland@Sun.COM 	/* entry assertions */
10299781SMoriah.Waterland@Sun.COM 
10309781SMoriah.Waterland@Sun.COM 	assert(r_path != (char *)NULL);
10319781SMoriah.Waterland@Sun.COM 	assert(r_pathLen > 0);
10329781SMoriah.Waterland@Sun.COM 	assert(r_pkgInst != (char *)NULL);
10339781SMoriah.Waterland@Sun.COM 	assert(r_pkgInstLen > 0);
10349781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
10359781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
10369781SMoriah.Waterland@Sun.COM 
10379781SMoriah.Waterland@Sun.COM 	/* normalize root path */
10389781SMoriah.Waterland@Sun.COM 
10399781SMoriah.Waterland@Sun.COM 	if ((a_rootPath == (char *)NULL) || (strcmp(a_rootPath, "/") == 0)) {
10409781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
10419781SMoriah.Waterland@Sun.COM 	}
10429781SMoriah.Waterland@Sun.COM 
10439781SMoriah.Waterland@Sun.COM 	/* construct path to package repository directory (eg. /var/sadm/pkg) */
10449781SMoriah.Waterland@Sun.COM 
10459781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgInstPath, sizeof (pkgInstPath), "%s%s", a_rootPath,
10469781SMoriah.Waterland@Sun.COM 		PKGLOC);
10479781SMoriah.Waterland@Sun.COM 
10489781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
10499781SMoriah.Waterland@Sun.COM 
10509781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_LOCHIGH_ENTRY);
10519781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_LOCHIGH_ARGS, pkgInstPath, a_pkgInst);
10529781SMoriah.Waterland@Sun.COM 
10539781SMoriah.Waterland@Sun.COM 	/* reset returned path/package instance so both ares empty */
10549781SMoriah.Waterland@Sun.COM 
10559781SMoriah.Waterland@Sun.COM 	*r_path = '\0';
10569781SMoriah.Waterland@Sun.COM 	*r_pkgInst = '\0';
10579781SMoriah.Waterland@Sun.COM 
10589781SMoriah.Waterland@Sun.COM 	/* remove any architecture extension */
10599781SMoriah.Waterland@Sun.COM 
10609781SMoriah.Waterland@Sun.COM 	pkgstrGetToken_r((char *)NULL, a_pkgInst, 0, ".",
10619781SMoriah.Waterland@Sun.COM 		pkgName, sizeof (pkgName));
10629781SMoriah.Waterland@Sun.COM 
10639781SMoriah.Waterland@Sun.COM 	/* make sure that the package name is valid and can be wild carded */
10649781SMoriah.Waterland@Sun.COM 
10659781SMoriah.Waterland@Sun.COM 	if (pkgnmchk(pkgName, NULL, 0) || strchr(pkgName, '.')) {
10669781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGOPS_LOCHIGH_BAD_PKGNAME, pkgName);
10679781SMoriah.Waterland@Sun.COM 		quit(99);
10689781SMoriah.Waterland@Sun.COM 	}
10699781SMoriah.Waterland@Sun.COM 
10709781SMoriah.Waterland@Sun.COM 	/* create wild card specification for this package instance */
10719781SMoriah.Waterland@Sun.COM 
10729781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgWild, sizeof (pkgWild), "%s.*", pkgName);
10739781SMoriah.Waterland@Sun.COM 
10749781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_LOCHIGH_WILDCARD, pkgName, pkgWild);
10759781SMoriah.Waterland@Sun.COM 
10769781SMoriah.Waterland@Sun.COM 	/*
10779781SMoriah.Waterland@Sun.COM 	 * inspect the system to determine if any instances of the
10789781SMoriah.Waterland@Sun.COM 	 * package being installed already exist on the system
10799781SMoriah.Waterland@Sun.COM 	 */
10809781SMoriah.Waterland@Sun.COM 
10819781SMoriah.Waterland@Sun.COM 	for (npkgs = 0; ; npkgs++) {
10829781SMoriah.Waterland@Sun.COM 		char	*savePkgdir;
10839781SMoriah.Waterland@Sun.COM 		int	r;
10849781SMoriah.Waterland@Sun.COM 
10859781SMoriah.Waterland@Sun.COM 		/* allocate new pinfo structure for use in the pkginfo call */
10869781SMoriah.Waterland@Sun.COM 
10879781SMoriah.Waterland@Sun.COM 		pinf = _pkginfoFactory();
10889781SMoriah.Waterland@Sun.COM 
10899781SMoriah.Waterland@Sun.COM 		/*
10909781SMoriah.Waterland@Sun.COM 		 * lookup the specified package; the first call will cause the
10919781SMoriah.Waterland@Sun.COM 		 * pkgdir directory to be opened - it will be closed when the
10929781SMoriah.Waterland@Sun.COM 		 * end of directory is read and pkginfo() returns != 0. You must
10939781SMoriah.Waterland@Sun.COM 		 * cycle through all instances until pkginfo() returns != 0.
10949781SMoriah.Waterland@Sun.COM 		 * NOTE: pkginfo() requires the global variable 'pkgdir' be set
10959781SMoriah.Waterland@Sun.COM 		 * to the package installed directory (<root>/var/sadm/pkg).
10969781SMoriah.Waterland@Sun.COM 		 */
10979781SMoriah.Waterland@Sun.COM 
10989781SMoriah.Waterland@Sun.COM 		savePkgdir = pkgdir;
10999781SMoriah.Waterland@Sun.COM 		pkgdir = pkgInstPath;
11009781SMoriah.Waterland@Sun.COM 
11019781SMoriah.Waterland@Sun.COM 		r = pkginfo(pinf, pkgWild, NULL, NULL);
11029781SMoriah.Waterland@Sun.COM 
11039781SMoriah.Waterland@Sun.COM 		pkgdir = savePkgdir;
11049781SMoriah.Waterland@Sun.COM 
11059781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, pkgName, r);
11069781SMoriah.Waterland@Sun.COM 
11079781SMoriah.Waterland@Sun.COM 		/* break out of loop of no package found */
11089781SMoriah.Waterland@Sun.COM 
11099781SMoriah.Waterland@Sun.COM 		if (r != 0) {
11109781SMoriah.Waterland@Sun.COM 			pkginfoFree(&pinf);
11119781SMoriah.Waterland@Sun.COM 			break;
11129781SMoriah.Waterland@Sun.COM 		}
11139781SMoriah.Waterland@Sun.COM 
11149781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGOPS_LOCHIGH_INSTANCE, npkgs,
11159781SMoriah.Waterland@Sun.COM 			pinf->pkginst ? pinf->pkginst : "",
11169781SMoriah.Waterland@Sun.COM 			pinf->name ? pinf->name : "",
11179781SMoriah.Waterland@Sun.COM 			pinf->arch ? pinf->arch : "",
11189781SMoriah.Waterland@Sun.COM 			pinf->version ? pinf->version : "",
11199781SMoriah.Waterland@Sun.COM 			pinf->vendor ? pinf->vendor : "",
11209781SMoriah.Waterland@Sun.COM 			pinf->basedir ? pinf->basedir : "",
11219781SMoriah.Waterland@Sun.COM 			pinf->catg ? pinf->catg : "",
11229781SMoriah.Waterland@Sun.COM 			pinf->status);
11239781SMoriah.Waterland@Sun.COM 
11249781SMoriah.Waterland@Sun.COM 		/* save path/instance name for this instance found */
11259781SMoriah.Waterland@Sun.COM 
11269781SMoriah.Waterland@Sun.COM 		(void) strlcpy(r_pkgInst, pinf->pkginst, r_pkgInstLen);
11279781SMoriah.Waterland@Sun.COM 		pkgstrPrintf_r(r_path, r_pathLen, "%s%s/%s", a_rootPath,
11289781SMoriah.Waterland@Sun.COM 			PKGLOC, pinf->pkginst);
11299781SMoriah.Waterland@Sun.COM 
11309781SMoriah.Waterland@Sun.COM 		pkginfoFree(&pinf);
11319781SMoriah.Waterland@Sun.COM 	}
11329781SMoriah.Waterland@Sun.COM 
11339781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGOPS_LOCHIGH_RETURN, npkgs, r_pkgInst, r_path);
11349781SMoriah.Waterland@Sun.COM }
11359781SMoriah.Waterland@Sun.COM 
11369781SMoriah.Waterland@Sun.COM /*
11379781SMoriah.Waterland@Sun.COM  * Name:	pkgTestInstalled
11389781SMoriah.Waterland@Sun.COM  * Description:	determine if package is installed at specified root path
11399781SMoriah.Waterland@Sun.COM  * Arguments:	a_packageName - name of package to test
11409781SMoriah.Waterland@Sun.COM  * 		a_rootPath - root path of alternative root to test
11419781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - package is installed
11429781SMoriah.Waterland@Sun.COM  *		B_FALSE - package is not installed
11439781SMoriah.Waterland@Sun.COM  */
11449781SMoriah.Waterland@Sun.COM 
11459781SMoriah.Waterland@Sun.COM boolean_t
pkgTestInstalled(char * a_packageName,char * a_rootPath)11469781SMoriah.Waterland@Sun.COM pkgTestInstalled(char *a_packageName, char *a_rootPath)
11479781SMoriah.Waterland@Sun.COM {
11489781SMoriah.Waterland@Sun.COM 	char	cmd[MAXPATHLEN+1];
11499781SMoriah.Waterland@Sun.COM 	int	rc;
11509781SMoriah.Waterland@Sun.COM 
11519781SMoriah.Waterland@Sun.COM 	/* entry assertions */
11529781SMoriah.Waterland@Sun.COM 
11539781SMoriah.Waterland@Sun.COM 	assert(a_packageName != (char *)NULL);
11549781SMoriah.Waterland@Sun.COM 	assert(*a_packageName != '\0');
11559781SMoriah.Waterland@Sun.COM 	assert(a_rootPath != (char *)NULL);
11569781SMoriah.Waterland@Sun.COM 	assert(a_rootPath != '\0');
11579781SMoriah.Waterland@Sun.COM 
11589781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
11599781SMoriah.Waterland@Sun.COM 
11609781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKG_TEST_EXISTENCE, a_packageName, a_rootPath);
11619781SMoriah.Waterland@Sun.COM 
11629781SMoriah.Waterland@Sun.COM 	/*
11639781SMoriah.Waterland@Sun.COM 	 * create pkginfo command to execute:
11649781SMoriah.Waterland@Sun.COM 	 * /usr/bin/pkginfo -q <packageName>
11659781SMoriah.Waterland@Sun.COM 	 */
11669781SMoriah.Waterland@Sun.COM 	(void) snprintf(cmd, sizeof (cmd),
11679781SMoriah.Waterland@Sun.COM 		"%s -q %s", PKGINFO_CMD, a_packageName);
11689781SMoriah.Waterland@Sun.COM 
11699781SMoriah.Waterland@Sun.COM 	/* execute command */
11709781SMoriah.Waterland@Sun.COM 
11719781SMoriah.Waterland@Sun.COM 	rc = system(cmd);
11729781SMoriah.Waterland@Sun.COM 
11739781SMoriah.Waterland@Sun.COM 	/* return success if pkginfo returns "0" */
11749781SMoriah.Waterland@Sun.COM 
11759781SMoriah.Waterland@Sun.COM 	if (rc == 0) {
11769781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKG_INSTALLED, a_packageName, a_rootPath);
11779781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
11789781SMoriah.Waterland@Sun.COM 	}
11799781SMoriah.Waterland@Sun.COM 
11809781SMoriah.Waterland@Sun.COM 	/* package not installed */
11819781SMoriah.Waterland@Sun.COM 
11829781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKG_NOT_INSTALLED, a_packageName, a_rootPath);
11839781SMoriah.Waterland@Sun.COM 
11849781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
11859781SMoriah.Waterland@Sun.COM }
11869781SMoriah.Waterland@Sun.COM 
11879781SMoriah.Waterland@Sun.COM /*
11889781SMoriah.Waterland@Sun.COM  * *****************************************************************************
11899781SMoriah.Waterland@Sun.COM  * static internal (private) functions
11909781SMoriah.Waterland@Sun.COM  * *****************************************************************************
11919781SMoriah.Waterland@Sun.COM  */
11929781SMoriah.Waterland@Sun.COM 
11939781SMoriah.Waterland@Sun.COM static void
_pkginfoInit(struct pkginfo * a_info)11949781SMoriah.Waterland@Sun.COM _pkginfoInit(struct pkginfo *a_info)
11959781SMoriah.Waterland@Sun.COM {
11969781SMoriah.Waterland@Sun.COM 	/* entry assertions */
11979781SMoriah.Waterland@Sun.COM 
11989781SMoriah.Waterland@Sun.COM 	assert(a_info != (struct pkginfo *)NULL);
11999781SMoriah.Waterland@Sun.COM 
12009781SMoriah.Waterland@Sun.COM 	/* free previously allocated space */
12019781SMoriah.Waterland@Sun.COM 
12029781SMoriah.Waterland@Sun.COM 	if (a_info->pkginst) {
12039781SMoriah.Waterland@Sun.COM 		free(a_info->pkginst);
12049781SMoriah.Waterland@Sun.COM 		if (a_info->arch)
12059781SMoriah.Waterland@Sun.COM 			free(a_info->arch);
12069781SMoriah.Waterland@Sun.COM 		if (a_info->version)
12079781SMoriah.Waterland@Sun.COM 			free(a_info->version);
12089781SMoriah.Waterland@Sun.COM 		if (a_info->basedir)
12099781SMoriah.Waterland@Sun.COM 			free(a_info->basedir);
12109781SMoriah.Waterland@Sun.COM 		if (a_info->name)
12119781SMoriah.Waterland@Sun.COM 			free(a_info->name);
12129781SMoriah.Waterland@Sun.COM 		if (a_info->vendor)
12139781SMoriah.Waterland@Sun.COM 			free(a_info->vendor);
12149781SMoriah.Waterland@Sun.COM 		if (a_info->catg)
12159781SMoriah.Waterland@Sun.COM 			free(a_info->catg);
12169781SMoriah.Waterland@Sun.COM 	}
12179781SMoriah.Waterland@Sun.COM 
12189781SMoriah.Waterland@Sun.COM 	a_info->pkginst = NULL;
12199781SMoriah.Waterland@Sun.COM 	a_info->arch = a_info->version = NULL;
12209781SMoriah.Waterland@Sun.COM 	a_info->basedir = a_info->name = NULL;
12219781SMoriah.Waterland@Sun.COM 	a_info->vendor = a_info->catg = NULL;
12229781SMoriah.Waterland@Sun.COM 	a_info->status = PI_UNKNOWN;
12239781SMoriah.Waterland@Sun.COM }
12249781SMoriah.Waterland@Sun.COM 
12259781SMoriah.Waterland@Sun.COM static struct pkginfo *
_pkginfoFactory(void)12269781SMoriah.Waterland@Sun.COM _pkginfoFactory(void)
12279781SMoriah.Waterland@Sun.COM {
12289781SMoriah.Waterland@Sun.COM 	struct pkginfo *pinf;
12299781SMoriah.Waterland@Sun.COM 
12309781SMoriah.Waterland@Sun.COM 	pinf = (struct pkginfo *)calloc(1, sizeof (struct pkginfo));
12319781SMoriah.Waterland@Sun.COM 	if (pinf == (struct pkginfo *)NULL) {
12329781SMoriah.Waterland@Sun.COM 		progerr(ERR_MEM);
12339781SMoriah.Waterland@Sun.COM 		exit(1);
12349781SMoriah.Waterland@Sun.COM 	}
12359781SMoriah.Waterland@Sun.COM 
12369781SMoriah.Waterland@Sun.COM 	_pkginfoInit(pinf);
12379781SMoriah.Waterland@Sun.COM 	return (pinf);
12389781SMoriah.Waterland@Sun.COM }
1239