xref: /onnv-gate/usr/src/cmd/svr4pkg/libinst/fixpath.c (revision 9781:ccf49524d5dc)
1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM  *
4*9781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM  *
8*9781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM  * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM  *
13*9781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM  *
19*9781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM  */
21*9781SMoriah.Waterland@Sun.COM 
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*9781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM  */
26*9781SMoriah.Waterland@Sun.COM 
27*9781SMoriah.Waterland@Sun.COM 
28*9781SMoriah.Waterland@Sun.COM /*
29*9781SMoriah.Waterland@Sun.COM  * This module contains all the code necessary to establish the key base
30*9781SMoriah.Waterland@Sun.COM  * directories to which the actual components of the package will be
31*9781SMoriah.Waterland@Sun.COM  * installed or removed. -- JST
32*9781SMoriah.Waterland@Sun.COM  */
33*9781SMoriah.Waterland@Sun.COM 
34*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
35*9781SMoriah.Waterland@Sun.COM #include <string.h>
36*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
37*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
38*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>	/* mkdir() declaration */
39*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
40*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
41*9781SMoriah.Waterland@Sun.COM #include <install.h>
42*9781SMoriah.Waterland@Sun.COM #include <libadm.h>
43*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
44*9781SMoriah.Waterland@Sun.COM 
45*9781SMoriah.Waterland@Sun.COM static char *install_root = NULL;
46*9781SMoriah.Waterland@Sun.COM static int install_root_exists = 0;	/* An install root was specified */
47*9781SMoriah.Waterland@Sun.COM static int install_root_len;		/* strlen(install_root) */
48*9781SMoriah.Waterland@Sun.COM static char *orig_basedir = NULL;	/* The unadjusted basedir */
49*9781SMoriah.Waterland@Sun.COM static char *basedir = NULL;		/* basedir (cmb w/ inst rt if req) */
50*9781SMoriah.Waterland@Sun.COM static int basedir_exists = 0;		/* There are relocatable paths */
51*9781SMoriah.Waterland@Sun.COM static char *client_basedir = NULL;
52*9781SMoriah.Waterland@Sun.COM static int client_basedir_exists = 0;	/* Installing from a host */
53*9781SMoriah.Waterland@Sun.COM static char *env_cl_bdir = NULL;	/* CLIENT_BASEDIR from environment */
54*9781SMoriah.Waterland@Sun.COM static int ir_accessed = 0;		/* install_root has been used */
55*9781SMoriah.Waterland@Sun.COM static int relocatable;			/* set_basedir() assumed this */
56*9781SMoriah.Waterland@Sun.COM static int partial_inst = 0; /* Installing pkg from partial spool directory */
57*9781SMoriah.Waterland@Sun.COM static boolean_t depend_pkginfo_DB = B_FALSE; /* Only update depend/pkginfoDB */
58*9781SMoriah.Waterland@Sun.COM static int partial_spool_create = 0; /* Create partial spool dir */
59*9781SMoriah.Waterland@Sun.COM 
60*9781SMoriah.Waterland@Sun.COM static int	ask_basedir(char *path, int nointeract);
61*9781SMoriah.Waterland@Sun.COM static char	*expand_path(char *path);
62*9781SMoriah.Waterland@Sun.COM static int	set_client_basedir(void);
63*9781SMoriah.Waterland@Sun.COM static char 	*fixpath_dup(char *path);
64*9781SMoriah.Waterland@Sun.COM static int	orig_offset_rel;
65*9781SMoriah.Waterland@Sun.COM 
66*9781SMoriah.Waterland@Sun.COM /*
67*9781SMoriah.Waterland@Sun.COM  * base_sepr and rel_fmt support construction of absolute paths from
68*9781SMoriah.Waterland@Sun.COM  * relative paths.
69*9781SMoriah.Waterland@Sun.COM  */
70*9781SMoriah.Waterland@Sun.COM static int	base_sepr = 1;	/* separator length btwn basedir & path */
71*9781SMoriah.Waterland@Sun.COM static char	*rel_fmt[] = { "%s%s", "%s/%s" };
72*9781SMoriah.Waterland@Sun.COM 
73*9781SMoriah.Waterland@Sun.COM static int	eval_valid = 0;	/* everything set up to do an eval_path() */
74*9781SMoriah.Waterland@Sun.COM 
75*9781SMoriah.Waterland@Sun.COM /* libpkg/gpkgmap.c */
76*9781SMoriah.Waterland@Sun.COM extern int	getmapmode();
77*9781SMoriah.Waterland@Sun.COM 
78*9781SMoriah.Waterland@Sun.COM #define	MSG_IR_REPL	"Replacing current install root with %s."
79*9781SMoriah.Waterland@Sun.COM #define	ERR_IRSET	"Install_root has already been set to <%s> and used."
80*9781SMoriah.Waterland@Sun.COM #define	ERR_IRNOTABS	"Install_root (-R option) requires an absolute " \
81*9781SMoriah.Waterland@Sun.COM 			"pathname: <%s>"
82*9781SMoriah.Waterland@Sun.COM #define	ERR_ALLOCFAILED	"insufficient memory in %s"
83*9781SMoriah.Waterland@Sun.COM #define	ERR_ADMIN_INVAL	"Invalid basedir entry in admin file."
84*9781SMoriah.Waterland@Sun.COM #define	ERR_PATHNAME 	"Path name is invalid"
85*9781SMoriah.Waterland@Sun.COM #define	ERR_RELINABS	"Relative path <%s> found in absolute package."
86*9781SMoriah.Waterland@Sun.COM #define	ERR_CL_MIS	"Constructed CLIENT_BASEDIR <%s> and " \
87*9781SMoriah.Waterland@Sun.COM 			"environment CLIENT_BASEDIR <%s> do not match."
88*9781SMoriah.Waterland@Sun.COM #define	ERR_ASKBD	"%s is already installed at %s. Cannot create a " \
89*9781SMoriah.Waterland@Sun.COM 			    "duplicate installation at %s."
90*9781SMoriah.Waterland@Sun.COM #define	ERR_NO_CL_BD	"Cannot resolve CLIENT_BASEDIR conflicts."
91*9781SMoriah.Waterland@Sun.COM #define	ERR_AMBDIRS	"Cannot evaluate path due to ambiguous " \
92*9781SMoriah.Waterland@Sun.COM 			"base directories."
93*9781SMoriah.Waterland@Sun.COM #define	ERR_NODELETE	"unable to delete <%s>."
94*9781SMoriah.Waterland@Sun.COM #define	ERR_MKBASE	"unable to make directory <%s>."
95*9781SMoriah.Waterland@Sun.COM #define	MSG_REQBASEDIR	"Installation of this package requires a base " \
96*9781SMoriah.Waterland@Sun.COM 			"directory."
97*9781SMoriah.Waterland@Sun.COM 
98*9781SMoriah.Waterland@Sun.COM #define	MSG_MUSTEXIST	"\\nThe selected base directory <%s> must exist " \
99*9781SMoriah.Waterland@Sun.COM 			"before installation is attempted."
100*9781SMoriah.Waterland@Sun.COM #define	MSG_YORNPRMPT	"Do you want this directory created now"
101*9781SMoriah.Waterland@Sun.COM 
102*9781SMoriah.Waterland@Sun.COM #define	MSG_ISAFILE	"\\nThe selected base directory <%s> must exist " \
103*9781SMoriah.Waterland@Sun.COM 			"before installation is attempted, but a file " \
104*9781SMoriah.Waterland@Sun.COM 			"already exists in it's place."
105*9781SMoriah.Waterland@Sun.COM #define	MSG_YORNFILE	"Do you want the file deleted and the directory " \
106*9781SMoriah.Waterland@Sun.COM 			"created now"
107*9781SMoriah.Waterland@Sun.COM 
108*9781SMoriah.Waterland@Sun.COM #define	MSG_PROMPT	"Enter path to package base directory"
109*9781SMoriah.Waterland@Sun.COM 
110*9781SMoriah.Waterland@Sun.COM #define	MSG_HELP	"Installation of this package requires that a UNIX " \
111*9781SMoriah.Waterland@Sun.COM 			"directory be available for installation of " \
112*9781SMoriah.Waterland@Sun.COM 			"appropriate software.  This directory may be part " \
113*9781SMoriah.Waterland@Sun.COM 			"of any mounted filesystem, or may itself be a " \
114*9781SMoriah.Waterland@Sun.COM 			"mount point.  In general, it is unwise to select a " \
115*9781SMoriah.Waterland@Sun.COM 			"base directory which already contains other files " \
116*9781SMoriah.Waterland@Sun.COM 			"and/or directories."
117*9781SMoriah.Waterland@Sun.COM 
118*9781SMoriah.Waterland@Sun.COM /*
119*9781SMoriah.Waterland@Sun.COM  * Set the install root (-R option).
120*9781SMoriah.Waterland@Sun.COM  */
121*9781SMoriah.Waterland@Sun.COM 
122*9781SMoriah.Waterland@Sun.COM int
set_inst_root(char * path)123*9781SMoriah.Waterland@Sun.COM set_inst_root(char *path)
124*9781SMoriah.Waterland@Sun.COM {
125*9781SMoriah.Waterland@Sun.COM 	static	char	tmp_path[PATH_MAX];
126*9781SMoriah.Waterland@Sun.COM 
127*9781SMoriah.Waterland@Sun.COM 	/*
128*9781SMoriah.Waterland@Sun.COM 	 * If we've already set the install_root but no one has used it
129*9781SMoriah.Waterland@Sun.COM 	 * yet, we'll complain and allow the change. If it's been used
130*9781SMoriah.Waterland@Sun.COM 	 * then we'll deny the switch & return failed.
131*9781SMoriah.Waterland@Sun.COM 	 */
132*9781SMoriah.Waterland@Sun.COM 	if (install_root_exists)
133*9781SMoriah.Waterland@Sun.COM 		/* If the two install_roots are different - problem */
134*9781SMoriah.Waterland@Sun.COM 		if (strcmp(install_root, path))
135*9781SMoriah.Waterland@Sun.COM 			/* We are trying to *change* the install_root */
136*9781SMoriah.Waterland@Sun.COM 			if (ir_accessed) {
137*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(ERR_IRSET), path);
138*9781SMoriah.Waterland@Sun.COM 				return (0);
139*9781SMoriah.Waterland@Sun.COM 			} else { /* !ir_accessed */
140*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(MSG_IR_REPL), path);
141*9781SMoriah.Waterland@Sun.COM 				install_root_exists = 0;	/* reset */
142*9781SMoriah.Waterland@Sun.COM 				install_root = NULL;
143*9781SMoriah.Waterland@Sun.COM 			}
144*9781SMoriah.Waterland@Sun.COM 
145*9781SMoriah.Waterland@Sun.COM 	if (path && *path) {
146*9781SMoriah.Waterland@Sun.COM 		if (*path != '/') {
147*9781SMoriah.Waterland@Sun.COM 			ptext(stderr, gettext(ERR_IRNOTABS), path);
148*9781SMoriah.Waterland@Sun.COM 			return (0);
149*9781SMoriah.Waterland@Sun.COM 		}
150*9781SMoriah.Waterland@Sun.COM 
151*9781SMoriah.Waterland@Sun.COM 		(void) strlcpy(tmp_path, path, sizeof (tmp_path));
152*9781SMoriah.Waterland@Sun.COM 
153*9781SMoriah.Waterland@Sun.COM 		canonize(tmp_path);
154*9781SMoriah.Waterland@Sun.COM 
155*9781SMoriah.Waterland@Sun.COM 		install_root = tmp_path;
156*9781SMoriah.Waterland@Sun.COM 
157*9781SMoriah.Waterland@Sun.COM 		install_root_exists = 1;
158*9781SMoriah.Waterland@Sun.COM 
159*9781SMoriah.Waterland@Sun.COM 		install_root_len = strlen(install_root);
160*9781SMoriah.Waterland@Sun.COM 
161*9781SMoriah.Waterland@Sun.COM 		/* If install_root is '/' then it's trivial. */
162*9781SMoriah.Waterland@Sun.COM 		if (install_root_len == 1)
163*9781SMoriah.Waterland@Sun.COM 			install_root_len = 0;
164*9781SMoriah.Waterland@Sun.COM 		else
165*9781SMoriah.Waterland@Sun.COM 			z_set_zone_root(install_root);
166*9781SMoriah.Waterland@Sun.COM 	} else
167*9781SMoriah.Waterland@Sun.COM 		install_root_exists = 0;
168*9781SMoriah.Waterland@Sun.COM 
169*9781SMoriah.Waterland@Sun.COM 	return (1);
170*9781SMoriah.Waterland@Sun.COM }
171*9781SMoriah.Waterland@Sun.COM 
172*9781SMoriah.Waterland@Sun.COM /*
173*9781SMoriah.Waterland@Sun.COM  * This routine returns a path with the correct install_root prepended.
174*9781SMoriah.Waterland@Sun.COM  * if the install_root has been set. NOTE : this allocates memory
175*9781SMoriah.Waterland@Sun.COM  * which will need to be freed at some point.
176*9781SMoriah.Waterland@Sun.COM  */
177*9781SMoriah.Waterland@Sun.COM char *
fixpath(char * path)178*9781SMoriah.Waterland@Sun.COM fixpath(char *path)
179*9781SMoriah.Waterland@Sun.COM {
180*9781SMoriah.Waterland@Sun.COM 	register char *npath_ptr, *ir_ptr;
181*9781SMoriah.Waterland@Sun.COM 	char *npath = NULL;
182*9781SMoriah.Waterland@Sun.COM 
183*9781SMoriah.Waterland@Sun.COM 	if (path && *path) {
184*9781SMoriah.Waterland@Sun.COM 		if (install_root_exists) {
185*9781SMoriah.Waterland@Sun.COM 			if ((npath =
186*9781SMoriah.Waterland@Sun.COM 			    calloc(1, strlen(path) + install_root_len +
187*9781SMoriah.Waterland@Sun.COM 			    1)) == NULL) {
188*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_ALLOCFAILED), "fixpath()");
189*9781SMoriah.Waterland@Sun.COM 				quit(99);
190*9781SMoriah.Waterland@Sun.COM 			}
191*9781SMoriah.Waterland@Sun.COM 
192*9781SMoriah.Waterland@Sun.COM 			npath_ptr = npath;
193*9781SMoriah.Waterland@Sun.COM 			ir_ptr = get_inst_root();
194*9781SMoriah.Waterland@Sun.COM 
195*9781SMoriah.Waterland@Sun.COM 			while (*ir_ptr)	/* for every char in install_root */
196*9781SMoriah.Waterland@Sun.COM 				*npath_ptr++ = *ir_ptr++;	/* copy it */
197*9781SMoriah.Waterland@Sun.COM 
198*9781SMoriah.Waterland@Sun.COM 			/*
199*9781SMoriah.Waterland@Sun.COM 			 * If install_root == "/", a concatenation will
200*9781SMoriah.Waterland@Sun.COM 			 * result in a return value of "//...", same goes
201*9781SMoriah.Waterland@Sun.COM 			 * for an install_root ending in '/'. So we back
202*9781SMoriah.Waterland@Sun.COM 			 * over a trailing '/' if it's there.
203*9781SMoriah.Waterland@Sun.COM 			 */
204*9781SMoriah.Waterland@Sun.COM 			if (*(npath_ptr - 1) == '/')
205*9781SMoriah.Waterland@Sun.COM 				npath_ptr--;
206*9781SMoriah.Waterland@Sun.COM 
207*9781SMoriah.Waterland@Sun.COM 			if (strcmp(path, "/"))
208*9781SMoriah.Waterland@Sun.COM 				(void) strcpy(npath_ptr, path);
209*9781SMoriah.Waterland@Sun.COM 		} else
210*9781SMoriah.Waterland@Sun.COM 			/*
211*9781SMoriah.Waterland@Sun.COM 			 * If there's no install root & no client_basedir,
212*9781SMoriah.Waterland@Sun.COM 			 * then return the path
213*9781SMoriah.Waterland@Sun.COM 			 */
214*9781SMoriah.Waterland@Sun.COM 			npath = strdup(path);
215*9781SMoriah.Waterland@Sun.COM 	} else
216*9781SMoriah.Waterland@Sun.COM 		/*
217*9781SMoriah.Waterland@Sun.COM 		 * If there's no path specified, return the install root
218*9781SMoriah.Waterland@Sun.COM 		 * since no matter what happens, this is where the
219*9781SMoriah.Waterland@Sun.COM 		 * path will have to start.
220*9781SMoriah.Waterland@Sun.COM 		 */
221*9781SMoriah.Waterland@Sun.COM 		if (install_root_exists)
222*9781SMoriah.Waterland@Sun.COM 			npath = strdup(get_inst_root());
223*9781SMoriah.Waterland@Sun.COM 
224*9781SMoriah.Waterland@Sun.COM 	return (npath);
225*9781SMoriah.Waterland@Sun.COM }
226*9781SMoriah.Waterland@Sun.COM 
227*9781SMoriah.Waterland@Sun.COM /*
228*9781SMoriah.Waterland@Sun.COM  * This routine does what fixpath() does except it's for high-volume
229*9781SMoriah.Waterland@Sun.COM  * stuff restricted to the instvol() function. By using
230*9781SMoriah.Waterland@Sun.COM  * pathdup() and pathalloc() memory fragmentation is reduced. Also, the
231*9781SMoriah.Waterland@Sun.COM  * memory allocated by pathdup() and pathalloc() gets freed at the end
232*9781SMoriah.Waterland@Sun.COM  * of each volume installed.
233*9781SMoriah.Waterland@Sun.COM  */
234*9781SMoriah.Waterland@Sun.COM char *
fixpath_dup(char * path)235*9781SMoriah.Waterland@Sun.COM fixpath_dup(char *path)
236*9781SMoriah.Waterland@Sun.COM {
237*9781SMoriah.Waterland@Sun.COM 	register char *npath_ptr, *ir_ptr;
238*9781SMoriah.Waterland@Sun.COM 	char *npath = NULL;
239*9781SMoriah.Waterland@Sun.COM 
240*9781SMoriah.Waterland@Sun.COM 	if (path && *path) {
241*9781SMoriah.Waterland@Sun.COM 		if (install_root_exists) {
242*9781SMoriah.Waterland@Sun.COM 			npath = pathalloc(strlen(path) + install_root_len + 1);
243*9781SMoriah.Waterland@Sun.COM 
244*9781SMoriah.Waterland@Sun.COM 			npath_ptr = npath;
245*9781SMoriah.Waterland@Sun.COM 			ir_ptr = get_inst_root();
246*9781SMoriah.Waterland@Sun.COM 
247*9781SMoriah.Waterland@Sun.COM 			while (*ir_ptr)	/* for every char in install_root */
248*9781SMoriah.Waterland@Sun.COM 				*npath_ptr++ = *ir_ptr++;	/* copy it */
249*9781SMoriah.Waterland@Sun.COM 
250*9781SMoriah.Waterland@Sun.COM 			/*
251*9781SMoriah.Waterland@Sun.COM 			 * If install_root == "/", a concatenation will
252*9781SMoriah.Waterland@Sun.COM 			 * result in a return value of "//...", same goes
253*9781SMoriah.Waterland@Sun.COM 			 * for an install_root ending in '/'. So we back
254*9781SMoriah.Waterland@Sun.COM 			 * over a trailing '/' if it's there.
255*9781SMoriah.Waterland@Sun.COM 			 */
256*9781SMoriah.Waterland@Sun.COM 			if (*(npath_ptr - 1) == '/')
257*9781SMoriah.Waterland@Sun.COM 				npath_ptr--;
258*9781SMoriah.Waterland@Sun.COM 
259*9781SMoriah.Waterland@Sun.COM 			if (strcmp(path, "/"))
260*9781SMoriah.Waterland@Sun.COM 				(void) strcpy(npath_ptr, path);
261*9781SMoriah.Waterland@Sun.COM 		} else
262*9781SMoriah.Waterland@Sun.COM 			/*
263*9781SMoriah.Waterland@Sun.COM 			 * If there's no install root & no client_basedir,
264*9781SMoriah.Waterland@Sun.COM 			 * then return the path
265*9781SMoriah.Waterland@Sun.COM 			 */
266*9781SMoriah.Waterland@Sun.COM 			npath = pathdup(path);
267*9781SMoriah.Waterland@Sun.COM 	} else
268*9781SMoriah.Waterland@Sun.COM 		/*
269*9781SMoriah.Waterland@Sun.COM 		 * If there's no path specified, return the install root
270*9781SMoriah.Waterland@Sun.COM 		 * since no matter what happens, this is where the
271*9781SMoriah.Waterland@Sun.COM 		 * path will have to start.
272*9781SMoriah.Waterland@Sun.COM 		 */
273*9781SMoriah.Waterland@Sun.COM 		if (install_root_exists)
274*9781SMoriah.Waterland@Sun.COM 			npath = pathdup(get_inst_root());
275*9781SMoriah.Waterland@Sun.COM 
276*9781SMoriah.Waterland@Sun.COM 	return (npath);
277*9781SMoriah.Waterland@Sun.COM }
278*9781SMoriah.Waterland@Sun.COM 
279*9781SMoriah.Waterland@Sun.COM /*
280*9781SMoriah.Waterland@Sun.COM  * This returns a pointer to a static name. This could be abused.
281*9781SMoriah.Waterland@Sun.COM  * -- JST (1993-07-21)
282*9781SMoriah.Waterland@Sun.COM  */
283*9781SMoriah.Waterland@Sun.COM char *
get_inst_root(void)284*9781SMoriah.Waterland@Sun.COM get_inst_root(void)
285*9781SMoriah.Waterland@Sun.COM {
286*9781SMoriah.Waterland@Sun.COM 	ir_accessed = 1;	/* we can't change it now */
287*9781SMoriah.Waterland@Sun.COM 	return (install_root);
288*9781SMoriah.Waterland@Sun.COM }
289*9781SMoriah.Waterland@Sun.COM 
290*9781SMoriah.Waterland@Sun.COM /*
291*9781SMoriah.Waterland@Sun.COM  * This routine takes path and removes install_root from the path
292*9781SMoriah.Waterland@Sun.COM  * if it has already been prepended. If install_root is not prepended to
293*9781SMoriah.Waterland@Sun.COM  * path or install_root is '/' or path == NULL then path is returned
294*9781SMoriah.Waterland@Sun.COM  * as is. If the resulting path is somehow relative, a corrupt
295*9781SMoriah.Waterland@Sun.COM  * package name error is raised and the program quits. NOTE : This
296*9781SMoriah.Waterland@Sun.COM  * function usually returns a pointer into the original path
297*9781SMoriah.Waterland@Sun.COM  * argument. It doesn't allocate new memory. This is possible,
298*9781SMoriah.Waterland@Sun.COM  * of course, because the path being returned is guaranteed to
299*9781SMoriah.Waterland@Sun.COM  * be a subset of the original argument unless basedir = '/' in
300*9781SMoriah.Waterland@Sun.COM  * which case a pointer to a static "/" is returned. See
301*9781SMoriah.Waterland@Sun.COM  * orig_path() below if you want to be handed a new copy of the
302*9781SMoriah.Waterland@Sun.COM  * return value.
303*9781SMoriah.Waterland@Sun.COM  */
304*9781SMoriah.Waterland@Sun.COM char *
orig_path_ptr(char * path)305*9781SMoriah.Waterland@Sun.COM orig_path_ptr(char *path)
306*9781SMoriah.Waterland@Sun.COM {
307*9781SMoriah.Waterland@Sun.COM 	char *retv = NULL;
308*9781SMoriah.Waterland@Sun.COM 
309*9781SMoriah.Waterland@Sun.COM 	if (path && *path) {	/* as long as we got an argument */
310*9781SMoriah.Waterland@Sun.COM 		if (!install_root_exists)	/* if no install_root */
311*9781SMoriah.Waterland@Sun.COM 			retv = path;		/*   path unchanged */
312*9781SMoriah.Waterland@Sun.COM 
313*9781SMoriah.Waterland@Sun.COM 		/*
314*9781SMoriah.Waterland@Sun.COM 		 * Otherwise, if install_root is really prepended to the path
315*9781SMoriah.Waterland@Sun.COM 		 * then remove it dealing appropriately with special cases.
316*9781SMoriah.Waterland@Sun.COM 		 */
317*9781SMoriah.Waterland@Sun.COM 		else if (strncmp(path, install_root, install_root_len) == 0) {
318*9781SMoriah.Waterland@Sun.COM 			retv = path + install_root_len;
319*9781SMoriah.Waterland@Sun.COM 			if (*retv == NULL)
320*9781SMoriah.Waterland@Sun.COM 				retv = "/";
321*9781SMoriah.Waterland@Sun.COM 
322*9781SMoriah.Waterland@Sun.COM 			/*
323*9781SMoriah.Waterland@Sun.COM 			 * The result will be relative if install_root = '/'.
324*9781SMoriah.Waterland@Sun.COM 			 * If the basedir path was built legally, then moving
325*9781SMoriah.Waterland@Sun.COM 			 * the pointer back one character will make it
326*9781SMoriah.Waterland@Sun.COM 			 * absolute. If that fails then the path we got was
327*9781SMoriah.Waterland@Sun.COM 			 * incorrectly constructed in the first place.
328*9781SMoriah.Waterland@Sun.COM 			 */
329*9781SMoriah.Waterland@Sun.COM 			else if (*retv != '/') {
330*9781SMoriah.Waterland@Sun.COM 				retv--;
331*9781SMoriah.Waterland@Sun.COM 				if (*retv != '/') {
332*9781SMoriah.Waterland@Sun.COM 					progerr(gettext(ERR_PATHNAME));
333*9781SMoriah.Waterland@Sun.COM 					quit(99);
334*9781SMoriah.Waterland@Sun.COM 				}
335*9781SMoriah.Waterland@Sun.COM 			}
336*9781SMoriah.Waterland@Sun.COM 		} else
337*9781SMoriah.Waterland@Sun.COM 			retv = path;	/* All else failing, return path. */
338*9781SMoriah.Waterland@Sun.COM 
339*9781SMoriah.Waterland@Sun.COM 		canonize(retv);
340*9781SMoriah.Waterland@Sun.COM 	}
341*9781SMoriah.Waterland@Sun.COM 
342*9781SMoriah.Waterland@Sun.COM 	return (retv);
343*9781SMoriah.Waterland@Sun.COM }
344*9781SMoriah.Waterland@Sun.COM 
345*9781SMoriah.Waterland@Sun.COM /*
346*9781SMoriah.Waterland@Sun.COM  * This function does the same as orig_path_ptr() except that it mallocs
347*9781SMoriah.Waterland@Sun.COM  * new space and provides a new copy of the original basedir path which
348*9781SMoriah.Waterland@Sun.COM  * needs to be free()'d one way or another later.
349*9781SMoriah.Waterland@Sun.COM  */
350*9781SMoriah.Waterland@Sun.COM char *
orig_path(char * path)351*9781SMoriah.Waterland@Sun.COM orig_path(char *path)
352*9781SMoriah.Waterland@Sun.COM {
353*9781SMoriah.Waterland@Sun.COM 	char *retv;
354*9781SMoriah.Waterland@Sun.COM 
355*9781SMoriah.Waterland@Sun.COM 	retv = orig_path_ptr(path);
356*9781SMoriah.Waterland@Sun.COM 
357*9781SMoriah.Waterland@Sun.COM 	return ((retv == NULL) ? retv : strdup(retv));
358*9781SMoriah.Waterland@Sun.COM }
359*9781SMoriah.Waterland@Sun.COM 
360*9781SMoriah.Waterland@Sun.COM /*
361*9781SMoriah.Waterland@Sun.COM  * This function lets us hold onto the environment's version of
362*9781SMoriah.Waterland@Sun.COM  * CLIENT_BASEDIR for later review by set_client_basedir().
363*9781SMoriah.Waterland@Sun.COM  */
364*9781SMoriah.Waterland@Sun.COM void
set_env_cbdir()365*9781SMoriah.Waterland@Sun.COM set_env_cbdir()
366*9781SMoriah.Waterland@Sun.COM {
367*9781SMoriah.Waterland@Sun.COM 	register char *cb_ptr;
368*9781SMoriah.Waterland@Sun.COM 
369*9781SMoriah.Waterland@Sun.COM 	cb_ptr = getenv("CLIENT_BASEDIR");
370*9781SMoriah.Waterland@Sun.COM 
371*9781SMoriah.Waterland@Sun.COM 	if (cb_ptr && *cb_ptr) {
372*9781SMoriah.Waterland@Sun.COM 		env_cl_bdir = strdup(cb_ptr);
373*9781SMoriah.Waterland@Sun.COM 		canonize(env_cl_bdir);
374*9781SMoriah.Waterland@Sun.COM 	}
375*9781SMoriah.Waterland@Sun.COM }
376*9781SMoriah.Waterland@Sun.COM 
377*9781SMoriah.Waterland@Sun.COM /* ask for the basedir */
378*9781SMoriah.Waterland@Sun.COM static int
ask_basedir(char * path,int nointeract)379*9781SMoriah.Waterland@Sun.COM ask_basedir(char *path, int nointeract)
380*9781SMoriah.Waterland@Sun.COM {
381*9781SMoriah.Waterland@Sun.COM 	int n;
382*9781SMoriah.Waterland@Sun.COM 
383*9781SMoriah.Waterland@Sun.COM 	if (nointeract) {
384*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(MSG_REQBASEDIR));
385*9781SMoriah.Waterland@Sun.COM 		return (5);
386*9781SMoriah.Waterland@Sun.COM 	} else {
387*9781SMoriah.Waterland@Sun.COM 		path[0] = '\0';
388*9781SMoriah.Waterland@Sun.COM 		if (n = ckpath(path, P_ABSOLUTE|P_DIR|P_WRITE,
389*9781SMoriah.Waterland@Sun.COM 		    basedir, NULL, gettext(MSG_HELP),
390*9781SMoriah.Waterland@Sun.COM 		    gettext(MSG_PROMPT)))
391*9781SMoriah.Waterland@Sun.COM 			return (n);	/* FAIL */
392*9781SMoriah.Waterland@Sun.COM 		orig_basedir =
393*9781SMoriah.Waterland@Sun.COM 		    expand_path(path);
394*9781SMoriah.Waterland@Sun.COM 	}
395*9781SMoriah.Waterland@Sun.COM 	return (0);
396*9781SMoriah.Waterland@Sun.COM }
397*9781SMoriah.Waterland@Sun.COM 
398*9781SMoriah.Waterland@Sun.COM /*
399*9781SMoriah.Waterland@Sun.COM  * Set the basedir and client_basedir based on install root and config
400*9781SMoriah.Waterland@Sun.COM  * files. It returns 0 if all OK otherwise returns the error code base
401*9781SMoriah.Waterland@Sun.COM  * appropriate to the problem.
402*9781SMoriah.Waterland@Sun.COM  */
403*9781SMoriah.Waterland@Sun.COM int
set_basedirs(int reloc,char * adm_basedir,char * pkginst,int nointeract)404*9781SMoriah.Waterland@Sun.COM set_basedirs(int reloc, char *adm_basedir, char *pkginst, int nointeract)
405*9781SMoriah.Waterland@Sun.COM {
406*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
407*9781SMoriah.Waterland@Sun.COM 	int	n;
408*9781SMoriah.Waterland@Sun.COM 
409*9781SMoriah.Waterland@Sun.COM 	relocatable = reloc;
410*9781SMoriah.Waterland@Sun.COM 
411*9781SMoriah.Waterland@Sun.COM 	/*
412*9781SMoriah.Waterland@Sun.COM 	 * If there are no relocatable files basedir is probably meaningless
413*9781SMoriah.Waterland@Sun.COM 	 * so we skip ahead to the simple tests. Otherwise we do the twisted
414*9781SMoriah.Waterland@Sun.COM 	 * stuff below. The BASEDIR is set based on the following heirarchy :
415*9781SMoriah.Waterland@Sun.COM 	 *	1. The entry in the admin file
416*9781SMoriah.Waterland@Sun.COM 	 *	2. The entry in the pkginfo file delivered on the medium
417*9781SMoriah.Waterland@Sun.COM 	 *	3. The entry in the already installed pkginfo file
418*9781SMoriah.Waterland@Sun.COM 	 *	4. ask
419*9781SMoriah.Waterland@Sun.COM 	 * If it's not a relocatable package, we go with whatever seems
420*9781SMoriah.Waterland@Sun.COM 	 * reasonable; if it's relocatable and we've exhausted our
421*9781SMoriah.Waterland@Sun.COM 	 * options, we ask.
422*9781SMoriah.Waterland@Sun.COM 	 */
423*9781SMoriah.Waterland@Sun.COM 	if (reloc) {
424*9781SMoriah.Waterland@Sun.COM 		int is_adm_basedir = (adm_basedir && *adm_basedir);
425*9781SMoriah.Waterland@Sun.COM 		int is_update = 0;
426*9781SMoriah.Waterland@Sun.COM 		int is_ask = 0;
427*9781SMoriah.Waterland@Sun.COM 
428*9781SMoriah.Waterland@Sun.COM 		if (is_adm_basedir) {
429*9781SMoriah.Waterland@Sun.COM 			if (strcmp(adm_basedir, "update") == 0) {
430*9781SMoriah.Waterland@Sun.COM 				is_update = 1;
431*9781SMoriah.Waterland@Sun.COM 				is_ask = 1;
432*9781SMoriah.Waterland@Sun.COM 			} else if (strcmp(adm_basedir, "ask") == 0)
433*9781SMoriah.Waterland@Sun.COM 				is_ask = 1;
434*9781SMoriah.Waterland@Sun.COM 		}
435*9781SMoriah.Waterland@Sun.COM 
436*9781SMoriah.Waterland@Sun.COM 		/*
437*9781SMoriah.Waterland@Sun.COM 		 * If there's a BASEDIR in the admin file & it's a valid
438*9781SMoriah.Waterland@Sun.COM 		 * absolute pathname, use it.
439*9781SMoriah.Waterland@Sun.COM 		 */
440*9781SMoriah.Waterland@Sun.COM 		if (is_adm_basedir && strchr("/$", *adm_basedir))
441*9781SMoriah.Waterland@Sun.COM 			orig_basedir = expand_path(adm_basedir);
442*9781SMoriah.Waterland@Sun.COM 
443*9781SMoriah.Waterland@Sun.COM 		/* If admin says 'ask regardless', ask and continue */
444*9781SMoriah.Waterland@Sun.COM 		else if (is_adm_basedir && is_ask) {
445*9781SMoriah.Waterland@Sun.COM 			if (n = ask_basedir(path, nointeract))
446*9781SMoriah.Waterland@Sun.COM 				return (n);
447*9781SMoriah.Waterland@Sun.COM 			if (is_update &&
448*9781SMoriah.Waterland@Sun.COM 			    strcmp(orig_basedir,
449*9781SMoriah.Waterland@Sun.COM 			    (basedir = getenv("BASEDIR"))) != 0) {
450*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_ASKBD),
451*9781SMoriah.Waterland@Sun.COM 				    getenv("PKG"), basedir, orig_basedir);
452*9781SMoriah.Waterland@Sun.COM 				quit(4);
453*9781SMoriah.Waterland@Sun.COM 			}
454*9781SMoriah.Waterland@Sun.COM 		}
455*9781SMoriah.Waterland@Sun.COM 		/*
456*9781SMoriah.Waterland@Sun.COM 		 * If it isn't the only other valid option,
457*9781SMoriah.Waterland@Sun.COM 		 * namely 'default', quit FAIL.
458*9781SMoriah.Waterland@Sun.COM 		 */
459*9781SMoriah.Waterland@Sun.COM 		else if (is_adm_basedir &&
460*9781SMoriah.Waterland@Sun.COM 		    strcmp(adm_basedir, "default") != 0) {
461*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_ADMIN_INVAL));
462*9781SMoriah.Waterland@Sun.COM 			return (1);
463*9781SMoriah.Waterland@Sun.COM 
464*9781SMoriah.Waterland@Sun.COM 		/*
465*9781SMoriah.Waterland@Sun.COM 		 * OK, the admin file has no preference, so we go to the
466*9781SMoriah.Waterland@Sun.COM 		 * other sources.
467*9781SMoriah.Waterland@Sun.COM 		 */
468*9781SMoriah.Waterland@Sun.COM 		} else {
469*9781SMoriah.Waterland@Sun.COM 			/*
470*9781SMoriah.Waterland@Sun.COM 			 * Check to see if BASEDIR is set in the environment
471*9781SMoriah.Waterland@Sun.COM 			 * (probably from the pkginfo file on the installation
472*9781SMoriah.Waterland@Sun.COM 			 * medium).
473*9781SMoriah.Waterland@Sun.COM 			 */
474*9781SMoriah.Waterland@Sun.COM 			basedir = getenv("BASEDIR");
475*9781SMoriah.Waterland@Sun.COM 			if (basedir && *basedir)
476*9781SMoriah.Waterland@Sun.COM 				orig_basedir = expand_path(basedir);
477*9781SMoriah.Waterland@Sun.COM 			else {
478*9781SMoriah.Waterland@Sun.COM 				/*
479*9781SMoriah.Waterland@Sun.COM 				 * Check to see if the package BASEDIR was
480*9781SMoriah.Waterland@Sun.COM 				 * already defined during a previous
481*9781SMoriah.Waterland@Sun.COM 				 * installation of this package instance. The
482*9781SMoriah.Waterland@Sun.COM 				 * function below looks for an installed
483*9781SMoriah.Waterland@Sun.COM 				 * pkginfo file and scans it.
484*9781SMoriah.Waterland@Sun.COM 				 */
485*9781SMoriah.Waterland@Sun.COM 				basedir = pkgparam(pkginst, "BASEDIR");
486*9781SMoriah.Waterland@Sun.COM 				if (basedir && *basedir)
487*9781SMoriah.Waterland@Sun.COM 					orig_basedir = expand_path(basedir);
488*9781SMoriah.Waterland@Sun.COM 				else if (n = ask_basedir(path, nointeract))
489*9781SMoriah.Waterland@Sun.COM 					return (n);
490*9781SMoriah.Waterland@Sun.COM 			}
491*9781SMoriah.Waterland@Sun.COM 		}
492*9781SMoriah.Waterland@Sun.COM 	} else {	/* not relocatable */
493*9781SMoriah.Waterland@Sun.COM 		/*
494*9781SMoriah.Waterland@Sun.COM 		 * Since all paths are absolute the only reason to have a
495*9781SMoriah.Waterland@Sun.COM 		 * basedir is if there's an install root meaning there's
496*9781SMoriah.Waterland@Sun.COM 		 * really a basedir relative to this host or this package is
497*9781SMoriah.Waterland@Sun.COM 		 * absolute only because it's sparse in which case we're
498*9781SMoriah.Waterland@Sun.COM 		 * interested in the prior basedir. So we next check for a
499*9781SMoriah.Waterland@Sun.COM 		 * prior basedir and then an install root.
500*9781SMoriah.Waterland@Sun.COM 		 */
501*9781SMoriah.Waterland@Sun.COM 		basedir = pkgparam(pkginst, "BASEDIR");
502*9781SMoriah.Waterland@Sun.COM 		if (basedir && *basedir)
503*9781SMoriah.Waterland@Sun.COM 			orig_basedir = expand_path(basedir);
504*9781SMoriah.Waterland@Sun.COM 
505*9781SMoriah.Waterland@Sun.COM 		else if (install_root_exists)
506*9781SMoriah.Waterland@Sun.COM 			/*
507*9781SMoriah.Waterland@Sun.COM 			 * If we have a basedir *only because*
508*9781SMoriah.Waterland@Sun.COM 			 * we have an install_root, we need to
509*9781SMoriah.Waterland@Sun.COM 			 * set orig_basedir to '/' to simplify
510*9781SMoriah.Waterland@Sun.COM 			 * later attempts to force
511*9781SMoriah.Waterland@Sun.COM 			 * client_basedir.
512*9781SMoriah.Waterland@Sun.COM 			 */
513*9781SMoriah.Waterland@Sun.COM 			orig_basedir = "/";
514*9781SMoriah.Waterland@Sun.COM 		else {
515*9781SMoriah.Waterland@Sun.COM 			eval_valid++;	/* we can run eval_path() now */
516*9781SMoriah.Waterland@Sun.COM 			return (0);	/* fixpath below unnecessary */
517*9781SMoriah.Waterland@Sun.COM 		}
518*9781SMoriah.Waterland@Sun.COM 	}
519*9781SMoriah.Waterland@Sun.COM 
520*9781SMoriah.Waterland@Sun.COM 	basedir_exists = 1;
521*9781SMoriah.Waterland@Sun.COM 
522*9781SMoriah.Waterland@Sun.COM 	basedir = fixpath(orig_basedir);
523*9781SMoriah.Waterland@Sun.COM 
524*9781SMoriah.Waterland@Sun.COM 	/*
525*9781SMoriah.Waterland@Sun.COM 	 * If basedir == "/" then there's no need for a "/" between
526*9781SMoriah.Waterland@Sun.COM 	 * it and the rest of the path.
527*9781SMoriah.Waterland@Sun.COM 	 */
528*9781SMoriah.Waterland@Sun.COM 	if (strcmp(basedir, "/") == 0)
529*9781SMoriah.Waterland@Sun.COM 		base_sepr = 0;
530*9781SMoriah.Waterland@Sun.COM 
531*9781SMoriah.Waterland@Sun.COM 	if (set_client_basedir() == 0) {
532*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NO_CL_BD));
533*9781SMoriah.Waterland@Sun.COM 		return (1);
534*9781SMoriah.Waterland@Sun.COM 	}
535*9781SMoriah.Waterland@Sun.COM 
536*9781SMoriah.Waterland@Sun.COM 	eval_valid++;	/* we've confirmed the validity of everything */
537*9781SMoriah.Waterland@Sun.COM 
538*9781SMoriah.Waterland@Sun.COM 	return (0);
539*9781SMoriah.Waterland@Sun.COM }
540*9781SMoriah.Waterland@Sun.COM 
541*9781SMoriah.Waterland@Sun.COM /*
542*9781SMoriah.Waterland@Sun.COM  * Make a directory from a path and all necessary directories above it as
543*9781SMoriah.Waterland@Sun.COM  * needed.
544*9781SMoriah.Waterland@Sun.COM  */
545*9781SMoriah.Waterland@Sun.COM int
mkpath(char * p)546*9781SMoriah.Waterland@Sun.COM mkpath(char *p)
547*9781SMoriah.Waterland@Sun.COM {
548*9781SMoriah.Waterland@Sun.COM 	char	*pt;
549*9781SMoriah.Waterland@Sun.COM 
550*9781SMoriah.Waterland@Sun.COM 	/* if entire path exists, return o.k. */
551*9781SMoriah.Waterland@Sun.COM 
552*9781SMoriah.Waterland@Sun.COM 	if (access(p, F_OK) == 0) {
553*9781SMoriah.Waterland@Sun.COM 		return (0);
554*9781SMoriah.Waterland@Sun.COM 	}
555*9781SMoriah.Waterland@Sun.COM 
556*9781SMoriah.Waterland@Sun.COM 	/* entire path not there - check components and create */
557*9781SMoriah.Waterland@Sun.COM 
558*9781SMoriah.Waterland@Sun.COM 	pt = (*p == '/') ? p+1 : p;
559*9781SMoriah.Waterland@Sun.COM 	do {
560*9781SMoriah.Waterland@Sun.COM 		if (pt = strchr(pt, '/')) {
561*9781SMoriah.Waterland@Sun.COM 			*pt = '\0';
562*9781SMoriah.Waterland@Sun.COM 		}
563*9781SMoriah.Waterland@Sun.COM 		if ((access(p, F_OK) != 0) && (mkdir(p, 0755) != 0)) {
564*9781SMoriah.Waterland@Sun.COM 			return (-1);
565*9781SMoriah.Waterland@Sun.COM 		}
566*9781SMoriah.Waterland@Sun.COM 		if (pt) {
567*9781SMoriah.Waterland@Sun.COM 			*pt++ = '/';
568*9781SMoriah.Waterland@Sun.COM 		}
569*9781SMoriah.Waterland@Sun.COM 	} while (pt);
570*9781SMoriah.Waterland@Sun.COM 
571*9781SMoriah.Waterland@Sun.COM 	return (0);
572*9781SMoriah.Waterland@Sun.COM }
573*9781SMoriah.Waterland@Sun.COM 
574*9781SMoriah.Waterland@Sun.COM /* This makes the required base directory if necessary */
575*9781SMoriah.Waterland@Sun.COM void
mkbasedir(int flag,char * basedir)576*9781SMoriah.Waterland@Sun.COM mkbasedir(int flag, char *basedir)
577*9781SMoriah.Waterland@Sun.COM {
578*9781SMoriah.Waterland@Sun.COM 	char	ans[MAX_INPUT];
579*9781SMoriah.Waterland@Sun.COM 	int	n;
580*9781SMoriah.Waterland@Sun.COM 
581*9781SMoriah.Waterland@Sun.COM 	/*
582*9781SMoriah.Waterland@Sun.COM 	 * If a base directory is called for but there's no such directory on
583*9781SMoriah.Waterland@Sun.COM 	 * the system, deal with that issue.
584*9781SMoriah.Waterland@Sun.COM 	 */
585*9781SMoriah.Waterland@Sun.COM 	if (is_a_basedir() && isdir(basedir)) {
586*9781SMoriah.Waterland@Sun.COM 		if (flag) {	/* Interaction is OK. */
587*9781SMoriah.Waterland@Sun.COM 			/*
588*9781SMoriah.Waterland@Sun.COM 			 * If there's a non-directory object in the way, ask.
589*9781SMoriah.Waterland@Sun.COM 			 */
590*9781SMoriah.Waterland@Sun.COM 			if (access(basedir, F_OK) == 0) {
591*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(MSG_ISAFILE), basedir);
592*9781SMoriah.Waterland@Sun.COM 
593*9781SMoriah.Waterland@Sun.COM 				if (n = ckyorn(ans, NULL, NULL, NULL,
594*9781SMoriah.Waterland@Sun.COM 				    gettext(MSG_YORNFILE)))
595*9781SMoriah.Waterland@Sun.COM 					quit(n);
596*9781SMoriah.Waterland@Sun.COM 				if (strchr("yY", *ans) == NULL)
597*9781SMoriah.Waterland@Sun.COM 					quit(3);
598*9781SMoriah.Waterland@Sun.COM 
599*9781SMoriah.Waterland@Sun.COM 				/*
600*9781SMoriah.Waterland@Sun.COM 				 * It isn't a directory, so we'll just unlink
601*9781SMoriah.Waterland@Sun.COM 				 * it.
602*9781SMoriah.Waterland@Sun.COM 				 */
603*9781SMoriah.Waterland@Sun.COM 				if (unlink(basedir) == -1) {
604*9781SMoriah.Waterland@Sun.COM 					progerr(gettext(ERR_NODELETE),
605*9781SMoriah.Waterland@Sun.COM 					    basedir);
606*9781SMoriah.Waterland@Sun.COM 					quit(99);
607*9781SMoriah.Waterland@Sun.COM 				}
608*9781SMoriah.Waterland@Sun.COM 
609*9781SMoriah.Waterland@Sun.COM 			} else {
610*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(MSG_MUSTEXIST), basedir);
611*9781SMoriah.Waterland@Sun.COM 
612*9781SMoriah.Waterland@Sun.COM 				if (n = ckyorn(ans, NULL, NULL, NULL,
613*9781SMoriah.Waterland@Sun.COM 				    gettext(MSG_YORNPRMPT)))
614*9781SMoriah.Waterland@Sun.COM 					quit(n);
615*9781SMoriah.Waterland@Sun.COM 				if (strchr("yY", *ans) == NULL)
616*9781SMoriah.Waterland@Sun.COM 					quit(3);
617*9781SMoriah.Waterland@Sun.COM 			}
618*9781SMoriah.Waterland@Sun.COM 		}
619*9781SMoriah.Waterland@Sun.COM 
620*9781SMoriah.Waterland@Sun.COM 		if (access(basedir, F_OK) == 0 || mkpath(basedir)) {
621*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MKBASE), basedir);
622*9781SMoriah.Waterland@Sun.COM 			quit(99);
623*9781SMoriah.Waterland@Sun.COM 		}
624*9781SMoriah.Waterland@Sun.COM 	}
625*9781SMoriah.Waterland@Sun.COM }
626*9781SMoriah.Waterland@Sun.COM 
627*9781SMoriah.Waterland@Sun.COM /*
628*9781SMoriah.Waterland@Sun.COM  * Create a client_basedir if it is appropriate. If all goes well, resulting
629*9781SMoriah.Waterland@Sun.COM  * in either a valid client_basedir or a valid lack thereof, it returns 1.
630*9781SMoriah.Waterland@Sun.COM  * If there is an irreconcileable conflict, it returns 0.
631*9781SMoriah.Waterland@Sun.COM  */
632*9781SMoriah.Waterland@Sun.COM static int
set_client_basedir(void)633*9781SMoriah.Waterland@Sun.COM set_client_basedir(void)
634*9781SMoriah.Waterland@Sun.COM {
635*9781SMoriah.Waterland@Sun.COM 	if (install_root_exists) {
636*9781SMoriah.Waterland@Sun.COM 		if (basedir_exists)
637*9781SMoriah.Waterland@Sun.COM 			client_basedir = strdup(orig_basedir);
638*9781SMoriah.Waterland@Sun.COM 		else
639*9781SMoriah.Waterland@Sun.COM 			client_basedir = "/";
640*9781SMoriah.Waterland@Sun.COM 		client_basedir_exists = 1;
641*9781SMoriah.Waterland@Sun.COM 	}
642*9781SMoriah.Waterland@Sun.COM 
643*9781SMoriah.Waterland@Sun.COM 	/*
644*9781SMoriah.Waterland@Sun.COM 	 * In response to an agreement associated with bug report #1133956,
645*9781SMoriah.Waterland@Sun.COM 	 * CLIENT_BASEDIR will be defined in all cases where BASEDIR is
646*9781SMoriah.Waterland@Sun.COM 	 * defined until the on1094 release. For on1094 delete the else if
647*9781SMoriah.Waterland@Sun.COM 	 * and associated expressions below. -- JST (6/25/1993)
648*9781SMoriah.Waterland@Sun.COM 	 */
649*9781SMoriah.Waterland@Sun.COM 	else if (basedir_exists) {
650*9781SMoriah.Waterland@Sun.COM 		client_basedir = strdup(basedir);
651*9781SMoriah.Waterland@Sun.COM 		client_basedir_exists = 1;
652*9781SMoriah.Waterland@Sun.COM 	}
653*9781SMoriah.Waterland@Sun.COM 
654*9781SMoriah.Waterland@Sun.COM 	/*
655*9781SMoriah.Waterland@Sun.COM 	 * At this point we may or may not have a client_basedir defined. Now
656*9781SMoriah.Waterland@Sun.COM 	 * we need to check for one in the environment & make sure it syncs
657*9781SMoriah.Waterland@Sun.COM 	 * up with prior findings. If there's no other client_basedir defined,
658*9781SMoriah.Waterland@Sun.COM 	 * the environment defines it.
659*9781SMoriah.Waterland@Sun.COM 	 */
660*9781SMoriah.Waterland@Sun.COM 	if (env_cl_bdir && *env_cl_bdir) {
661*9781SMoriah.Waterland@Sun.COM 		if (client_basedir_exists) {
662*9781SMoriah.Waterland@Sun.COM 			/* If the two client basedirs mismatch, return fail */
663*9781SMoriah.Waterland@Sun.COM 			if (strcmp(client_basedir, env_cl_bdir)) {
664*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(ERR_CL_MIS),
665*9781SMoriah.Waterland@Sun.COM 				    client_basedir, env_cl_bdir);
666*9781SMoriah.Waterland@Sun.COM 				return (0);
667*9781SMoriah.Waterland@Sun.COM 			}
668*9781SMoriah.Waterland@Sun.COM 		} else {
669*9781SMoriah.Waterland@Sun.COM 			client_basedir = env_cl_bdir;
670*9781SMoriah.Waterland@Sun.COM 			client_basedir_exists = 1;
671*9781SMoriah.Waterland@Sun.COM 		}
672*9781SMoriah.Waterland@Sun.COM 	}
673*9781SMoriah.Waterland@Sun.COM 
674*9781SMoriah.Waterland@Sun.COM 	return (1);
675*9781SMoriah.Waterland@Sun.COM }
676*9781SMoriah.Waterland@Sun.COM 
677*9781SMoriah.Waterland@Sun.COM static char *
expand_path(char * path)678*9781SMoriah.Waterland@Sun.COM expand_path(char *path)
679*9781SMoriah.Waterland@Sun.COM {
680*9781SMoriah.Waterland@Sun.COM 	char	path_buf[PATH_MAX];
681*9781SMoriah.Waterland@Sun.COM 
682*9781SMoriah.Waterland@Sun.COM 	if (!path || !*path)
683*9781SMoriah.Waterland@Sun.COM 		return (path);
684*9781SMoriah.Waterland@Sun.COM 
685*9781SMoriah.Waterland@Sun.COM 	(void) strlcpy(path_buf, path, sizeof (path_buf));
686*9781SMoriah.Waterland@Sun.COM 	mappath(getmapmode(), path_buf);
687*9781SMoriah.Waterland@Sun.COM 	canonize(path_buf);
688*9781SMoriah.Waterland@Sun.COM 
689*9781SMoriah.Waterland@Sun.COM 	return (qstrdup(path_buf));
690*9781SMoriah.Waterland@Sun.COM }
691*9781SMoriah.Waterland@Sun.COM 
692*9781SMoriah.Waterland@Sun.COM char *
get_basedir(void)693*9781SMoriah.Waterland@Sun.COM get_basedir(void)
694*9781SMoriah.Waterland@Sun.COM {
695*9781SMoriah.Waterland@Sun.COM 	return (basedir);
696*9781SMoriah.Waterland@Sun.COM }
697*9781SMoriah.Waterland@Sun.COM 
698*9781SMoriah.Waterland@Sun.COM char *
get_client_basedir(void)699*9781SMoriah.Waterland@Sun.COM get_client_basedir(void)
700*9781SMoriah.Waterland@Sun.COM {
701*9781SMoriah.Waterland@Sun.COM 	return (client_basedir);
702*9781SMoriah.Waterland@Sun.COM }
703*9781SMoriah.Waterland@Sun.COM 
704*9781SMoriah.Waterland@Sun.COM /*
705*9781SMoriah.Waterland@Sun.COM  * This function returns the basedir that is appropriate for this package's
706*9781SMoriah.Waterland@Sun.COM  * pkginfo file.
707*9781SMoriah.Waterland@Sun.COM  */
708*9781SMoriah.Waterland@Sun.COM char *
get_info_basedir(void)709*9781SMoriah.Waterland@Sun.COM get_info_basedir(void)
710*9781SMoriah.Waterland@Sun.COM {
711*9781SMoriah.Waterland@Sun.COM 	if (install_root_exists)
712*9781SMoriah.Waterland@Sun.COM 		return (client_basedir);
713*9781SMoriah.Waterland@Sun.COM 	else if (basedir_exists)
714*9781SMoriah.Waterland@Sun.COM 		return (basedir);
715*9781SMoriah.Waterland@Sun.COM 	else
716*9781SMoriah.Waterland@Sun.COM 		return (NULL);
717*9781SMoriah.Waterland@Sun.COM }
718*9781SMoriah.Waterland@Sun.COM 
719*9781SMoriah.Waterland@Sun.COM int
is_an_inst_root(void)720*9781SMoriah.Waterland@Sun.COM is_an_inst_root(void)
721*9781SMoriah.Waterland@Sun.COM {
722*9781SMoriah.Waterland@Sun.COM 	return (install_root_exists);
723*9781SMoriah.Waterland@Sun.COM }
724*9781SMoriah.Waterland@Sun.COM 
725*9781SMoriah.Waterland@Sun.COM int
is_a_basedir(void)726*9781SMoriah.Waterland@Sun.COM is_a_basedir(void)
727*9781SMoriah.Waterland@Sun.COM {
728*9781SMoriah.Waterland@Sun.COM 	return (basedir_exists);
729*9781SMoriah.Waterland@Sun.COM }
730*9781SMoriah.Waterland@Sun.COM 
731*9781SMoriah.Waterland@Sun.COM int
is_relocatable(void)732*9781SMoriah.Waterland@Sun.COM is_relocatable(void)
733*9781SMoriah.Waterland@Sun.COM {
734*9781SMoriah.Waterland@Sun.COM 	return (relocatable);
735*9781SMoriah.Waterland@Sun.COM }
736*9781SMoriah.Waterland@Sun.COM 
737*9781SMoriah.Waterland@Sun.COM int
is_a_cl_basedir(void)738*9781SMoriah.Waterland@Sun.COM is_a_cl_basedir(void)
739*9781SMoriah.Waterland@Sun.COM {
740*9781SMoriah.Waterland@Sun.COM 	return (client_basedir_exists);
741*9781SMoriah.Waterland@Sun.COM }
742*9781SMoriah.Waterland@Sun.COM 
743*9781SMoriah.Waterland@Sun.COM /*
744*9781SMoriah.Waterland@Sun.COM  * Since calls to putparam() become valid long after much of the above
745*9781SMoriah.Waterland@Sun.COM  * code has run, this routine allows the insertion of these key
746*9781SMoriah.Waterland@Sun.COM  * environment variables without passing a bunch of pointers.
747*9781SMoriah.Waterland@Sun.COM  */
748*9781SMoriah.Waterland@Sun.COM void
put_path_params(void)749*9781SMoriah.Waterland@Sun.COM put_path_params(void)
750*9781SMoriah.Waterland@Sun.COM {
751*9781SMoriah.Waterland@Sun.COM 	if (install_root_exists)
752*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_INSTALL_ROOT", get_inst_root());
753*9781SMoriah.Waterland@Sun.COM 
754*9781SMoriah.Waterland@Sun.COM 	if (basedir_exists)
755*9781SMoriah.Waterland@Sun.COM 		putparam("BASEDIR", basedir);
756*9781SMoriah.Waterland@Sun.COM 
757*9781SMoriah.Waterland@Sun.COM 	if (client_basedir_exists)
758*9781SMoriah.Waterland@Sun.COM 		putparam("CLIENT_BASEDIR", client_basedir);
759*9781SMoriah.Waterland@Sun.COM }
760*9781SMoriah.Waterland@Sun.COM 
761*9781SMoriah.Waterland@Sun.COM /*
762*9781SMoriah.Waterland@Sun.COM  * This fills three pointers and a buffer which contains the longest
763*9781SMoriah.Waterland@Sun.COM  * possible path (with install_root and basedir prepended. The pointers
764*9781SMoriah.Waterland@Sun.COM  * are to the subpaths within the string. This was added so that the
765*9781SMoriah.Waterland@Sun.COM  * eptlist could be produced with all relevant paths defined without
766*9781SMoriah.Waterland@Sun.COM  * repeated calls and string scans. For example, given a path of
767*9781SMoriah.Waterland@Sun.COM  * haberdasher/crute we may return
768*9781SMoriah.Waterland@Sun.COM  *
769*9781SMoriah.Waterland@Sun.COM  *	server_ptr -----> /export/root/client1/opt/SUNWhab/haberdasher/crute
770*9781SMoriah.Waterland@Sun.COM  *                                            |            |
771*9781SMoriah.Waterland@Sun.COM  *	client_ptr ---------------------------             |
772*9781SMoriah.Waterland@Sun.COM  *	map_ptr -------------------------------------------
773*9781SMoriah.Waterland@Sun.COM  *
774*9781SMoriah.Waterland@Sun.COM  * We construct the new path based upon the established environment
775*9781SMoriah.Waterland@Sun.COM  * and the type of path that was passed. Here are the possibilities:
776*9781SMoriah.Waterland@Sun.COM  *
777*9781SMoriah.Waterland@Sun.COM  *   |					| relative path	| absolute path	|
778*9781SMoriah.Waterland@Sun.COM  *   |	--------------------------------|---------------|---------------|
779*9781SMoriah.Waterland@Sun.COM  *   |	is_an_inst_root			|	1	|	2	|
780*9781SMoriah.Waterland@Sun.COM  *   V	! an_inst_root && is_a_basedir	|	1	|	3	|
781*9781SMoriah.Waterland@Sun.COM  *	! an_inst_root && ! a_basedir	|	X	|	3	|
782*9781SMoriah.Waterland@Sun.COM  *
783*9781SMoriah.Waterland@Sun.COM  * METHOD
784*9781SMoriah.Waterland@Sun.COM  * 1. Prepend the basedir to the path (the basedir is guaranteed to exist
785*9781SMoriah.Waterland@Sun.COM  *	whenever there's an install_root).
786*9781SMoriah.Waterland@Sun.COM  *
787*9781SMoriah.Waterland@Sun.COM  * 2. Prepend the install_root (not the basedir) to the path
788*9781SMoriah.Waterland@Sun.COM  *
789*9781SMoriah.Waterland@Sun.COM  * 3. Return the path as unchanged.
790*9781SMoriah.Waterland@Sun.COM  *
791*9781SMoriah.Waterland@Sun.COM  * X. THIS CAN'T HAPPEN
792*9781SMoriah.Waterland@Sun.COM  */
793*9781SMoriah.Waterland@Sun.COM int
eval_path(char ** server_ptr,char ** client_ptr,char ** map_ptr,char * path)794*9781SMoriah.Waterland@Sun.COM eval_path(char **server_ptr, char **client_ptr, char **map_ptr, char *path)
795*9781SMoriah.Waterland@Sun.COM {
796*9781SMoriah.Waterland@Sun.COM 	static int client_offset;
797*9781SMoriah.Waterland@Sun.COM 	static int offsets_valid, retcode;
798*9781SMoriah.Waterland@Sun.COM 	int path_size;
799*9781SMoriah.Waterland@Sun.COM 
800*9781SMoriah.Waterland@Sun.COM 	if (!offsets_valid) {
801*9781SMoriah.Waterland@Sun.COM 		/*
802*9781SMoriah.Waterland@Sun.COM 		 * This is the offset from the beginning of the evaluated
803*9781SMoriah.Waterland@Sun.COM 		 * path to the start of the relative path. Note that we
804*9781SMoriah.Waterland@Sun.COM 		 * are accounting for the '/' inserted between the
805*9781SMoriah.Waterland@Sun.COM 		 * basedir and the path with the '+ 1'. If there is a
806*9781SMoriah.Waterland@Sun.COM 		 * relative path, then there is always a basedir. The
807*9781SMoriah.Waterland@Sun.COM 		 * only way this will come up '0' is if this is an
808*9781SMoriah.Waterland@Sun.COM 		 * absolute package.
809*9781SMoriah.Waterland@Sun.COM 		 */
810*9781SMoriah.Waterland@Sun.COM 		orig_offset_rel = (is_a_basedir()) ? (strlen(basedir) +
811*9781SMoriah.Waterland@Sun.COM 		    base_sepr) : 0;
812*9781SMoriah.Waterland@Sun.COM 
813*9781SMoriah.Waterland@Sun.COM 		/*
814*9781SMoriah.Waterland@Sun.COM 		 * This is the position of the client-relative path
815*9781SMoriah.Waterland@Sun.COM 		 * in that it points to the '/' beginning the base
816*9781SMoriah.Waterland@Sun.COM 		 * directory or the absolute path. Once the basedir has
817*9781SMoriah.Waterland@Sun.COM 		 * been afixed, the path is absolute. For that reason,
818*9781SMoriah.Waterland@Sun.COM 		 * the client path is the same thing as the original path
819*9781SMoriah.Waterland@Sun.COM 		 * if it were absolute.
820*9781SMoriah.Waterland@Sun.COM 		 */
821*9781SMoriah.Waterland@Sun.COM 		client_offset = (is_an_inst_root()) ? install_root_len : 0;
822*9781SMoriah.Waterland@Sun.COM 
823*9781SMoriah.Waterland@Sun.COM 		offsets_valid = 1;
824*9781SMoriah.Waterland@Sun.COM 	}
825*9781SMoriah.Waterland@Sun.COM 
826*9781SMoriah.Waterland@Sun.COM 	/*
827*9781SMoriah.Waterland@Sun.COM 	 * If we've evaluated the base directory and come up trumps,
828*9781SMoriah.Waterland@Sun.COM 	 * then we can procede with this operation, otherwise, the
829*9781SMoriah.Waterland@Sun.COM 	 * available data is too ambiguous to resolve the issue.
830*9781SMoriah.Waterland@Sun.COM 	 */
831*9781SMoriah.Waterland@Sun.COM 	if (eval_valid) {
832*9781SMoriah.Waterland@Sun.COM 		if (RELATIVE(path)) {
833*9781SMoriah.Waterland@Sun.COM 			if (relocatable) {
834*9781SMoriah.Waterland@Sun.COM 				/*
835*9781SMoriah.Waterland@Sun.COM 				 * Figure out how long our buffer will
836*9781SMoriah.Waterland@Sun.COM 				 * have to be.
837*9781SMoriah.Waterland@Sun.COM 				 */
838*9781SMoriah.Waterland@Sun.COM 				path_size = orig_offset_rel + strlen(path);
839*9781SMoriah.Waterland@Sun.COM 
840*9781SMoriah.Waterland@Sun.COM 				(*server_ptr) = pathalloc(path_size);
841*9781SMoriah.Waterland@Sun.COM 
842*9781SMoriah.Waterland@Sun.COM 				*client_ptr = *server_ptr + client_offset;
843*9781SMoriah.Waterland@Sun.COM 
844*9781SMoriah.Waterland@Sun.COM 				if (map_ptr)
845*9781SMoriah.Waterland@Sun.COM 					*map_ptr = *server_ptr +
846*9781SMoriah.Waterland@Sun.COM 					    orig_offset_rel;
847*9781SMoriah.Waterland@Sun.COM 
848*9781SMoriah.Waterland@Sun.COM 				/* LINTED warning: variable format specifier */
849*9781SMoriah.Waterland@Sun.COM 				(void) snprintf(*server_ptr, path_size+1,
850*9781SMoriah.Waterland@Sun.COM 					rel_fmt[base_sepr], basedir, path);
851*9781SMoriah.Waterland@Sun.COM 			} else {
852*9781SMoriah.Waterland@Sun.COM 				ptext(stderr, gettext(ERR_RELINABS), path);
853*9781SMoriah.Waterland@Sun.COM 				retcode = 0;
854*9781SMoriah.Waterland@Sun.COM 			}
855*9781SMoriah.Waterland@Sun.COM 		} else {	/* NOT RELATIVE */
856*9781SMoriah.Waterland@Sun.COM 			*server_ptr = fixpath_dup(path);
857*9781SMoriah.Waterland@Sun.COM 
858*9781SMoriah.Waterland@Sun.COM 			if ((*client_ptr = *server_ptr + client_offset) == NULL)
859*9781SMoriah.Waterland@Sun.COM 				*client_ptr = "/";
860*9781SMoriah.Waterland@Sun.COM 
861*9781SMoriah.Waterland@Sun.COM 			if (map_ptr)
862*9781SMoriah.Waterland@Sun.COM 				*map_ptr = *client_ptr;
863*9781SMoriah.Waterland@Sun.COM 		}
864*9781SMoriah.Waterland@Sun.COM 
865*9781SMoriah.Waterland@Sun.COM 		retcode = 1;
866*9781SMoriah.Waterland@Sun.COM 	} else {
867*9781SMoriah.Waterland@Sun.COM 		ptext(stderr, gettext(ERR_AMBDIRS));
868*9781SMoriah.Waterland@Sun.COM 		retcode = 0;
869*9781SMoriah.Waterland@Sun.COM 	}
870*9781SMoriah.Waterland@Sun.COM 
871*9781SMoriah.Waterland@Sun.COM 	return (retcode);
872*9781SMoriah.Waterland@Sun.COM }
873*9781SMoriah.Waterland@Sun.COM 
874*9781SMoriah.Waterland@Sun.COM void
export_client_env(char * root_path)875*9781SMoriah.Waterland@Sun.COM export_client_env(char *root_path)
876*9781SMoriah.Waterland@Sun.COM {
877*9781SMoriah.Waterland@Sun.COM 	char	*inst_release_path;
878*9781SMoriah.Waterland@Sun.COM 	char	*key;
879*9781SMoriah.Waterland@Sun.COM 	char	*value;
880*9781SMoriah.Waterland@Sun.COM 	FILE	*inst_fp;
881*9781SMoriah.Waterland@Sun.COM 	size_t	len;
882*9781SMoriah.Waterland@Sun.COM 
883*9781SMoriah.Waterland@Sun.COM 	/*
884*9781SMoriah.Waterland@Sun.COM 	 * Put the variables found in a clients INST_RELEASE file into the
885*9781SMoriah.Waterland@Sun.COM 	 * package environment so procedure scripts can know what
886*9781SMoriah.Waterland@Sun.COM 	 * release/version/revision a client is running. Also this function
887*9781SMoriah.Waterland@Sun.COM 	 * doesn't return state since the INST_RELEASE file may not exist in
888*9781SMoriah.Waterland@Sun.COM 	 * some package installation environments
889*9781SMoriah.Waterland@Sun.COM 	 */
890*9781SMoriah.Waterland@Sun.COM 
891*9781SMoriah.Waterland@Sun.COM 	len = strlen(root_path) + strlen(INST_RELEASE) + 2;
892*9781SMoriah.Waterland@Sun.COM 
893*9781SMoriah.Waterland@Sun.COM 	inst_release_path = (char *)malloc(len);
894*9781SMoriah.Waterland@Sun.COM 
895*9781SMoriah.Waterland@Sun.COM 	key = (char *)malloc(PATH_MAX);
896*9781SMoriah.Waterland@Sun.COM 
897*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(inst_release_path, len, "%s/%s", root_path,
898*9781SMoriah.Waterland@Sun.COM 				INST_RELEASE);
899*9781SMoriah.Waterland@Sun.COM 
900*9781SMoriah.Waterland@Sun.COM 	if ((inst_fp = fopen(inst_release_path, "r")) != NULL) {
901*9781SMoriah.Waterland@Sun.COM 		while (value = fpkgparam(inst_fp, key)) {
902*9781SMoriah.Waterland@Sun.COM 			if (strcmp(key, "OS") == 0) {
903*9781SMoriah.Waterland@Sun.COM 				putparam("PKG_CLIENT_OS", value);
904*9781SMoriah.Waterland@Sun.COM 			} else if (strcmp(key, "VERSION") == 0) {
905*9781SMoriah.Waterland@Sun.COM 				putparam("PKG_CLIENT_VERSION", value);
906*9781SMoriah.Waterland@Sun.COM 			} else if (strcmp(key, "REV") == 0) {
907*9781SMoriah.Waterland@Sun.COM 				putparam("PKG_CLIENT_REVISION", value);
908*9781SMoriah.Waterland@Sun.COM 			}
909*9781SMoriah.Waterland@Sun.COM 			*key = '\0';
910*9781SMoriah.Waterland@Sun.COM 		}
911*9781SMoriah.Waterland@Sun.COM 		(void) fclose(inst_fp);
912*9781SMoriah.Waterland@Sun.COM 	}
913*9781SMoriah.Waterland@Sun.COM 	free(inst_release_path);
914*9781SMoriah.Waterland@Sun.COM 	free(key);
915*9781SMoriah.Waterland@Sun.COM }
916*9781SMoriah.Waterland@Sun.COM 
917*9781SMoriah.Waterland@Sun.COM /*
918*9781SMoriah.Waterland@Sun.COM  * Increment variable indicating the installation is from a partially spooled
919*9781SMoriah.Waterland@Sun.COM  * package.
920*9781SMoriah.Waterland@Sun.COM  */
921*9781SMoriah.Waterland@Sun.COM void
set_partial_inst(void)922*9781SMoriah.Waterland@Sun.COM set_partial_inst(void)
923*9781SMoriah.Waterland@Sun.COM {
924*9781SMoriah.Waterland@Sun.COM 	partial_inst++;
925*9781SMoriah.Waterland@Sun.COM }
926*9781SMoriah.Waterland@Sun.COM 
927*9781SMoriah.Waterland@Sun.COM /*
928*9781SMoriah.Waterland@Sun.COM  * Return variable indicating that the installation is from a partially spooled
929*9781SMoriah.Waterland@Sun.COM  * package.
930*9781SMoriah.Waterland@Sun.COM  * Returns:  !0 for true
931*9781SMoriah.Waterland@Sun.COM  *           0 for false
932*9781SMoriah.Waterland@Sun.COM  */
933*9781SMoriah.Waterland@Sun.COM int
is_partial_inst(void)934*9781SMoriah.Waterland@Sun.COM is_partial_inst(void)
935*9781SMoriah.Waterland@Sun.COM {
936*9781SMoriah.Waterland@Sun.COM 	return (partial_inst);
937*9781SMoriah.Waterland@Sun.COM }
938*9781SMoriah.Waterland@Sun.COM 
939*9781SMoriah.Waterland@Sun.COM /*
940*9781SMoriah.Waterland@Sun.COM  * Increment variable indicating that only the depend and pkginfo DB's are to be
941*9781SMoriah.Waterland@Sun.COM  * updated
942*9781SMoriah.Waterland@Sun.COM  */
943*9781SMoriah.Waterland@Sun.COM 
944*9781SMoriah.Waterland@Sun.COM void
set_depend_pkginfo_DB(boolean_t a_setting)945*9781SMoriah.Waterland@Sun.COM set_depend_pkginfo_DB(boolean_t a_setting)
946*9781SMoriah.Waterland@Sun.COM {
947*9781SMoriah.Waterland@Sun.COM 	depend_pkginfo_DB = a_setting;
948*9781SMoriah.Waterland@Sun.COM }
949*9781SMoriah.Waterland@Sun.COM 
950*9781SMoriah.Waterland@Sun.COM /*
951*9781SMoriah.Waterland@Sun.COM  * Return variable indicating that the installation only updates the depend
952*9781SMoriah.Waterland@Sun.COM  * and pkginfo DB's.
953*9781SMoriah.Waterland@Sun.COM  * Returns:  !0 for true
954*9781SMoriah.Waterland@Sun.COM  *           0 for false
955*9781SMoriah.Waterland@Sun.COM  */
956*9781SMoriah.Waterland@Sun.COM 
957*9781SMoriah.Waterland@Sun.COM boolean_t
is_depend_pkginfo_DB(void)958*9781SMoriah.Waterland@Sun.COM is_depend_pkginfo_DB(void)
959*9781SMoriah.Waterland@Sun.COM {
960*9781SMoriah.Waterland@Sun.COM 	return (depend_pkginfo_DB);
961*9781SMoriah.Waterland@Sun.COM }
962*9781SMoriah.Waterland@Sun.COM 
963*9781SMoriah.Waterland@Sun.COM /*
964*9781SMoriah.Waterland@Sun.COM  * Increment variable indicating that packages should not be spooled in
965*9781SMoriah.Waterland@Sun.COM  * var/sadm/pkg/<pkgabbrev>/save/pspool/
966*9781SMoriah.Waterland@Sun.COM  */
967*9781SMoriah.Waterland@Sun.COM void
disable_spool_create(void)968*9781SMoriah.Waterland@Sun.COM disable_spool_create(void)
969*9781SMoriah.Waterland@Sun.COM {
970*9781SMoriah.Waterland@Sun.COM 	partial_spool_create++;
971*9781SMoriah.Waterland@Sun.COM }
972*9781SMoriah.Waterland@Sun.COM 
973*9781SMoriah.Waterland@Sun.COM /*
974*9781SMoriah.Waterland@Sun.COM  * Return variable indicating whether or not the partial spool directory
975*9781SMoriah.Waterland@Sun.COM  * should be created.
976*9781SMoriah.Waterland@Sun.COM  * Returns:  1 for true
977*9781SMoriah.Waterland@Sun.COM  *           0 for false
978*9781SMoriah.Waterland@Sun.COM  */
979*9781SMoriah.Waterland@Sun.COM int
is_spool_create(void)980*9781SMoriah.Waterland@Sun.COM is_spool_create(void)
981*9781SMoriah.Waterland@Sun.COM {
982*9781SMoriah.Waterland@Sun.COM 	return (partial_spool_create);
983*9781SMoriah.Waterland@Sun.COM }
984