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