xref: /titanic_50/usr/src/cmd/svr4pkg/libinst/pkgops.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland #include <stdio.h>
29*5c51f124SMoriah Waterland #include <limits.h>
30*5c51f124SMoriah Waterland #include <stdlib.h>
31*5c51f124SMoriah Waterland #include <unistd.h>
32*5c51f124SMoriah Waterland #include <string.h>
33*5c51f124SMoriah Waterland #include <fcntl.h>
34*5c51f124SMoriah Waterland #include <sys/types.h>
35*5c51f124SMoriah Waterland #include <sys/stat.h>
36*5c51f124SMoriah Waterland #include <signal.h>
37*5c51f124SMoriah Waterland #include <errno.h>
38*5c51f124SMoriah Waterland #include <assert.h>
39*5c51f124SMoriah Waterland #include <pkgdev.h>
40*5c51f124SMoriah Waterland #include <pkginfo.h>
41*5c51f124SMoriah Waterland #include <pkglocs.h>
42*5c51f124SMoriah Waterland #include <locale.h>
43*5c51f124SMoriah Waterland #include <libintl.h>
44*5c51f124SMoriah Waterland #include <instzones_api.h>
45*5c51f124SMoriah Waterland #include <pkglib.h>
46*5c51f124SMoriah Waterland #include <install.h>
47*5c51f124SMoriah Waterland #include <libinst.h>
48*5c51f124SMoriah Waterland #include <libadm.h>
49*5c51f124SMoriah Waterland #include <messages.h>
50*5c51f124SMoriah Waterland 
51*5c51f124SMoriah Waterland /* commands to execute */
52*5c51f124SMoriah Waterland 
53*5c51f124SMoriah Waterland #define	PKGINFO_CMD	"/usr/bin/pkginfo"
54*5c51f124SMoriah Waterland 
55*5c51f124SMoriah Waterland #define	GLOBALZONE_ONLY_PACKAGE_FILE_PATH	\
56*5c51f124SMoriah Waterland 					"/var/sadm/install/gz-only-packages"
57*5c51f124SMoriah Waterland 
58*5c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
59*5c51f124SMoriah Waterland #define	TEXT_DOMAIN	"SYS_TEST"
60*5c51f124SMoriah Waterland #endif
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland /*
63*5c51f124SMoriah Waterland  * forward declarations
64*5c51f124SMoriah Waterland  */
65*5c51f124SMoriah Waterland 
66*5c51f124SMoriah Waterland static void		_pkginfoInit(struct pkginfo *a_info);
67*5c51f124SMoriah Waterland static struct pkginfo	*_pkginfoFactory(void);
68*5c51f124SMoriah Waterland static char		**thisZonePackages;
69*5c51f124SMoriah Waterland static int		numThisZonePackages;
70*5c51f124SMoriah Waterland 
71*5c51f124SMoriah Waterland /*
72*5c51f124SMoriah Waterland  * *****************************************************************************
73*5c51f124SMoriah Waterland  * global external (public) functions
74*5c51f124SMoriah Waterland  * *****************************************************************************
75*5c51f124SMoriah Waterland  */
76*5c51f124SMoriah Waterland 
77*5c51f124SMoriah Waterland /*
78*5c51f124SMoriah Waterland  * Name:	pkginfoFree
79*5c51f124SMoriah Waterland  * Description:	free pkginfo structure returned from various functions
80*5c51f124SMoriah Waterland  * Arguments:	r_info - pointer to pointer to pkginfo structure to free
81*5c51f124SMoriah Waterland  * Returns:	void
82*5c51f124SMoriah Waterland  */
83*5c51f124SMoriah Waterland 
84*5c51f124SMoriah Waterland void
85*5c51f124SMoriah Waterland pkginfoFree(struct pkginfo **r_info)
86*5c51f124SMoriah Waterland {
87*5c51f124SMoriah Waterland 	struct pkginfo	*pinfo;
88*5c51f124SMoriah Waterland 
89*5c51f124SMoriah Waterland 	/* entry assertions */
90*5c51f124SMoriah Waterland 
91*5c51f124SMoriah Waterland 	assert(r_info != (struct pkginfo **)NULL);
92*5c51f124SMoriah Waterland 
93*5c51f124SMoriah Waterland 	/* localize reference to info structure to free */
94*5c51f124SMoriah Waterland 
95*5c51f124SMoriah Waterland 	pinfo = *r_info;
96*5c51f124SMoriah Waterland 
97*5c51f124SMoriah Waterland 	/* reset callers handle to info structure */
98*5c51f124SMoriah Waterland 
99*5c51f124SMoriah Waterland 	*r_info = (struct pkginfo *)NULL;
100*5c51f124SMoriah Waterland 
101*5c51f124SMoriah Waterland 	assert(pinfo != (struct pkginfo *)NULL);
102*5c51f124SMoriah Waterland 
103*5c51f124SMoriah Waterland 	/* free up contents of the structure */
104*5c51f124SMoriah Waterland 
105*5c51f124SMoriah Waterland 	_pkginfoInit(pinfo);
106*5c51f124SMoriah Waterland 
107*5c51f124SMoriah Waterland 	/* free up structure itself */
108*5c51f124SMoriah Waterland 
109*5c51f124SMoriah Waterland 	(void) free(pinfo);
110*5c51f124SMoriah Waterland }
111*5c51f124SMoriah Waterland 
112*5c51f124SMoriah Waterland /*
113*5c51f124SMoriah Waterland  * Name:	pkginfoIsPkgInstalled
114*5c51f124SMoriah Waterland  * Description:	determine if specified package is installed, return pkginfo
115*5c51f124SMoriah Waterland  *		structure describing package if package is installed
116*5c51f124SMoriah Waterland  * Arguments:	r_pinfo - pointer to pointer to pkginfo structure
117*5c51f124SMoriah Waterland  *			If this pointer is NOT null:
118*5c51f124SMoriah Waterland  *			-On success, this handle is filled in with a pointer
119*5c51f124SMoriah Waterland  *			--to a newly allocated pkginfo structure describing
120*5c51f124SMoriah Waterland  *			--the package discovered
121*5c51f124SMoriah Waterland  *			-On failure, this handle is filled with NULL
122*5c51f124SMoriah Waterland  *			If this pointer is NULL:
123*5c51f124SMoriah Waterland  *			-no pkginfo structure is returned on success.
124*5c51f124SMoriah Waterland  *		a_pkgInst - package instance (name) to lookup
125*5c51f124SMoriah Waterland  * Returns:	boolean_t
126*5c51f124SMoriah Waterland  *			B_TRUE - package installed, pkginfo returned
127*5c51f124SMoriah Waterland  *			B_FALSE - package not installed, no pkginfo returned
128*5c51f124SMoriah Waterland  * NOTE:	This function returns the first instance of package that
129*5c51f124SMoriah Waterland  *		is installed - see pkginfo() function for details
130*5c51f124SMoriah Waterland  * NOTE:    	Any pkginfo structure returned is placed in new storage for the
131*5c51f124SMoriah Waterland  *		calling function. The caller must use 'pkginfoFree' to dispose
132*5c51f124SMoriah Waterland  *		of the storage once the pkginfo structure is no longer needed.
133*5c51f124SMoriah Waterland  */
134*5c51f124SMoriah Waterland 
135*5c51f124SMoriah Waterland boolean_t
136*5c51f124SMoriah Waterland pkginfoIsPkgInstalled(struct pkginfo **r_pinfo, char *a_pkgInst)
137*5c51f124SMoriah Waterland {
138*5c51f124SMoriah Waterland 	int		r;
139*5c51f124SMoriah Waterland 	struct pkginfo	*pinf;
140*5c51f124SMoriah Waterland 
141*5c51f124SMoriah Waterland 	/* entry assertions */
142*5c51f124SMoriah Waterland 
143*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
144*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
145*5c51f124SMoriah Waterland 
146*5c51f124SMoriah Waterland 	/* reset returned pkginfo structure handle */
147*5c51f124SMoriah Waterland 
148*5c51f124SMoriah Waterland 	if (r_pinfo != (struct pkginfo **)NULL) {
149*5c51f124SMoriah Waterland 		*r_pinfo = (struct pkginfo *)NULL;
150*5c51f124SMoriah Waterland 	}
151*5c51f124SMoriah Waterland 
152*5c51f124SMoriah Waterland 	/* allocate a new pinfo structure for use in the call to pkginfo */
153*5c51f124SMoriah Waterland 
154*5c51f124SMoriah Waterland 	pinf = _pkginfoFactory();
155*5c51f124SMoriah Waterland 
156*5c51f124SMoriah Waterland 	/* lookup the specified package */
157*5c51f124SMoriah Waterland 
158*5c51f124SMoriah Waterland 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
159*5c51f124SMoriah Waterland 	r = pkginfo(pinf, a_pkgInst, NULL, NULL);
160*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, a_pkgInst, r);
161*5c51f124SMoriah Waterland 
162*5c51f124SMoriah Waterland 	if (r_pinfo != (struct pkginfo **)NULL) {
163*5c51f124SMoriah Waterland 		*r_pinfo = pinf;
164*5c51f124SMoriah Waterland 	} else {
165*5c51f124SMoriah Waterland 		/* free pkginfo structure */
166*5c51f124SMoriah Waterland 		pkginfoFree(&pinf);
167*5c51f124SMoriah Waterland 	}
168*5c51f124SMoriah Waterland 
169*5c51f124SMoriah Waterland 	return (r == 0 ? B_TRUE : B_FALSE);
170*5c51f124SMoriah Waterland }
171*5c51f124SMoriah Waterland 
172*5c51f124SMoriah Waterland /*
173*5c51f124SMoriah Waterland  * Name:	pkgOpenInGzOnlyFile
174*5c51f124SMoriah Waterland  * Description:	Open the global zone only package list file
175*5c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
176*5c51f124SMoriah Waterland  *			where the global zone only package list file is
177*5c51f124SMoriah Waterland  *			located - NULL is the same as "/"
178*5c51f124SMoriah Waterland  * Returns:	FILE *
179*5c51f124SMoriah Waterland  *			== NULL - failure - file not open
180*5c51f124SMoriah Waterland  *			!= NULL - success - file pointer returned
181*5c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
182*5c51f124SMoriah Waterland  */
183*5c51f124SMoriah Waterland 
184*5c51f124SMoriah Waterland FILE *
185*5c51f124SMoriah Waterland pkgOpenInGzOnlyFile(char *a_rootPath)
186*5c51f124SMoriah Waterland {
187*5c51f124SMoriah Waterland 	FILE	*pkgingzonlyFP;
188*5c51f124SMoriah Waterland 	char	pkgingzonlyPath[PATH_MAX];
189*5c51f124SMoriah Waterland 	int	len;
190*5c51f124SMoriah Waterland 
191*5c51f124SMoriah Waterland 	/* normalize root path */
192*5c51f124SMoriah Waterland 
193*5c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
194*5c51f124SMoriah Waterland 		a_rootPath = "";
195*5c51f124SMoriah Waterland 	}
196*5c51f124SMoriah Waterland 
197*5c51f124SMoriah Waterland 	/* generate path to glocal zone only list file */
198*5c51f124SMoriah Waterland 
199*5c51f124SMoriah Waterland 	len = snprintf(pkgingzonlyPath, sizeof (pkgingzonlyPath), "%s/%s",
200*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
201*5c51f124SMoriah Waterland 	if (len > sizeof (pkgingzonlyPath)) {
202*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
203*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
204*5c51f124SMoriah Waterland 		return ((FILE *)NULL);
205*5c51f124SMoriah Waterland 	}
206*5c51f124SMoriah Waterland 
207*5c51f124SMoriah Waterland 	/* open global zone only list file */
208*5c51f124SMoriah Waterland 
209*5c51f124SMoriah Waterland 	pkgingzonlyFP = fopen(pkgingzonlyPath, "r+");
210*5c51f124SMoriah Waterland 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno == ENOENT)) {
211*5c51f124SMoriah Waterland 		pkgingzonlyFP = fopen(pkgingzonlyPath, "w+");
212*5c51f124SMoriah Waterland 	}
213*5c51f124SMoriah Waterland 
214*5c51f124SMoriah Waterland 	if ((pkgingzonlyFP == (FILE *)NULL) && (errno != ENOENT)) {
215*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, pkgingzonlyPath,
216*5c51f124SMoriah Waterland 				strerror(errno));
217*5c51f124SMoriah Waterland 		return ((FILE *)NULL);
218*5c51f124SMoriah Waterland 	}
219*5c51f124SMoriah Waterland 
220*5c51f124SMoriah Waterland 	/* success - return FILE pointer open on global zone only list file */
221*5c51f124SMoriah Waterland 
222*5c51f124SMoriah Waterland 	return (pkgingzonlyFP);
223*5c51f124SMoriah Waterland }
224*5c51f124SMoriah Waterland 
225*5c51f124SMoriah Waterland /*
226*5c51f124SMoriah Waterland  * Name:	pkgIsPkgInGzOnly
227*5c51f124SMoriah Waterland  * Description:	determine if package is recorded as "in global zone only"
228*5c51f124SMoriah Waterland  *		by opening the appropriate files and searching for the
229*5c51f124SMoriah Waterland  *		specified package
230*5c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
231*5c51f124SMoriah Waterland  *			where the global zone only package list file is
232*5c51f124SMoriah Waterland  *			located - NULL is the same as "/"
233*5c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
234*5c51f124SMoriah Waterland  *			(name) of the package to lookup
235*5c51f124SMoriah Waterland  * Returns:	boolean_t
236*5c51f124SMoriah Waterland  *			B_TRUE - package is recorded as "in global zone only"
237*5c51f124SMoriah Waterland  *			B_FALSE - package is NOT recorded as "in gz only"
238*5c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
239*5c51f124SMoriah Waterland  */
240*5c51f124SMoriah Waterland 
241*5c51f124SMoriah Waterland boolean_t
242*5c51f124SMoriah Waterland pkgIsPkgInGzOnly(char *a_rootPath, char *a_pkgInst)
243*5c51f124SMoriah Waterland {
244*5c51f124SMoriah Waterland 	FILE		*fp;
245*5c51f124SMoriah Waterland 	boolean_t	in_gz_only;
246*5c51f124SMoriah Waterland 
247*5c51f124SMoriah Waterland 	/* normalize root path */
248*5c51f124SMoriah Waterland 
249*5c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
250*5c51f124SMoriah Waterland 		a_rootPath = "";
251*5c51f124SMoriah Waterland 	}
252*5c51f124SMoriah Waterland 
253*5c51f124SMoriah Waterland 	/* open the global zone only package list file */
254*5c51f124SMoriah Waterland 
255*5c51f124SMoriah Waterland 	fp = pkgOpenInGzOnlyFile(a_rootPath);
256*5c51f124SMoriah Waterland 	if (fp == (FILE *)NULL) {
257*5c51f124SMoriah Waterland 		echoDebug(ERR_PKGOPS_CANNOT_OPEN_GZONLY,
258*5c51f124SMoriah Waterland 				a_rootPath ? a_rootPath : "/");
259*5c51f124SMoriah Waterland 		return (B_FALSE);
260*5c51f124SMoriah Waterland 	}
261*5c51f124SMoriah Waterland 
262*5c51f124SMoriah Waterland 	/* is the package recorded as "in global zone only" ? */
263*5c51f124SMoriah Waterland 
264*5c51f124SMoriah Waterland 	in_gz_only = pkgIsPkgInGzOnlyFP(fp, a_pkgInst);
265*5c51f124SMoriah Waterland 
266*5c51f124SMoriah Waterland 	/* close the global zone only package list file */
267*5c51f124SMoriah Waterland 
268*5c51f124SMoriah Waterland 	(void) fclose(fp);
269*5c51f124SMoriah Waterland 
270*5c51f124SMoriah Waterland 	/* return results */
271*5c51f124SMoriah Waterland 
272*5c51f124SMoriah Waterland 	return (in_gz_only);
273*5c51f124SMoriah Waterland }
274*5c51f124SMoriah Waterland 
275*5c51f124SMoriah Waterland /*
276*5c51f124SMoriah Waterland  * Name:	pkgIsPkgInGzOnly
277*5c51f124SMoriah Waterland  * Description:	determine if package is recorded as "in global zone only"
278*5c51f124SMoriah Waterland  *		by searching the specified open FILE for the specified package
279*5c51f124SMoriah Waterland  * Arguments:	a_fp - pointer to FILE handle open on file to search
280*5c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
281*5c51f124SMoriah Waterland  *			(name) of the package to lookup
282*5c51f124SMoriah Waterland  * Returns:	boolean_t
283*5c51f124SMoriah Waterland  *			B_TRUE - package is recorded as "in global zone only"
284*5c51f124SMoriah Waterland  *			B_FALSE - package is NOT recorded as "in gz only"
285*5c51f124SMoriah Waterland  */
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland boolean_t
288*5c51f124SMoriah Waterland pkgIsPkgInGzOnlyFP(FILE *a_fp, char *a_pkgInst)
289*5c51f124SMoriah Waterland {
290*5c51f124SMoriah Waterland 	char	line[PATH_MAX+1];
291*5c51f124SMoriah Waterland 
292*5c51f124SMoriah Waterland 	/* entry assertions */
293*5c51f124SMoriah Waterland 
294*5c51f124SMoriah Waterland 	assert(a_fp != (FILE *)NULL);
295*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
296*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
297*5c51f124SMoriah Waterland 
298*5c51f124SMoriah Waterland 	/* rewind the file to the beginning */
299*5c51f124SMoriah Waterland 
300*5c51f124SMoriah Waterland 	rewind(a_fp);
301*5c51f124SMoriah Waterland 
302*5c51f124SMoriah Waterland 	/* read the file line by line searching for the specified package */
303*5c51f124SMoriah Waterland 
304*5c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), a_fp) != (char *)NULL) {
305*5c51f124SMoriah Waterland 		int	len;
306*5c51f124SMoriah Waterland 
307*5c51f124SMoriah Waterland 		/* strip off trailing newlines */
308*5c51f124SMoriah Waterland 		len = strlen(line);
309*5c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
310*5c51f124SMoriah Waterland 			line[--len] = '\0';
311*5c51f124SMoriah Waterland 		}
312*5c51f124SMoriah Waterland 
313*5c51f124SMoriah Waterland 		/* ignore blank and comment lines */
314*5c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
315*5c51f124SMoriah Waterland 			continue;
316*5c51f124SMoriah Waterland 		}
317*5c51f124SMoriah Waterland 
318*5c51f124SMoriah Waterland 		/* return true if this is the package we are looking for */
319*5c51f124SMoriah Waterland 		if (strcmp(a_pkgInst, line) == 0) {
320*5c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_PKG_IS_GZONLY, a_pkgInst);
321*5c51f124SMoriah Waterland 			return (B_TRUE);
322*5c51f124SMoriah Waterland 		}
323*5c51f124SMoriah Waterland 	}
324*5c51f124SMoriah Waterland 
325*5c51f124SMoriah Waterland 	/* end of file - package not found */
326*5c51f124SMoriah Waterland 
327*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PKG_NOT_GZONLY, a_pkgInst);
328*5c51f124SMoriah Waterland 
329*5c51f124SMoriah Waterland 	return (B_FALSE);
330*5c51f124SMoriah Waterland }
331*5c51f124SMoriah Waterland 
332*5c51f124SMoriah Waterland /*
333*5c51f124SMoriah Waterland  * Name:	pkgRemovePackageFromGzonlyList
334*5c51f124SMoriah Waterland  * Description:	Remove specified package from the global zone only package list
335*5c51f124SMoriah Waterland  *		file located at a specified root path
336*5c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
337*5c51f124SMoriah Waterland  *			where the global zone only package list file is
338*5c51f124SMoriah Waterland  *			located - NULL is the same as "/"
339*5c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
340*5c51f124SMoriah Waterland  *			(name) of the package to remove
341*5c51f124SMoriah Waterland  * Returns:	boolean_t
342*5c51f124SMoriah Waterland  *			B_TRUE - package is successfully removed
343*5c51f124SMoriah Waterland  *			B_FALSE - failed to remove package from file
344*5c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
345*5c51f124SMoriah Waterland  */
346*5c51f124SMoriah Waterland 
347*5c51f124SMoriah Waterland boolean_t
348*5c51f124SMoriah Waterland pkgRemovePackageFromGzonlyList(char *a_rootPath, char *a_pkgInst)
349*5c51f124SMoriah Waterland {
350*5c51f124SMoriah Waterland 	FILE		*destFP;
351*5c51f124SMoriah Waterland 	FILE		*srcFP;
352*5c51f124SMoriah Waterland 	boolean_t	pkgremoved = B_FALSE;
353*5c51f124SMoriah Waterland 	char		destPath[PATH_MAX];
354*5c51f124SMoriah Waterland 	char		line[PATH_MAX+1];
355*5c51f124SMoriah Waterland 	char		savePath[PATH_MAX];
356*5c51f124SMoriah Waterland 	char		srcPath[PATH_MAX];
357*5c51f124SMoriah Waterland 	char		timeb[BUFSIZ];
358*5c51f124SMoriah Waterland 	int		len;
359*5c51f124SMoriah Waterland 	struct tm	*timep;
360*5c51f124SMoriah Waterland 	time_t		clock;
361*5c51f124SMoriah Waterland 
362*5c51f124SMoriah Waterland 	/* entry assertions */
363*5c51f124SMoriah Waterland 
364*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
365*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
366*5c51f124SMoriah Waterland 
367*5c51f124SMoriah Waterland 	/* normalize root path */
368*5c51f124SMoriah Waterland 
369*5c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
370*5c51f124SMoriah Waterland 		a_rootPath = "";
371*5c51f124SMoriah Waterland 	}
372*5c51f124SMoriah Waterland 
373*5c51f124SMoriah Waterland 	/*
374*5c51f124SMoriah Waterland 	 * calculate paths to various objects
375*5c51f124SMoriah Waterland 	 */
376*5c51f124SMoriah Waterland 
377*5c51f124SMoriah Waterland 	/* path to current "source" ingzonly file */
378*5c51f124SMoriah Waterland 
379*5c51f124SMoriah Waterland 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
380*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
381*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
382*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
383*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
384*5c51f124SMoriah Waterland 		return (B_FALSE);
385*5c51f124SMoriah Waterland 	}
386*5c51f124SMoriah Waterland 
387*5c51f124SMoriah Waterland 	/* path to new "destination" ingzonly file */
388*5c51f124SMoriah Waterland 
389*5c51f124SMoriah Waterland 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
390*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
391*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
392*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
393*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
394*5c51f124SMoriah Waterland 		return (B_FALSE);
395*5c51f124SMoriah Waterland 	}
396*5c51f124SMoriah Waterland 
397*5c51f124SMoriah Waterland 	/* path to temporary "saved" ingzonly file */
398*5c51f124SMoriah Waterland 
399*5c51f124SMoriah Waterland 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
400*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
401*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
402*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
403*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
404*5c51f124SMoriah Waterland 		return (B_FALSE);
405*5c51f124SMoriah Waterland 	}
406*5c51f124SMoriah Waterland 
407*5c51f124SMoriah Waterland 	/* open source file, creating if necessary */
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland 	srcFP = fopen(srcPath, "r+");
410*5c51f124SMoriah Waterland 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
411*5c51f124SMoriah Waterland 		srcFP = fopen(srcPath, "w+");
412*5c51f124SMoriah Waterland 	}
413*5c51f124SMoriah Waterland 
414*5c51f124SMoriah Waterland 	/* error if could not open/create file */
415*5c51f124SMoriah Waterland 
416*5c51f124SMoriah Waterland 	if (srcFP == (FILE *)NULL) {
417*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
418*5c51f124SMoriah Waterland 		return (B_FALSE);
419*5c51f124SMoriah Waterland 	}
420*5c51f124SMoriah Waterland 
421*5c51f124SMoriah Waterland 	/* open/create new destination file */
422*5c51f124SMoriah Waterland 
423*5c51f124SMoriah Waterland 	(void) remove(destPath);
424*5c51f124SMoriah Waterland 	destFP = fopen(destPath, "w");
425*5c51f124SMoriah Waterland 	if (destFP == (FILE *)NULL) {
426*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
427*5c51f124SMoriah Waterland 		if (srcFP != (FILE *)NULL) {
428*5c51f124SMoriah Waterland 			(void) fclose(srcFP);
429*5c51f124SMoriah Waterland 		}
430*5c51f124SMoriah Waterland 		return (B_FALSE);
431*5c51f124SMoriah Waterland 	}
432*5c51f124SMoriah Waterland 
433*5c51f124SMoriah Waterland 	/* add standard comment to beginning of file */
434*5c51f124SMoriah Waterland 
435*5c51f124SMoriah Waterland 	(void) time(&clock);
436*5c51f124SMoriah Waterland 	timep = localtime(&clock);
437*5c51f124SMoriah Waterland 
438*5c51f124SMoriah Waterland 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
439*5c51f124SMoriah Waterland 
440*5c51f124SMoriah Waterland 	/* put standard header at the beginning of the file */
441*5c51f124SMoriah Waterland 
442*5c51f124SMoriah Waterland 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
443*5c51f124SMoriah Waterland 			get_prog_name(), "remove", a_pkgInst, timeb);
444*5c51f124SMoriah Waterland 
445*5c51f124SMoriah Waterland 	/* read source/write destination - removing specified package */
446*5c51f124SMoriah Waterland 
447*5c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
448*5c51f124SMoriah Waterland 		int	len;
449*5c51f124SMoriah Waterland 
450*5c51f124SMoriah Waterland 		/* strip off trailing newlines */
451*5c51f124SMoriah Waterland 		len = strlen(line);
452*5c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
453*5c51f124SMoriah Waterland 			line[--len] = '\0';
454*5c51f124SMoriah Waterland 		}
455*5c51f124SMoriah Waterland 
456*5c51f124SMoriah Waterland 		/* ignore blank and comment lines */
457*5c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
458*5c51f124SMoriah Waterland 			continue;
459*5c51f124SMoriah Waterland 		}
460*5c51f124SMoriah Waterland 
461*5c51f124SMoriah Waterland 		/* add pkg if yet to add and pkg <= line */
462*5c51f124SMoriah Waterland 		if ((pkgremoved == B_FALSE) && (strcmp(a_pkgInst, line) == 0)) {
463*5c51f124SMoriah Waterland 			pkgremoved = B_TRUE;
464*5c51f124SMoriah Waterland 		} else {
465*5c51f124SMoriah Waterland 			(void) fprintf(destFP, "%s\n", line);
466*5c51f124SMoriah Waterland 		}
467*5c51f124SMoriah Waterland 	}
468*5c51f124SMoriah Waterland 
469*5c51f124SMoriah Waterland 	/* close both files */
470*5c51f124SMoriah Waterland 
471*5c51f124SMoriah Waterland 	(void) fclose(srcFP);
472*5c51f124SMoriah Waterland 
473*5c51f124SMoriah Waterland 	(void) fclose(destFP);
474*5c51f124SMoriah Waterland 
475*5c51f124SMoriah Waterland 	/*
476*5c51f124SMoriah Waterland 	 * if package not found there is no need to update the original file
477*5c51f124SMoriah Waterland 	 */
478*5c51f124SMoriah Waterland 
479*5c51f124SMoriah Waterland 	if (pkgremoved == B_FALSE) {
480*5c51f124SMoriah Waterland 		(void) unlink(destPath);
481*5c51f124SMoriah Waterland 		return (B_TRUE);
482*5c51f124SMoriah Waterland 	}
483*5c51f124SMoriah Waterland 
484*5c51f124SMoriah Waterland 	/*
485*5c51f124SMoriah Waterland 	 * Now we want to make a copy of the old gzonly file as a
486*5c51f124SMoriah Waterland 	 * fail-safe.
487*5c51f124SMoriah Waterland 	 */
488*5c51f124SMoriah Waterland 
489*5c51f124SMoriah Waterland 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
490*5c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
491*5c51f124SMoriah Waterland 		(void) remove(destPath);
492*5c51f124SMoriah Waterland 		return (B_FALSE);
493*5c51f124SMoriah Waterland 	}
494*5c51f124SMoriah Waterland 
495*5c51f124SMoriah Waterland 	if (link(srcPath, savePath) != 0) {
496*5c51f124SMoriah Waterland 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
497*5c51f124SMoriah Waterland 		(void) remove(destPath);
498*5c51f124SMoriah Waterland 		return (B_FALSE);
499*5c51f124SMoriah Waterland 	}
500*5c51f124SMoriah Waterland 
501*5c51f124SMoriah Waterland 	if (rename(destPath, srcPath) != 0) {
502*5c51f124SMoriah Waterland 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
503*5c51f124SMoriah Waterland 		if (rename(savePath, srcPath)) {
504*5c51f124SMoriah Waterland 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
505*5c51f124SMoriah Waterland 		}
506*5c51f124SMoriah Waterland 		(void) remove(destPath);
507*5c51f124SMoriah Waterland 		return (B_FALSE);
508*5c51f124SMoriah Waterland 	}
509*5c51f124SMoriah Waterland 
510*5c51f124SMoriah Waterland 	if (remove(savePath) != 0) {
511*5c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
512*5c51f124SMoriah Waterland 	}
513*5c51f124SMoriah Waterland 
514*5c51f124SMoriah Waterland 	/* successfully removed package */
515*5c51f124SMoriah Waterland 
516*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_REMOVED_GZPKG, a_pkgInst);
517*5c51f124SMoriah Waterland 
518*5c51f124SMoriah Waterland 	return (B_TRUE);
519*5c51f124SMoriah Waterland }
520*5c51f124SMoriah Waterland 
521*5c51f124SMoriah Waterland /*
522*5c51f124SMoriah Waterland  * Name:	pkgAddPackageFromGzonlyList
523*5c51f124SMoriah Waterland  * Description:	Add specified package to the global zone only package list
524*5c51f124SMoriah Waterland  *		file located at a specified root path
525*5c51f124SMoriah Waterland  * Arguments:	a_rootPath - pointer to string representing the root path
526*5c51f124SMoriah Waterland  *			where the global zone only package list file is
527*5c51f124SMoriah Waterland  *			located - NULL is the same as "/"
528*5c51f124SMoriah Waterland  *		a_pkgInst - pointer to string representing the package instance
529*5c51f124SMoriah Waterland  *			(name) of the package to add
530*5c51f124SMoriah Waterland  * Returns:	boolean_t
531*5c51f124SMoriah Waterland  *			B_TRUE - package is successfully added
532*5c51f124SMoriah Waterland  *			B_FALSE - failed to add package to the file
533*5c51f124SMoriah Waterland  * NOTE:	This function will create the file if it does not exist.
534*5c51f124SMoriah Waterland  */
535*5c51f124SMoriah Waterland 
536*5c51f124SMoriah Waterland boolean_t
537*5c51f124SMoriah Waterland pkgAddPackageToGzonlyList(char *a_pkgInst, char *a_rootPath)
538*5c51f124SMoriah Waterland {
539*5c51f124SMoriah Waterland 	FILE		*destFP;
540*5c51f124SMoriah Waterland 	FILE		*srcFP;
541*5c51f124SMoriah Waterland 	boolean_t	pkgadded = B_FALSE;
542*5c51f124SMoriah Waterland 	char		destPath[PATH_MAX];
543*5c51f124SMoriah Waterland 	char		line[PATH_MAX+1];
544*5c51f124SMoriah Waterland 	char		savePath[PATH_MAX];
545*5c51f124SMoriah Waterland 	char		srcPath[PATH_MAX];
546*5c51f124SMoriah Waterland 	char		timeb[BUFSIZ];
547*5c51f124SMoriah Waterland 	int		len;
548*5c51f124SMoriah Waterland 	struct tm	*timep;
549*5c51f124SMoriah Waterland 	time_t		clock;
550*5c51f124SMoriah Waterland 
551*5c51f124SMoriah Waterland 	/* entry assertions */
552*5c51f124SMoriah Waterland 
553*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
554*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
555*5c51f124SMoriah Waterland 
556*5c51f124SMoriah Waterland 	/* normalize root path */
557*5c51f124SMoriah Waterland 
558*5c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
559*5c51f124SMoriah Waterland 		a_rootPath = "";
560*5c51f124SMoriah Waterland 	}
561*5c51f124SMoriah Waterland 
562*5c51f124SMoriah Waterland 	/* entry debugging info */
563*5c51f124SMoriah Waterland 
564*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADDGZPKG, a_pkgInst, a_rootPath);
565*5c51f124SMoriah Waterland 
566*5c51f124SMoriah Waterland 	/*
567*5c51f124SMoriah Waterland 	 * calculate paths to various objects
568*5c51f124SMoriah Waterland 	 */
569*5c51f124SMoriah Waterland 
570*5c51f124SMoriah Waterland 	/* path to current "source" ingzonly file */
571*5c51f124SMoriah Waterland 
572*5c51f124SMoriah Waterland 	len = snprintf(srcPath, sizeof (srcPath), "%s/%s",
573*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
574*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
575*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
576*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
577*5c51f124SMoriah Waterland 		return (B_FALSE);
578*5c51f124SMoriah Waterland 	}
579*5c51f124SMoriah Waterland 
580*5c51f124SMoriah Waterland 	/* path to new "destination" ingzonly file */
581*5c51f124SMoriah Waterland 
582*5c51f124SMoriah Waterland 	len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp",
583*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
584*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
585*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
586*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
587*5c51f124SMoriah Waterland 		return (B_FALSE);
588*5c51f124SMoriah Waterland 	}
589*5c51f124SMoriah Waterland 
590*5c51f124SMoriah Waterland 	/* path to temporary "saved" ingzonly file */
591*5c51f124SMoriah Waterland 
592*5c51f124SMoriah Waterland 	len = snprintf(savePath, sizeof (savePath), "%s/%s.save",
593*5c51f124SMoriah Waterland 		a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
594*5c51f124SMoriah Waterland 	if (len > sizeof (srcPath)) {
595*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_rootPath,
596*5c51f124SMoriah Waterland 				GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
597*5c51f124SMoriah Waterland 		return (B_FALSE);
598*5c51f124SMoriah Waterland 	}
599*5c51f124SMoriah Waterland 
600*5c51f124SMoriah Waterland 	/* open source file, creating if necessary */
601*5c51f124SMoriah Waterland 
602*5c51f124SMoriah Waterland 	srcFP = fopen(srcPath, "r+");
603*5c51f124SMoriah Waterland 	if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) {
604*5c51f124SMoriah Waterland 		srcFP = fopen(srcPath, "w+");
605*5c51f124SMoriah Waterland 	}
606*5c51f124SMoriah Waterland 
607*5c51f124SMoriah Waterland 	/* error if could not open/create file */
608*5c51f124SMoriah Waterland 
609*5c51f124SMoriah Waterland 	if (srcFP == (FILE *)NULL) {
610*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno));
611*5c51f124SMoriah Waterland 		return (B_FALSE);
612*5c51f124SMoriah Waterland 	}
613*5c51f124SMoriah Waterland 
614*5c51f124SMoriah Waterland 	/* open/create new destination file */
615*5c51f124SMoriah Waterland 
616*5c51f124SMoriah Waterland 	(void) remove(destPath);
617*5c51f124SMoriah Waterland 	destFP = fopen(destPath, "w");
618*5c51f124SMoriah Waterland 	if (destFP == (FILE *)NULL) {
619*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno));
620*5c51f124SMoriah Waterland 		if (srcFP != (FILE *)NULL) {
621*5c51f124SMoriah Waterland 			(void) fclose(srcFP);
622*5c51f124SMoriah Waterland 		}
623*5c51f124SMoriah Waterland 		return (B_FALSE);
624*5c51f124SMoriah Waterland 	}
625*5c51f124SMoriah Waterland 
626*5c51f124SMoriah Waterland 	/* add standard comment to beginning of file */
627*5c51f124SMoriah Waterland 
628*5c51f124SMoriah Waterland 	(void) time(&clock);
629*5c51f124SMoriah Waterland 	timep = localtime(&clock);
630*5c51f124SMoriah Waterland 
631*5c51f124SMoriah Waterland 	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
632*5c51f124SMoriah Waterland 
633*5c51f124SMoriah Waterland 	/* put standard header at the beginning of the file */
634*5c51f124SMoriah Waterland 
635*5c51f124SMoriah Waterland 	(void) fprintf(destFP, MSG_GZONLY_FILE_HEADER,
636*5c51f124SMoriah Waterland 			get_prog_name(), "add", a_pkgInst, timeb);
637*5c51f124SMoriah Waterland 
638*5c51f124SMoriah Waterland 	/* read source/write destination; add package at appropriate location */
639*5c51f124SMoriah Waterland 
640*5c51f124SMoriah Waterland 	while (fgets(line, sizeof (line), srcFP) != (char *)NULL) {
641*5c51f124SMoriah Waterland 		int	len;
642*5c51f124SMoriah Waterland 
643*5c51f124SMoriah Waterland 		/* strip off trailing newlines */
644*5c51f124SMoriah Waterland 		len = strlen(line);
645*5c51f124SMoriah Waterland 		while ((len > 0) && (line[len-1] == '\n')) {
646*5c51f124SMoriah Waterland 			line[--len] = '\0';
647*5c51f124SMoriah Waterland 		}
648*5c51f124SMoriah Waterland 
649*5c51f124SMoriah Waterland 		/* ignore blank and comment lines */
650*5c51f124SMoriah Waterland 		if ((line[0] == '#') || (line[0] == '\0')) {
651*5c51f124SMoriah Waterland 			continue;
652*5c51f124SMoriah Waterland 		}
653*5c51f124SMoriah Waterland 
654*5c51f124SMoriah Waterland 		/* add pkg if yet to add and pkg <= line */
655*5c51f124SMoriah Waterland 		if ((pkgadded == B_FALSE) && (strcmp(a_pkgInst, line) <= 0)) {
656*5c51f124SMoriah Waterland 			if (strcmp(a_pkgInst, line) != 0) {
657*5c51f124SMoriah Waterland 				(void) fprintf(destFP, "%s\n", a_pkgInst);
658*5c51f124SMoriah Waterland 			}
659*5c51f124SMoriah Waterland 			pkgadded = B_TRUE;
660*5c51f124SMoriah Waterland 		}
661*5c51f124SMoriah Waterland 
662*5c51f124SMoriah Waterland 		(void) fprintf(destFP, "%s\n", line);
663*5c51f124SMoriah Waterland 	}
664*5c51f124SMoriah Waterland 
665*5c51f124SMoriah Waterland 	/* if package not added yet, add to end of the file */
666*5c51f124SMoriah Waterland 
667*5c51f124SMoriah Waterland 	if (pkgadded == B_FALSE) {
668*5c51f124SMoriah Waterland 		(void) fprintf(destFP, "%s\n", a_pkgInst);
669*5c51f124SMoriah Waterland 	}
670*5c51f124SMoriah Waterland 
671*5c51f124SMoriah Waterland 	/* close both files */
672*5c51f124SMoriah Waterland 
673*5c51f124SMoriah Waterland 	(void) fclose(srcFP);
674*5c51f124SMoriah Waterland 
675*5c51f124SMoriah Waterland 	(void) fclose(destFP);
676*5c51f124SMoriah Waterland 
677*5c51f124SMoriah Waterland 	/*
678*5c51f124SMoriah Waterland 	 * Now we want to make a copy of the old gzonly file as a
679*5c51f124SMoriah Waterland 	 * fail-safe.
680*5c51f124SMoriah Waterland 	 */
681*5c51f124SMoriah Waterland 
682*5c51f124SMoriah Waterland 	if ((access(savePath, F_OK) == 0) && remove(savePath)) {
683*5c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
684*5c51f124SMoriah Waterland 		(void) remove(destPath);
685*5c51f124SMoriah Waterland 		return (B_FALSE);
686*5c51f124SMoriah Waterland 	}
687*5c51f124SMoriah Waterland 
688*5c51f124SMoriah Waterland 	if (link(srcPath, savePath) != 0) {
689*5c51f124SMoriah Waterland 		progerr(ERR_LINK, savePath, srcPath, strerror(errno));
690*5c51f124SMoriah Waterland 		(void) remove(destPath);
691*5c51f124SMoriah Waterland 		return (B_FALSE);
692*5c51f124SMoriah Waterland 	}
693*5c51f124SMoriah Waterland 
694*5c51f124SMoriah Waterland 	if (rename(destPath, srcPath) != 0) {
695*5c51f124SMoriah Waterland 		progerr(ERR_RENAME, destPath, srcPath, strerror(errno));
696*5c51f124SMoriah Waterland 		if (rename(savePath, srcPath)) {
697*5c51f124SMoriah Waterland 			progerr(ERR_RENAME, savePath, srcPath, strerror(errno));
698*5c51f124SMoriah Waterland 		}
699*5c51f124SMoriah Waterland 		(void) remove(destPath);
700*5c51f124SMoriah Waterland 		return (B_FALSE);
701*5c51f124SMoriah Waterland 	}
702*5c51f124SMoriah Waterland 
703*5c51f124SMoriah Waterland 	if (remove(savePath) != 0) {
704*5c51f124SMoriah Waterland 		progerr(ERR_REMOVE, savePath, strerror(errno));
705*5c51f124SMoriah Waterland 	}
706*5c51f124SMoriah Waterland 
707*5c51f124SMoriah Waterland 	/* successfully added package */
708*5c51f124SMoriah Waterland 
709*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADDED_GZPKG, a_pkgInst);
710*5c51f124SMoriah Waterland 
711*5c51f124SMoriah Waterland 	return (B_TRUE);
712*5c51f124SMoriah Waterland }
713*5c51f124SMoriah Waterland 
714*5c51f124SMoriah Waterland /*
715*5c51f124SMoriah Waterland  * Name:	pkginfoParamTruth
716*5c51f124SMoriah Waterland  * Description:	Search pkginfo file for specified parameter/value pair
717*5c51f124SMoriah Waterland  * Arguments:	a_fp - Pointer to FILE handle open on pkginfo file to search
718*5c51f124SMoriah Waterland  *		a_param - Pointer to string representing the parameter name
719*5c51f124SMoriah Waterland  *			to search for
720*5c51f124SMoriah Waterland  *		a_value - Pointer to string representing the "success" value
721*5c51f124SMoriah Waterland  *			being searched for
722*5c51f124SMoriah Waterland  *		a_default - determine results if parameter NOT found
723*5c51f124SMoriah Waterland  *			B_TRUE - parameter is TRUE if not found
724*5c51f124SMoriah Waterland  *			B_FALSE - parameter is FALSE if not found
725*5c51f124SMoriah Waterland  * Returns:	boolean_t
726*5c51f124SMoriah Waterland  *		B_TRUE - the parameter was found and matched the specified value
727*5c51f124SMoriah Waterland  *			OR the paramter was not found and a_default == B_TRUE
728*5c51f124SMoriah Waterland  *		B_FALSE - the parameter was found and did NOT match the value
729*5c51f124SMoriah Waterland  *			OR the paramter was not found and a_default == B_FALSE
730*5c51f124SMoriah Waterland  */
731*5c51f124SMoriah Waterland 
732*5c51f124SMoriah Waterland boolean_t
733*5c51f124SMoriah Waterland pkginfoParamTruth(FILE *a_fp, char *a_param, char *a_value, boolean_t a_default)
734*5c51f124SMoriah Waterland {
735*5c51f124SMoriah Waterland 	char		*param;
736*5c51f124SMoriah Waterland 	boolean_t	result;
737*5c51f124SMoriah Waterland 
738*5c51f124SMoriah Waterland 	/* entry assertions */
739*5c51f124SMoriah Waterland 
740*5c51f124SMoriah Waterland 	assert(a_fp != (FILE *)NULL);
741*5c51f124SMoriah Waterland 	assert(a_param != (char *)NULL);
742*5c51f124SMoriah Waterland 	assert(*a_param != '\0');
743*5c51f124SMoriah Waterland 	assert(a_value != (char *)NULL);
744*5c51f124SMoriah Waterland 	assert(*a_value != '\0');
745*5c51f124SMoriah Waterland 
746*5c51f124SMoriah Waterland 	/* rewind the file to the beginning */
747*5c51f124SMoriah Waterland 
748*5c51f124SMoriah Waterland 	rewind(a_fp);
749*5c51f124SMoriah Waterland 
750*5c51f124SMoriah Waterland 	/* search pkginfo file for the specified parameter */
751*5c51f124SMoriah Waterland 
752*5c51f124SMoriah Waterland 	param = fpkgparam(a_fp, a_param);
753*5c51f124SMoriah Waterland 
754*5c51f124SMoriah Waterland 	if (param == (char *)NULL) {
755*5c51f124SMoriah Waterland 		/* parameter not found - return default */
756*5c51f124SMoriah Waterland 		result = a_default;
757*5c51f124SMoriah Waterland 	} else if (*param == '\0') {
758*5c51f124SMoriah Waterland 		/* parameter found but no value - return default */
759*5c51f124SMoriah Waterland 		result = a_default;
760*5c51f124SMoriah Waterland 	} else if (strcasecmp(param, a_value) == 0) {
761*5c51f124SMoriah Waterland 		/* paramter found - matches value */
762*5c51f124SMoriah Waterland 		result = B_TRUE;
763*5c51f124SMoriah Waterland 	} else {
764*5c51f124SMoriah Waterland 		/* parameter found - does not match value */
765*5c51f124SMoriah Waterland 		result = B_FALSE;
766*5c51f124SMoriah Waterland 	}
767*5c51f124SMoriah Waterland 
768*5c51f124SMoriah Waterland 	/* exit debugging info */
769*5c51f124SMoriah Waterland 
770*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_PARAMTRUTH_RESULTS,
771*5c51f124SMoriah Waterland 		a_param, a_value, a_default == B_TRUE ? "true" : "false",
772*5c51f124SMoriah Waterland 		param ? param : "?", result == B_TRUE ? "true" : "false");
773*5c51f124SMoriah Waterland 
774*5c51f124SMoriah Waterland 	/* if parameter value found, free results */
775*5c51f124SMoriah Waterland 
776*5c51f124SMoriah Waterland 	if (param != (char *)NULL) {
777*5c51f124SMoriah Waterland 		(void) free(param);
778*5c51f124SMoriah Waterland 	}
779*5c51f124SMoriah Waterland 
780*5c51f124SMoriah Waterland 	/* return results of search */
781*5c51f124SMoriah Waterland 
782*5c51f124SMoriah Waterland 	return (result);
783*5c51f124SMoriah Waterland }
784*5c51f124SMoriah Waterland 
785*5c51f124SMoriah Waterland /*
786*5c51f124SMoriah Waterland  * Name:	pkgGetPackageList
787*5c51f124SMoriah Waterland  * Description:	Determine list of packages based on list of packages that are
788*5c51f124SMoriah Waterland  *		available, category of packages to select, and list of packages
789*5c51f124SMoriah Waterland  *		to select.
790*5c51f124SMoriah Waterland  * Arguments:	r_pkgList - pointer to pointer to string array where the list
791*5c51f124SMoriah Waterland  *			of selected packages will be returned
792*5c51f124SMoriah Waterland  *		a_argv - pointer to string array containing list of packages
793*5c51f124SMoriah Waterland  *			to select
794*5c51f124SMoriah Waterland  *		a_optind - index into string array of first package to select
795*5c51f124SMoriah Waterland  *		a_categories - pointer to string representing the categories of
796*5c51f124SMoriah Waterland  *			packages to select
797*5c51f124SMoriah Waterland  *		a_categoryList - pointer to string array representing a list
798*5c51f124SMoriah Waterland  *			of categories to select
799*5c51f124SMoriah Waterland  *		a_pkgdev - package dev containing packages that can be selected
800*5c51f124SMoriah Waterland  * Returns:	int
801*5c51f124SMoriah Waterland  *	== 0  - packages found r_pkgList contains results package list retrieved
802*5c51f124SMoriah Waterland  *	== -1 - no packages found (errno == ENOPKG)
803*5c51f124SMoriah Waterland  *	!= 0 - "quit" value entered by user
804*5c51f124SMoriah Waterland  * NOTE:	If both a category and a list of packages to select are provided
805*5c51f124SMoriah Waterland  *		the category is used over the list of packages provided
806*5c51f124SMoriah Waterland  * NOTE:	If neither a category nor a list of packages to select are
807*5c51f124SMoriah Waterland  *		provided, an error is returned
808*5c51f124SMoriah Waterland  */
809*5c51f124SMoriah Waterland 
810*5c51f124SMoriah Waterland int
811*5c51f124SMoriah Waterland pkgGetPackageList(char ***r_pkgList, char **a_argv, int a_optind,
812*5c51f124SMoriah Waterland 	char *a_categories, char **a_categoryList, struct pkgdev *a_pkgdev)
813*5c51f124SMoriah Waterland {
814*5c51f124SMoriah Waterland 	char	*all_pkgs[4] = {"all", NULL};
815*5c51f124SMoriah Waterland 
816*5c51f124SMoriah Waterland 	/* entry assertions */
817*5c51f124SMoriah Waterland 
818*5c51f124SMoriah Waterland 	assert(a_pkgdev != (struct pkgdev *)NULL);
819*5c51f124SMoriah Waterland 	assert(a_pkgdev->dirname != (char *)NULL);
820*5c51f124SMoriah Waterland 	assert(*a_pkgdev->dirname != '\0');
821*5c51f124SMoriah Waterland 	assert(r_pkgList != (char ***)NULL);
822*5c51f124SMoriah Waterland 	assert(a_argv != (char **)NULL);
823*5c51f124SMoriah Waterland 
824*5c51f124SMoriah Waterland 	/* entry debugging info */
825*5c51f124SMoriah Waterland 
826*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_GETPKGLIST_ENTRY);
827*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_GETPKGLIST_ARGS, a_pkgdev->dirname,
828*5c51f124SMoriah Waterland 			a_categories ? a_categories : "?");
829*5c51f124SMoriah Waterland 
830*5c51f124SMoriah Waterland 	/* reset returned package list handle */
831*5c51f124SMoriah Waterland 
832*5c51f124SMoriah Waterland 	*r_pkgList = (char **)NULL;
833*5c51f124SMoriah Waterland 
834*5c51f124SMoriah Waterland 	/*
835*5c51f124SMoriah Waterland 	 * generate list of packages to be removed: if removing by category,
836*5c51f124SMoriah Waterland 	 * then generate package list based on all packages by category,
837*5c51f124SMoriah Waterland 	 * else generate package list based on all packages specified.
838*5c51f124SMoriah Waterland 	 */
839*5c51f124SMoriah Waterland 
840*5c51f124SMoriah Waterland 	if (a_categories != NULL) {
841*5c51f124SMoriah Waterland 		/* generate package list from all packages in given category */
842*5c51f124SMoriah Waterland 
843*5c51f124SMoriah Waterland 		*r_pkgList = gpkglist(a_pkgdev->dirname, &all_pkgs[0],
844*5c51f124SMoriah Waterland 					a_categoryList);
845*5c51f124SMoriah Waterland 
846*5c51f124SMoriah Waterland 		if (*r_pkgList == NULL) {
847*5c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_GPKGLIST_CATFAILED, a_categories);
848*5c51f124SMoriah Waterland 			progerr(ERR_CAT_FND, a_categories);
849*5c51f124SMoriah Waterland 			return (1);
850*5c51f124SMoriah Waterland 		}
851*5c51f124SMoriah Waterland 
852*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_CATOK, a_categories);
853*5c51f124SMoriah Waterland 
854*5c51f124SMoriah Waterland 		return (0);
855*5c51f124SMoriah Waterland 	}
856*5c51f124SMoriah Waterland 
857*5c51f124SMoriah Waterland 	/* generate package list from specified packages */
858*5c51f124SMoriah Waterland 
859*5c51f124SMoriah Waterland 	*r_pkgList = gpkglist(a_pkgdev->dirname, &a_argv[a_optind], NULL);
860*5c51f124SMoriah Waterland 
861*5c51f124SMoriah Waterland 	/* if list generated return results */
862*5c51f124SMoriah Waterland 
863*5c51f124SMoriah Waterland 	if (*r_pkgList != NULL) {
864*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_OK);
865*5c51f124SMoriah Waterland 		return (0);
866*5c51f124SMoriah Waterland 	}
867*5c51f124SMoriah Waterland 
868*5c51f124SMoriah Waterland 	/* handle error from gpkglist */
869*5c51f124SMoriah Waterland 
870*5c51f124SMoriah Waterland 	switch (errno) {
871*5c51f124SMoriah Waterland 	    case ENOPKG:	/* no packages */
872*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_ENOPKG);
873*5c51f124SMoriah Waterland 		return (-1);
874*5c51f124SMoriah Waterland 
875*5c51f124SMoriah Waterland 	    case ESRCH:
876*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_ESRCH);
877*5c51f124SMoriah Waterland 		return (1);
878*5c51f124SMoriah Waterland 
879*5c51f124SMoriah Waterland 	    case EINTR:
880*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_EINTR);
881*5c51f124SMoriah Waterland 		return (3);
882*5c51f124SMoriah Waterland 
883*5c51f124SMoriah Waterland 	    default:
884*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_GPKGLIST_UNKNOWN, errno);
885*5c51f124SMoriah Waterland 		progerr(ERR_GPKGLIST_ERROR);
886*5c51f124SMoriah Waterland 		return (99);
887*5c51f124SMoriah Waterland 	}
888*5c51f124SMoriah Waterland }
889*5c51f124SMoriah Waterland 
890*5c51f124SMoriah Waterland /*
891*5c51f124SMoriah Waterland  * Name:	pkgMatchInherited
892*5c51f124SMoriah Waterland  * Description:	given a pointer to a "source" and a "destination" for an object,
893*5c51f124SMoriah Waterland  *		along with other attributes of the object, determine if the
894*5c51f124SMoriah Waterland  *		object is already installed and is current.
895*5c51f124SMoriah Waterland  * Arguments:	a_src - pointer to string representing the "source" file to
896*5c51f124SMoriah Waterland  *			verify - this would be the current temporary location of
897*5c51f124SMoriah Waterland  *			the file that would be installed
898*5c51f124SMoriah Waterland  *		a_dst - pointer to string representing the "destination" file to
899*5c51f124SMoriah Waterland  *			verify - this would be the ultimate destination for the
900*5c51f124SMoriah Waterland  *			file if installed
901*5c51f124SMoriah Waterland  *		a_rootDir - pointer to string representing the "root directory"
902*5c51f124SMoriah Waterland  *			where the package is being installed
903*5c51f124SMoriah Waterland  *		a_mode - final "mode" file should have when installed
904*5c51f124SMoriah Waterland  *		a_modtime - final "modtime" file should have when installed
905*5c51f124SMoriah Waterland  *		a_ftype - contents "type" of file (f/e/v/s/l)
906*5c51f124SMoriah Waterland  *		a_cksum - final "checksum" file should have when installed
907*5c51f124SMoriah Waterland  * Returns:	boolean_t
908*5c51f124SMoriah Waterland  *			B_TRUE - the specified source file MATCHES the file
909*5c51f124SMoriah Waterland  *				located at the specified destination
910*5c51f124SMoriah Waterland  *			B_FALSE - the specified source files does NOT match
911*5c51f124SMoriah Waterland  *				the file located at the specified destination
912*5c51f124SMoriah Waterland  */
913*5c51f124SMoriah Waterland 
914*5c51f124SMoriah Waterland boolean_t
915*5c51f124SMoriah Waterland pkgMatchInherited(char *a_src, char *a_dst, char *a_rootDir,
916*5c51f124SMoriah Waterland 	char a_mode, time_t a_modtime, char a_ftype, unsigned long a_cksum)
917*5c51f124SMoriah Waterland {
918*5c51f124SMoriah Waterland 	char		cwd[PATH_MAX+1] = {'\0'};
919*5c51f124SMoriah Waterland 	char		dstpath[PATH_MAX+1];
920*5c51f124SMoriah Waterland 	int		cksumerr;
921*5c51f124SMoriah Waterland 	int		n;
922*5c51f124SMoriah Waterland 	struct stat	statbufDst;
923*5c51f124SMoriah Waterland 	struct stat	statbufSrc;
924*5c51f124SMoriah Waterland 	unsigned long	dstcksum;
925*5c51f124SMoriah Waterland 	unsigned long	srcksum;
926*5c51f124SMoriah Waterland 
927*5c51f124SMoriah Waterland 	/* entry assertions */
928*5c51f124SMoriah Waterland 
929*5c51f124SMoriah Waterland 	assert(a_src != (char *)NULL);
930*5c51f124SMoriah Waterland 	assert(*a_src != '\0');
931*5c51f124SMoriah Waterland 	assert(a_dst != (char *)NULL);
932*5c51f124SMoriah Waterland 	assert(*a_dst != '\0');
933*5c51f124SMoriah Waterland 
934*5c51f124SMoriah Waterland 	/* normalize root directory */
935*5c51f124SMoriah Waterland 
936*5c51f124SMoriah Waterland 	if ((a_rootDir == (char *)NULL) || (*a_rootDir == '\0')) {
937*5c51f124SMoriah Waterland 		a_rootDir = "/";
938*5c51f124SMoriah Waterland 	}
939*5c51f124SMoriah Waterland 
940*5c51f124SMoriah Waterland 	/* entry debugging */
941*5c51f124SMoriah Waterland 
942*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_MATCHINHERIT_ENTRY);
943*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_MATCHINHERIT_ARGS, a_src, a_dst, a_rootDir,
944*5c51f124SMoriah Waterland 		a_mode, a_modtime, a_ftype, a_cksum);
945*5c51f124SMoriah Waterland 
946*5c51f124SMoriah Waterland 	/* save current working directory - resolvepath can change it */
947*5c51f124SMoriah Waterland 
948*5c51f124SMoriah Waterland 	(void) getcwd(cwd, sizeof (cwd));
949*5c51f124SMoriah Waterland 
950*5c51f124SMoriah Waterland 	n = resolvepath(a_dst, dstpath, sizeof (dstpath));
951*5c51f124SMoriah Waterland 	if (n <= 0) {
952*5c51f124SMoriah Waterland 		if (errno != ENOENT) {
953*5c51f124SMoriah Waterland 			progerr(ERR_RESOLVEPATH, a_dst, strerror(errno));
954*5c51f124SMoriah Waterland 		}
955*5c51f124SMoriah Waterland 		(void) chdir(cwd);
956*5c51f124SMoriah Waterland 		return (B_FALSE);
957*5c51f124SMoriah Waterland 	}
958*5c51f124SMoriah Waterland 	dstpath[n++] = '\0';	/* make sure string is terminated */
959*5c51f124SMoriah Waterland 
960*5c51f124SMoriah Waterland 	/* return false if path is not in inherited file system space */
961*5c51f124SMoriah Waterland 
962*5c51f124SMoriah Waterland 	if (!z_path_is_inherited(dstpath, a_ftype, a_rootDir)) {
963*5c51f124SMoriah Waterland 		return (B_FALSE);
964*5c51f124SMoriah Waterland 	}
965*5c51f124SMoriah Waterland 
966*5c51f124SMoriah Waterland 	/*
967*5c51f124SMoriah Waterland 	 * path is in inherited file system space: verify existence
968*5c51f124SMoriah Waterland 	 */
969*5c51f124SMoriah Waterland 
970*5c51f124SMoriah Waterland 	/* return false if source file cannot be stat()ed */
971*5c51f124SMoriah Waterland 
972*5c51f124SMoriah Waterland 	if (stat(a_src, &statbufSrc) != 0) {
973*5c51f124SMoriah Waterland 		progerr(ERR_STAT, a_src, strerror(errno));
974*5c51f124SMoriah Waterland 		return (B_FALSE);
975*5c51f124SMoriah Waterland 	}
976*5c51f124SMoriah Waterland 
977*5c51f124SMoriah Waterland 	/* return false if destination file cannot be stat()ed */
978*5c51f124SMoriah Waterland 
979*5c51f124SMoriah Waterland 	if (stat(dstpath, &statbufDst) != 0) {
980*5c51f124SMoriah Waterland 		progerr(ERR_STAT, dstpath, strerror(errno));
981*5c51f124SMoriah Waterland 		return (B_FALSE);
982*5c51f124SMoriah Waterland 	}
983*5c51f124SMoriah Waterland 
984*5c51f124SMoriah Waterland 	/*
985*5c51f124SMoriah Waterland 	 * if this is an editable or volatile file, then the only
986*5c51f124SMoriah Waterland 	 * thing to guarantee is that the file exists - the file
987*5c51f124SMoriah Waterland 	 * attributes do not need to match
988*5c51f124SMoriah Waterland 	 */
989*5c51f124SMoriah Waterland 
990*5c51f124SMoriah Waterland 	/* editable file only needs to exist */
991*5c51f124SMoriah Waterland 
992*5c51f124SMoriah Waterland 	if (a_ftype == 'e') {
993*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_EDITABLE_EXISTS, dstpath);
994*5c51f124SMoriah Waterland 		return (B_TRUE);
995*5c51f124SMoriah Waterland 	}
996*5c51f124SMoriah Waterland 
997*5c51f124SMoriah Waterland 	/* volatile file only needs to exist */
998*5c51f124SMoriah Waterland 
999*5c51f124SMoriah Waterland 	if (a_ftype == 'v') {
1000*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_VOLATILE_EXISTS, dstpath);
1001*5c51f124SMoriah Waterland 		return (B_TRUE);
1002*5c51f124SMoriah Waterland 	}
1003*5c51f124SMoriah Waterland 
1004*5c51f124SMoriah Waterland 	/*
1005*5c51f124SMoriah Waterland 	 * verify modtime if file is not modifiable after install
1006*5c51f124SMoriah Waterland 	 */
1007*5c51f124SMoriah Waterland 
1008*5c51f124SMoriah Waterland 	/* return false if source and destination have different mod times */
1009*5c51f124SMoriah Waterland 
1010*5c51f124SMoriah Waterland 	if (statbufSrc.st_mtim.tv_sec != statbufDst.st_mtim.tv_sec) {
1011*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_MOD_MISMATCH,  a_src,
1012*5c51f124SMoriah Waterland 			statbufSrc.st_mtim.tv_sec, dstpath,
1013*5c51f124SMoriah Waterland 			statbufDst.st_mtim.tv_sec);
1014*5c51f124SMoriah Waterland 		return (B_FALSE);
1015*5c51f124SMoriah Waterland 	}
1016*5c51f124SMoriah Waterland 
1017*5c51f124SMoriah Waterland 	/* return false if destination does not have required mod time */
1018*5c51f124SMoriah Waterland 
1019*5c51f124SMoriah Waterland 	if (statbufDst.st_mtim.tv_sec != a_modtime) {
1020*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_MOD_MISMATCH, dstpath,
1021*5c51f124SMoriah Waterland 			statbufDst.st_mtim.tv_sec, "source", a_modtime);
1022*5c51f124SMoriah Waterland 		return (B_FALSE);
1023*5c51f124SMoriah Waterland 	}
1024*5c51f124SMoriah Waterland 
1025*5c51f124SMoriah Waterland 	/*
1026*5c51f124SMoriah Waterland 	 * verify checksums of both files
1027*5c51f124SMoriah Waterland 	 */
1028*5c51f124SMoriah Waterland 
1029*5c51f124SMoriah Waterland 	/* generate checksum of installed file */
1030*5c51f124SMoriah Waterland 
1031*5c51f124SMoriah Waterland 	cksumerr = 0;
1032*5c51f124SMoriah Waterland 	dstcksum = compute_checksum(&cksumerr, dstpath);
1033*5c51f124SMoriah Waterland 	if (cksumerr != 0) {
1034*5c51f124SMoriah Waterland 		progerr(ERR_CANNOT_CKSUM_FILE, dstpath, strerror(errno));
1035*5c51f124SMoriah Waterland 		return (B_FALSE);
1036*5c51f124SMoriah Waterland 	}
1037*5c51f124SMoriah Waterland 
1038*5c51f124SMoriah Waterland 	/* return false if destination does not match recorded checksum */
1039*5c51f124SMoriah Waterland 
1040*5c51f124SMoriah Waterland 	if (dstcksum != a_cksum) {
1041*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_CKSUM_MISMATCH, dstpath, dstcksum,
1042*5c51f124SMoriah Waterland 				"source", a_cksum);
1043*5c51f124SMoriah Waterland 		return (B_FALSE);
1044*5c51f124SMoriah Waterland 	}
1045*5c51f124SMoriah Waterland 
1046*5c51f124SMoriah Waterland 	/* generate checksum of file to install */
1047*5c51f124SMoriah Waterland 
1048*5c51f124SMoriah Waterland 	cksumerr = 0;
1049*5c51f124SMoriah Waterland 	srcksum = compute_checksum(&cksumerr, a_src);
1050*5c51f124SMoriah Waterland 	if (cksumerr != 0) {
1051*5c51f124SMoriah Waterland 		progerr(ERR_CANNOT_CKSUM_FILE, a_src, strerror(errno));
1052*5c51f124SMoriah Waterland 		return (B_FALSE);
1053*5c51f124SMoriah Waterland 	}
1054*5c51f124SMoriah Waterland 
1055*5c51f124SMoriah Waterland 	/* return false if source to install does not match recorded checksum */
1056*5c51f124SMoriah Waterland 
1057*5c51f124SMoriah Waterland 	if (srcksum != dstcksum) {
1058*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_CKSUM_MISMATCH, a_src, srcksum, dstpath,
1059*5c51f124SMoriah Waterland 				dstcksum);
1060*5c51f124SMoriah Waterland 		return (B_FALSE);
1061*5c51f124SMoriah Waterland 	}
1062*5c51f124SMoriah Waterland 
1063*5c51f124SMoriah Waterland 	/* src/dest identical - return true */
1064*5c51f124SMoriah Waterland 
1065*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_IS_INHERITED, dstpath, "");
1066*5c51f124SMoriah Waterland 
1067*5c51f124SMoriah Waterland 	return (B_TRUE);
1068*5c51f124SMoriah Waterland }
1069*5c51f124SMoriah Waterland 
1070*5c51f124SMoriah Waterland /*
1071*5c51f124SMoriah Waterland  * return string representing path to "global zone only file"
1072*5c51f124SMoriah Waterland  */
1073*5c51f124SMoriah Waterland 
1074*5c51f124SMoriah Waterland char *
1075*5c51f124SMoriah Waterland pkgGetGzOnlyPath(void)
1076*5c51f124SMoriah Waterland {
1077*5c51f124SMoriah Waterland 	return (GLOBALZONE_ONLY_PACKAGE_FILE_PATH);
1078*5c51f124SMoriah Waterland }
1079*5c51f124SMoriah Waterland 
1080*5c51f124SMoriah Waterland /*
1081*5c51f124SMoriah Waterland  * Name:	pkgAddThisZonePackage
1082*5c51f124SMoriah Waterland  * Description:	Add specified package to internal list of "this zone only" pkgs
1083*5c51f124SMoriah Waterland  * Arguments:	a_pkgInst - name of package to add to list
1084*5c51f124SMoriah Waterland  * Returns:	void
1085*5c51f124SMoriah Waterland  */
1086*5c51f124SMoriah Waterland 
1087*5c51f124SMoriah Waterland void
1088*5c51f124SMoriah Waterland pkgAddThisZonePackage(char *a_pkgInst)
1089*5c51f124SMoriah Waterland {
1090*5c51f124SMoriah Waterland 	/* entry assertions */
1091*5c51f124SMoriah Waterland 
1092*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
1093*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
1094*5c51f124SMoriah Waterland 
1095*5c51f124SMoriah Waterland 	/* do not duplicate entries */
1096*5c51f124SMoriah Waterland 
1097*5c51f124SMoriah Waterland 	if (pkgPackageIsThisZone(a_pkgInst) == B_TRUE) {
1098*5c51f124SMoriah Waterland 		return;
1099*5c51f124SMoriah Waterland 	}
1100*5c51f124SMoriah Waterland 
1101*5c51f124SMoriah Waterland 	/* add package name to internal list */
1102*5c51f124SMoriah Waterland 
1103*5c51f124SMoriah Waterland 	if (thisZonePackages == (char **)NULL) {
1104*5c51f124SMoriah Waterland 		thisZonePackages =
1105*5c51f124SMoriah Waterland 				(char **)calloc(2, sizeof (char **));
1106*5c51f124SMoriah Waterland 	} else {
1107*5c51f124SMoriah Waterland 		thisZonePackages =
1108*5c51f124SMoriah Waterland 				(char **)realloc(thisZonePackages,
1109*5c51f124SMoriah Waterland 				sizeof (char **)*(numThisZonePackages+2));
1110*5c51f124SMoriah Waterland 	}
1111*5c51f124SMoriah Waterland 
1112*5c51f124SMoriah Waterland 	/* handle out of memory error */
1113*5c51f124SMoriah Waterland 
1114*5c51f124SMoriah Waterland 	if (thisZonePackages == (char **)NULL) {
1115*5c51f124SMoriah Waterland 		progerr(ERR_MEMORY, errno);
1116*5c51f124SMoriah Waterland 		quit(99);
1117*5c51f124SMoriah Waterland 	}
1118*5c51f124SMoriah Waterland 
1119*5c51f124SMoriah Waterland 	/* add this entry to the end of the list */
1120*5c51f124SMoriah Waterland 
1121*5c51f124SMoriah Waterland 	thisZonePackages[numThisZonePackages] = strdup(a_pkgInst);
1122*5c51f124SMoriah Waterland 	if (thisZonePackages[numThisZonePackages] == (char *)NULL) {
1123*5c51f124SMoriah Waterland 		progerr(ERR_MEMORY, errno);
1124*5c51f124SMoriah Waterland 		quit(99);
1125*5c51f124SMoriah Waterland 	}
1126*5c51f124SMoriah Waterland 
1127*5c51f124SMoriah Waterland 	numThisZonePackages++;
1128*5c51f124SMoriah Waterland 
1129*5c51f124SMoriah Waterland 	/* make sure end of the list is properly terminated */
1130*5c51f124SMoriah Waterland 
1131*5c51f124SMoriah Waterland 	thisZonePackages[numThisZonePackages] = (char *)NULL;
1132*5c51f124SMoriah Waterland 
1133*5c51f124SMoriah Waterland 	/* exit debugging info */
1134*5c51f124SMoriah Waterland 
1135*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_ADD_TZP, numThisZonePackages,
1136*5c51f124SMoriah Waterland 			thisZonePackages[numThisZonePackages-1]);
1137*5c51f124SMoriah Waterland }
1138*5c51f124SMoriah Waterland 
1139*5c51f124SMoriah Waterland /*
1140*5c51f124SMoriah Waterland  * Name:	pkgPackageIsThisZone
1141*5c51f124SMoriah Waterland  * Description:	Determine if the specified package is marked to be installed
1142*5c51f124SMoriah Waterland  *		in this zone only
1143*5c51f124SMoriah Waterland  * Arguments:	a_pkgInst - pointer to string representing package name to check
1144*5c51f124SMoriah Waterland  * Returns:	boolean_t
1145*5c51f124SMoriah Waterland  *			B_TRUE - the package IS "this zone only"
1146*5c51f124SMoriah Waterland  *			B_FALSE - the paackage is NOT "this zone only"
1147*5c51f124SMoriah Waterland  */
1148*5c51f124SMoriah Waterland 
1149*5c51f124SMoriah Waterland boolean_t
1150*5c51f124SMoriah Waterland pkgPackageIsThisZone(char *a_pkgInst)
1151*5c51f124SMoriah Waterland {
1152*5c51f124SMoriah Waterland 	int		n;
1153*5c51f124SMoriah Waterland 
1154*5c51f124SMoriah Waterland 	/* entry assertions */
1155*5c51f124SMoriah Waterland 
1156*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
1157*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
1158*5c51f124SMoriah Waterland 
1159*5c51f124SMoriah Waterland 	/* if no inherited file systems, there can be no match */
1160*5c51f124SMoriah Waterland 
1161*5c51f124SMoriah Waterland 	if (numThisZonePackages == 0) {
1162*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_NOT_THISZONE, a_pkgInst);
1163*5c51f124SMoriah Waterland 		return (B_FALSE);
1164*5c51f124SMoriah Waterland 	}
1165*5c51f124SMoriah Waterland 
1166*5c51f124SMoriah Waterland 	/*
1167*5c51f124SMoriah Waterland 	 * see if this package is in the "this zone only" list
1168*5c51f124SMoriah Waterland 	 */
1169*5c51f124SMoriah Waterland 
1170*5c51f124SMoriah Waterland 	for (n = 0; n < numThisZonePackages; n++) {
1171*5c51f124SMoriah Waterland 		if (strcmp(a_pkgInst, thisZonePackages[n]) == 0) {
1172*5c51f124SMoriah Waterland 			echoDebug(DBG_PKGOPS_IS_THISZONE, a_pkgInst);
1173*5c51f124SMoriah Waterland 			return (B_TRUE);
1174*5c51f124SMoriah Waterland 		}
1175*5c51f124SMoriah Waterland 	}
1176*5c51f124SMoriah Waterland 
1177*5c51f124SMoriah Waterland 	/* path is not in "this zone only" list */
1178*5c51f124SMoriah Waterland 
1179*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_IS_NOT_THISZONE, a_pkgInst);
1180*5c51f124SMoriah Waterland 
1181*5c51f124SMoriah Waterland 	return (B_FALSE);
1182*5c51f124SMoriah Waterland }
1183*5c51f124SMoriah Waterland 
1184*5c51f124SMoriah Waterland /*
1185*5c51f124SMoriah Waterland  * Name:	pkgLocateHighestInst
1186*5c51f124SMoriah Waterland  * Description:	Locate the highest installed instance of a package
1187*5c51f124SMoriah Waterland  * Arguments:	r_path - [RO, *RW] - (char *)
1188*5c51f124SMoriah Waterland  *			Pointer to buffer where the full path to the top level
1189*5c51f124SMoriah Waterland  *			directory containing the latest instance of the
1190*5c51f124SMoriah Waterland  *			specified package is located is placed.
1191*5c51f124SMoriah Waterland  *		r_pathLen - [RO, *RO] - (int)
1192*5c51f124SMoriah Waterland  *			Integer representing the size of r_path in bytes.
1193*5c51f124SMoriah Waterland  *		r_pkgInst - [RO, *RW] - (char *)
1194*5c51f124SMoriah Waterland  *			Pointer to buffer where the package instance name of the
1195*5c51f124SMoriah Waterland  *			latest instance of the specified package is placed.
1196*5c51f124SMoriah Waterland  *		r_pkgInstLen - [RO, *RO] - (int)
1197*5c51f124SMoriah Waterland  *			Integer representing the size of r_pkgInst in bytes.
1198*5c51f124SMoriah Waterland  *		a_rootPath - [RO, *RO] - (char *)
1199*5c51f124SMoriah Waterland  *			Pointer to string representing the root path to look
1200*5c51f124SMoriah Waterland  *			for the latest instance of the specified package.
1201*5c51f124SMoriah Waterland  *		a_pkgInst - [RO, *RO] - (char *)
1202*5c51f124SMoriah Waterland  *			Pointer to string representing the name of the package
1203*5c51f124SMoriah Waterland  *			to locate the latest installed instance of.
1204*5c51f124SMoriah Waterland  */
1205*5c51f124SMoriah Waterland 
1206*5c51f124SMoriah Waterland void
1207*5c51f124SMoriah Waterland pkgLocateHighestInst(char *r_path, int r_pathLen, char *r_pkgInst,
1208*5c51f124SMoriah Waterland 	int r_pkgInstLen, char *a_rootPath, char *a_pkgInst)
1209*5c51f124SMoriah Waterland {
1210*5c51f124SMoriah Waterland 	char		pkgInstPath[PATH_MAX] = {'\0'};
1211*5c51f124SMoriah Waterland 	char		pkgWild[PKGSIZ+1] = {'\0'};
1212*5c51f124SMoriah Waterland 	char		pkgName[PKGSIZ+1] = {'\0'};
1213*5c51f124SMoriah Waterland 	int		npkgs;
1214*5c51f124SMoriah Waterland 	struct pkginfo	*pinf = (struct pkginfo *)NULL;
1215*5c51f124SMoriah Waterland 
1216*5c51f124SMoriah Waterland 	/* entry assertions */
1217*5c51f124SMoriah Waterland 
1218*5c51f124SMoriah Waterland 	assert(r_path != (char *)NULL);
1219*5c51f124SMoriah Waterland 	assert(r_pathLen > 0);
1220*5c51f124SMoriah Waterland 	assert(r_pkgInst != (char *)NULL);
1221*5c51f124SMoriah Waterland 	assert(r_pkgInstLen > 0);
1222*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
1223*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
1224*5c51f124SMoriah Waterland 
1225*5c51f124SMoriah Waterland 	/* normalize root path */
1226*5c51f124SMoriah Waterland 
1227*5c51f124SMoriah Waterland 	if ((a_rootPath == (char *)NULL) || (strcmp(a_rootPath, "/") == 0)) {
1228*5c51f124SMoriah Waterland 		a_rootPath = "";
1229*5c51f124SMoriah Waterland 	}
1230*5c51f124SMoriah Waterland 
1231*5c51f124SMoriah Waterland 	/* construct path to package repository directory (eg. /var/sadm/pkg) */
1232*5c51f124SMoriah Waterland 
1233*5c51f124SMoriah Waterland 	(void) snprintf(pkgInstPath, sizeof (pkgInstPath), "%s%s", a_rootPath,
1234*5c51f124SMoriah Waterland 		PKGLOC);
1235*5c51f124SMoriah Waterland 
1236*5c51f124SMoriah Waterland 	/* entry debugging info */
1237*5c51f124SMoriah Waterland 
1238*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_ENTRY);
1239*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_ARGS, pkgInstPath, a_pkgInst);
1240*5c51f124SMoriah Waterland 
1241*5c51f124SMoriah Waterland 	/* reset returned path/package instance so both ares empty */
1242*5c51f124SMoriah Waterland 
1243*5c51f124SMoriah Waterland 	*r_path = '\0';
1244*5c51f124SMoriah Waterland 	*r_pkgInst = '\0';
1245*5c51f124SMoriah Waterland 
1246*5c51f124SMoriah Waterland 	/* remove any architecture extension */
1247*5c51f124SMoriah Waterland 
1248*5c51f124SMoriah Waterland 	pkgstrGetToken_r((char *)NULL, a_pkgInst, 0, ".",
1249*5c51f124SMoriah Waterland 		pkgName, sizeof (pkgName));
1250*5c51f124SMoriah Waterland 
1251*5c51f124SMoriah Waterland 	/* make sure that the package name is valid and can be wild carded */
1252*5c51f124SMoriah Waterland 
1253*5c51f124SMoriah Waterland 	if (pkgnmchk(pkgName, NULL, 0) || strchr(pkgName, '.')) {
1254*5c51f124SMoriah Waterland 		progerr(ERR_PKGOPS_LOCHIGH_BAD_PKGNAME, pkgName);
1255*5c51f124SMoriah Waterland 		quit(99);
1256*5c51f124SMoriah Waterland 	}
1257*5c51f124SMoriah Waterland 
1258*5c51f124SMoriah Waterland 	/* create wild card specification for this package instance */
1259*5c51f124SMoriah Waterland 
1260*5c51f124SMoriah Waterland 	(void) snprintf(pkgWild, sizeof (pkgWild), "%s.*", pkgName);
1261*5c51f124SMoriah Waterland 
1262*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_WILDCARD, pkgName, pkgWild);
1263*5c51f124SMoriah Waterland 
1264*5c51f124SMoriah Waterland 	/*
1265*5c51f124SMoriah Waterland 	 * inspect the system to determine if any instances of the
1266*5c51f124SMoriah Waterland 	 * package being installed already exist on the system
1267*5c51f124SMoriah Waterland 	 */
1268*5c51f124SMoriah Waterland 
1269*5c51f124SMoriah Waterland 	for (npkgs = 0; ; npkgs++) {
1270*5c51f124SMoriah Waterland 		char	*savePkgdir;
1271*5c51f124SMoriah Waterland 		int	r;
1272*5c51f124SMoriah Waterland 
1273*5c51f124SMoriah Waterland 		/* allocate new pinfo structure for use in the pkginfo call */
1274*5c51f124SMoriah Waterland 
1275*5c51f124SMoriah Waterland 		pinf = _pkginfoFactory();
1276*5c51f124SMoriah Waterland 
1277*5c51f124SMoriah Waterland 		/*
1278*5c51f124SMoriah Waterland 		 * lookup the specified package; the first call will cause the
1279*5c51f124SMoriah Waterland 		 * pkgdir directory to be opened - it will be closed when the
1280*5c51f124SMoriah Waterland 		 * end of directory is read and pkginfo() returns != 0. You must
1281*5c51f124SMoriah Waterland 		 * cycle through all instances until pkginfo() returns != 0.
1282*5c51f124SMoriah Waterland 		 * NOTE: pkginfo() requires the global variable 'pkgdir' be set
1283*5c51f124SMoriah Waterland 		 * to the package installed directory (<root>/var/sadm/pkg).
1284*5c51f124SMoriah Waterland 		 */
1285*5c51f124SMoriah Waterland 
1286*5c51f124SMoriah Waterland 		savePkgdir = pkgdir;
1287*5c51f124SMoriah Waterland 		pkgdir = pkgInstPath;
1288*5c51f124SMoriah Waterland 
1289*5c51f124SMoriah Waterland 		r = pkginfo(pinf, pkgWild, NULL, NULL);
1290*5c51f124SMoriah Waterland 
1291*5c51f124SMoriah Waterland 		pkgdir = savePkgdir;
1292*5c51f124SMoriah Waterland 
1293*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, pkgName, r);
1294*5c51f124SMoriah Waterland 
1295*5c51f124SMoriah Waterland 		/* break out of loop of no package found */
1296*5c51f124SMoriah Waterland 
1297*5c51f124SMoriah Waterland 		if (r != 0) {
1298*5c51f124SMoriah Waterland 			pkginfoFree(&pinf);
1299*5c51f124SMoriah Waterland 			break;
1300*5c51f124SMoriah Waterland 		}
1301*5c51f124SMoriah Waterland 
1302*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGOPS_LOCHIGH_INSTANCE, npkgs,
1303*5c51f124SMoriah Waterland 			pinf->pkginst ? pinf->pkginst : "",
1304*5c51f124SMoriah Waterland 			pinf->name ? pinf->name : "",
1305*5c51f124SMoriah Waterland 			pinf->arch ? pinf->arch : "",
1306*5c51f124SMoriah Waterland 			pinf->version ? pinf->version : "",
1307*5c51f124SMoriah Waterland 			pinf->vendor ? pinf->vendor : "",
1308*5c51f124SMoriah Waterland 			pinf->basedir ? pinf->basedir : "",
1309*5c51f124SMoriah Waterland 			pinf->catg ? pinf->catg : "",
1310*5c51f124SMoriah Waterland 			pinf->status);
1311*5c51f124SMoriah Waterland 
1312*5c51f124SMoriah Waterland 		/* save path/instance name for this instance found */
1313*5c51f124SMoriah Waterland 
1314*5c51f124SMoriah Waterland 		(void) strlcpy(r_pkgInst, pinf->pkginst, r_pkgInstLen);
1315*5c51f124SMoriah Waterland 		pkgstrPrintf_r(r_path, r_pathLen, "%s%s/%s", a_rootPath,
1316*5c51f124SMoriah Waterland 			PKGLOC, pinf->pkginst);
1317*5c51f124SMoriah Waterland 
1318*5c51f124SMoriah Waterland 		pkginfoFree(&pinf);
1319*5c51f124SMoriah Waterland 	}
1320*5c51f124SMoriah Waterland 
1321*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGOPS_LOCHIGH_RETURN, npkgs, r_pkgInst, r_path);
1322*5c51f124SMoriah Waterland }
1323*5c51f124SMoriah Waterland 
1324*5c51f124SMoriah Waterland /*
1325*5c51f124SMoriah Waterland  * Name:	pkgTestInstalled
1326*5c51f124SMoriah Waterland  * Description:	determine if package is installed at specified root path
1327*5c51f124SMoriah Waterland  * Arguments:	a_packageName - name of package to test
1328*5c51f124SMoriah Waterland  * 		a_rootPath - root path of alternative root to test
1329*5c51f124SMoriah Waterland  * Returns:	B_TRUE - package is installed
1330*5c51f124SMoriah Waterland  *		B_FALSE - package is not installed
1331*5c51f124SMoriah Waterland  */
1332*5c51f124SMoriah Waterland 
1333*5c51f124SMoriah Waterland boolean_t
1334*5c51f124SMoriah Waterland pkgTestInstalled(char *a_packageName, char *a_rootPath)
1335*5c51f124SMoriah Waterland {
1336*5c51f124SMoriah Waterland 	char	cmd[MAXPATHLEN+1];
1337*5c51f124SMoriah Waterland 	int	rc;
1338*5c51f124SMoriah Waterland 
1339*5c51f124SMoriah Waterland 	/* entry assertions */
1340*5c51f124SMoriah Waterland 
1341*5c51f124SMoriah Waterland 	assert(a_packageName != (char *)NULL);
1342*5c51f124SMoriah Waterland 	assert(*a_packageName != '\0');
1343*5c51f124SMoriah Waterland 	assert(a_rootPath != (char *)NULL);
1344*5c51f124SMoriah Waterland 	assert(a_rootPath != '\0');
1345*5c51f124SMoriah Waterland 
1346*5c51f124SMoriah Waterland 	/* entry debugging info */
1347*5c51f124SMoriah Waterland 
1348*5c51f124SMoriah Waterland 	echoDebug(DBG_PKG_TEST_EXISTENCE, a_packageName, a_rootPath);
1349*5c51f124SMoriah Waterland 
1350*5c51f124SMoriah Waterland 	/*
1351*5c51f124SMoriah Waterland 	 * create pkginfo command to execute:
1352*5c51f124SMoriah Waterland 	 * /usr/bin/pkginfo -q <packageName>
1353*5c51f124SMoriah Waterland 	 */
1354*5c51f124SMoriah Waterland 	(void) snprintf(cmd, sizeof (cmd),
1355*5c51f124SMoriah Waterland 		"%s -q %s", PKGINFO_CMD, a_packageName);
1356*5c51f124SMoriah Waterland 
1357*5c51f124SMoriah Waterland 	/* execute command */
1358*5c51f124SMoriah Waterland 
1359*5c51f124SMoriah Waterland 	rc = system(cmd);
1360*5c51f124SMoriah Waterland 
1361*5c51f124SMoriah Waterland 	/* return success if pkginfo returns "0" */
1362*5c51f124SMoriah Waterland 
1363*5c51f124SMoriah Waterland 	if (rc == 0) {
1364*5c51f124SMoriah Waterland 		echoDebug(DBG_PKG_INSTALLED, a_packageName, a_rootPath);
1365*5c51f124SMoriah Waterland 		return (B_TRUE);
1366*5c51f124SMoriah Waterland 	}
1367*5c51f124SMoriah Waterland 
1368*5c51f124SMoriah Waterland 	/* package not installed */
1369*5c51f124SMoriah Waterland 
1370*5c51f124SMoriah Waterland 	echoDebug(DBG_PKG_NOT_INSTALLED, a_packageName, a_rootPath);
1371*5c51f124SMoriah Waterland 
1372*5c51f124SMoriah Waterland 	return (B_FALSE);
1373*5c51f124SMoriah Waterland }
1374*5c51f124SMoriah Waterland 
1375*5c51f124SMoriah Waterland /*
1376*5c51f124SMoriah Waterland  * *****************************************************************************
1377*5c51f124SMoriah Waterland  * static internal (private) functions
1378*5c51f124SMoriah Waterland  * *****************************************************************************
1379*5c51f124SMoriah Waterland  */
1380*5c51f124SMoriah Waterland 
1381*5c51f124SMoriah Waterland static void
1382*5c51f124SMoriah Waterland _pkginfoInit(struct pkginfo *a_info)
1383*5c51f124SMoriah Waterland {
1384*5c51f124SMoriah Waterland 	/* entry assertions */
1385*5c51f124SMoriah Waterland 
1386*5c51f124SMoriah Waterland 	assert(a_info != (struct pkginfo *)NULL);
1387*5c51f124SMoriah Waterland 
1388*5c51f124SMoriah Waterland 	/* free previously allocated space */
1389*5c51f124SMoriah Waterland 
1390*5c51f124SMoriah Waterland 	if (a_info->pkginst) {
1391*5c51f124SMoriah Waterland 		free(a_info->pkginst);
1392*5c51f124SMoriah Waterland 		if (a_info->arch)
1393*5c51f124SMoriah Waterland 			free(a_info->arch);
1394*5c51f124SMoriah Waterland 		if (a_info->version)
1395*5c51f124SMoriah Waterland 			free(a_info->version);
1396*5c51f124SMoriah Waterland 		if (a_info->basedir)
1397*5c51f124SMoriah Waterland 			free(a_info->basedir);
1398*5c51f124SMoriah Waterland 		if (a_info->name)
1399*5c51f124SMoriah Waterland 			free(a_info->name);
1400*5c51f124SMoriah Waterland 		if (a_info->vendor)
1401*5c51f124SMoriah Waterland 			free(a_info->vendor);
1402*5c51f124SMoriah Waterland 		if (a_info->catg)
1403*5c51f124SMoriah Waterland 			free(a_info->catg);
1404*5c51f124SMoriah Waterland 	}
1405*5c51f124SMoriah Waterland 
1406*5c51f124SMoriah Waterland 	a_info->pkginst = NULL;
1407*5c51f124SMoriah Waterland 	a_info->arch = a_info->version = NULL;
1408*5c51f124SMoriah Waterland 	a_info->basedir = a_info->name = NULL;
1409*5c51f124SMoriah Waterland 	a_info->vendor = a_info->catg = NULL;
1410*5c51f124SMoriah Waterland 	a_info->status = PI_UNKNOWN;
1411*5c51f124SMoriah Waterland }
1412*5c51f124SMoriah Waterland 
1413*5c51f124SMoriah Waterland static struct pkginfo *
1414*5c51f124SMoriah Waterland _pkginfoFactory(void)
1415*5c51f124SMoriah Waterland {
1416*5c51f124SMoriah Waterland 	struct pkginfo *pinf;
1417*5c51f124SMoriah Waterland 
1418*5c51f124SMoriah Waterland 	pinf = (struct pkginfo *)calloc(1, sizeof (struct pkginfo));
1419*5c51f124SMoriah Waterland 	if (pinf == (struct pkginfo *)NULL) {
1420*5c51f124SMoriah Waterland 		progerr(ERR_MEM);
1421*5c51f124SMoriah Waterland 		exit(1);
1422*5c51f124SMoriah Waterland 	}
1423*5c51f124SMoriah Waterland 
1424*5c51f124SMoriah Waterland 	_pkginfoInit(pinf);
1425*5c51f124SMoriah Waterland 	return (pinf);
1426*5c51f124SMoriah Waterland }
1427