5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This module contains all the code necessary to establish the key base
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directories to which the actual components of the package will be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * installed or removed. -- JST
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/stat.h> /* mkdir() declaration */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int install_root_exists = 0; /* An install root was specified */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int install_root_len; /* strlen(install_root) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *orig_basedir = NULL; /* The unadjusted basedir */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *basedir = NULL; /* basedir (cmb w/ inst rt if req) */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int basedir_exists = 0; /* There are relocatable paths */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int client_basedir_exists = 0; /* Installing from a host */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *env_cl_bdir = NULL; /* CLIENT_BASEDIR from environment */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ir_accessed = 0; /* install_root has been used */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int relocatable; /* set_basedir() assumed this */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int partial_inst = 0; /* Installing pkg from partial spool directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic boolean_t depend_pkginfo_DB = B_FALSE; /* Only update depend/pkginfoDB */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int partial_spool_create = 0; /* Create partial spool dir */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ask_basedir(char *path, int nointeract);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * base_sepr and rel_fmt support construction of absolute paths from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * relative paths.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int base_sepr = 1; /* separator length btwn basedir & path */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *rel_fmt[] = { "%s%s", "%s/%s" };
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int eval_valid = 0; /* everything set up to do an eval_path() */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_IR_REPL "Replacing current install root with %s."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_IRSET "Install_root has already been set to <%s> and used."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_IRNOTABS "Install_root (-R option) requires an absolute " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "pathname: <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_ALLOCFAILED "insufficient memory in %s"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_ADMIN_INVAL "Invalid basedir entry in admin file."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_RELINABS "Relative path <%s> found in absolute package."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_CL_MIS "Constructed CLIENT_BASEDIR <%s> and " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "environment CLIENT_BASEDIR <%s> do not match."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_ASKBD "%s is already installed at %s. Cannot create a " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "duplicate installation at %s."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_NO_CL_BD "Cannot resolve CLIENT_BASEDIR conflicts."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_AMBDIRS "Cannot evaluate path due to ambiguous " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "base directories."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_NODELETE "unable to delete <%s>."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_MKBASE "unable to make directory <%s>."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_REQBASEDIR "Installation of this package requires a base " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_MUSTEXIST "\\nThe selected base directory <%s> must exist " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "before installation is attempted."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_YORNPRMPT "Do you want this directory created now"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_ISAFILE "\\nThe selected base directory <%s> must exist " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "before installation is attempted, but a file " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "already exists in it's place."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_YORNFILE "Do you want the file deleted and the directory " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "created now"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_PROMPT "Enter path to package base directory"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_HELP "Installation of this package requires that a UNIX " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "directory be available for installation of " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "appropriate software. This directory may be part " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "of any mounted filesystem, or may itself be a " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "mount point. In general, it is unwise to select a " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "base directory which already contains other files " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "and/or directories."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Set the install root (-R option).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If we've already set the install_root but no one has used it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * yet, we'll complain and allow the change. If it's been used
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then we'll deny the switch & return failed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If the two install_roots are different - problem */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* We are trying to *change* the install_root */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else { /* !ir_accessed */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ptext(stderr, gettext(ERR_IRNOTABS), path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(tmp_path, path, sizeof (tmp_path));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If install_root is '/' then it's trivial. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This routine returns a path with the correct install_root prepended.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if the install_root has been set. NOTE : this allocates memory
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which will need to be freed at some point.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland calloc(1, strlen(path) + install_root_len +
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_ALLOCFAILED), "fixpath()");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*ir_ptr) /* for every char in install_root */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If install_root == "/", a concatenation will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * result in a return value of "//...", same goes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for an install_root ending in '/'. So we back
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * over a trailing '/' if it's there.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's no install root & no client_basedir,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then return the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's no path specified, return the install root
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * since no matter what happens, this is where the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path will have to start.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This routine does what fixpath() does except it's for high-volume
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * stuff restricted to the instvol() function. By using
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pathdup() and pathalloc() memory fragmentation is reduced. Also, the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * memory allocated by pathdup() and pathalloc() gets freed at the end
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of each volume installed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland npath = pathalloc(strlen(path) + install_root_len + 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*ir_ptr) /* for every char in install_root */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If install_root == "/", a concatenation will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * result in a return value of "//...", same goes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for an install_root ending in '/'. So we back
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * over a trailing '/' if it's there.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's no install root & no client_basedir,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then return the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's no path specified, return the install root
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * since no matter what happens, this is where the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path will have to start.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This returns a pointer to a static name. This could be abused.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- JST (1993-07-21)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ir_accessed = 1; /* we can't change it now */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This routine takes path and removes install_root from the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if it has already been prepended. If install_root is not prepended to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path or install_root is '/' or path == NULL then path is returned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * as is. If the resulting path is somehow relative, a corrupt
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * package name error is raised and the program quits. NOTE : This
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function usually returns a pointer into the original path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * argument. It doesn't allocate new memory. This is possible,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of course, because the path being returned is guaranteed to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be a subset of the original argument unless basedir = '/' in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which case a pointer to a static "/" is returned. See
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * orig_path() below if you want to be handed a new copy of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * return value.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (path && *path) { /* as long as we got an argument */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!install_root_exists) /* if no install_root */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Otherwise, if install_root is really prepended to the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then remove it dealing appropriately with special cases.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (strncmp(path, install_root, install_root_len) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The result will be relative if install_root = '/'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the basedir path was built legally, then moving
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the pointer back one character will make it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * absolute. If that fails then the path we got was
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * incorrectly constructed in the first place.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland retv = path; /* All else failing, return path. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function does the same as orig_path_ptr() except that it mallocs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * new space and provides a new copy of the original basedir path which
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * needs to be free()'d one way or another later.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return ((retv == NULL) ? retv : strdup(retv));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function lets us hold onto the environment's version of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CLIENT_BASEDIR for later review by set_client_basedir().
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* ask for the basedir */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = ckpath(path, P_ABSOLUTE|P_DIR|P_WRITE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n); /* FAIL */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Set the basedir and client_basedir based on install root and config
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * files. It returns 0 if all OK otherwise returns the error code base
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * appropriate to the problem.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandset_basedirs(int reloc, char *adm_basedir, char *pkginst, int nointeract)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there are no relocatable files basedir is probably meaningless
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * so we skip ahead to the simple tests. Otherwise we do the twisted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * stuff below. The BASEDIR is set based on the following heirarchy :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1. The entry in the admin file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 2. The entry in the pkginfo file delivered on the medium
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 3. The entry in the already installed pkginfo file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it's not a relocatable package, we go with whatever seems
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * reasonable; if it's relocatable and we've exhausted our
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * options, we ask.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int is_adm_basedir = (adm_basedir && *adm_basedir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (strcmp(adm_basedir, "ask") == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's a BASEDIR in the admin file & it's a valid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * absolute pathname, use it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (is_adm_basedir && strchr("/$", *adm_basedir))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If admin says 'ask regardless', ask and continue */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it isn't the only other valid option,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * namely 'default', quit FAIL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * OK, the admin file has no preference, so we go to the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * other sources.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Check to see if BASEDIR is set in the environment
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * (probably from the pkginfo file on the installation
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Check to see if the package BASEDIR was
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * already defined during a previous
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * installation of this package instance. The
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function below looks for an installed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkginfo file and scans it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (n = ask_basedir(path, nointeract))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else { /* not relocatable */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Since all paths are absolute the only reason to have a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * basedir is if there's an install root meaning there's
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * really a basedir relative to this host or this package is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * absolute only because it's sparse in which case we're
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * interested in the prior basedir. So we next check for a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * prior basedir and then an install root.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If we have a basedir *only because*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * we have an install_root, we need to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * set orig_basedir to '/' to simplify
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * later attempts to force
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * client_basedir.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eval_valid++; /* we can run eval_path() now */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0); /* fixpath below unnecessary */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If basedir == "/" then there's no need for a "/" between
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * it and the rest of the path.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eval_valid++; /* we've confirmed the validity of everything */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Make a directory from a path and all necessary directories above it as
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if entire path exists, return o.k. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entire path not there - check components and create */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((access(p, F_OK) != 0) && (mkdir(p, 0755) != 0)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* This makes the required base directory if necessary */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If a base directory is called for but there's no such directory on
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the system, deal with that issue.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there's a non-directory object in the way, ask.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ptext(stderr, gettext(MSG_ISAFILE), basedir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * It isn't a directory, so we'll just unlink
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ptext(stderr, gettext(MSG_MUSTEXIST), basedir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (access(basedir, F_OK) == 0 || mkpath(basedir)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Create a client_basedir if it is appropriate. If all goes well, resulting
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in either a valid client_basedir or a valid lack thereof, it returns 1.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If there is an irreconcileable conflict, it returns 0.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * In response to an agreement associated with bug report #1133956,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CLIENT_BASEDIR will be defined in all cases where BASEDIR is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * defined until the on1094 release. For on1094 delete the else if
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and associated expressions below. -- JST (6/25/1993)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * At this point we may or may not have a client_basedir defined. Now
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * we need to check for one in the environment & make sure it syncs
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * up with prior findings. If there's no other client_basedir defined,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the environment defines it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If the two client basedirs mismatch, return fail */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(path_buf, path, sizeof (path_buf));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function returns the basedir that is appropriate for this package's
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkginfo file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Since calls to putparam() become valid long after much of the above
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * code has run, this routine allows the insertion of these key
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * environment variables without passing a bunch of pointers.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland putparam("PKG_INSTALL_ROOT", get_inst_root());
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland putparam("CLIENT_BASEDIR", client_basedir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This fills three pointers and a buffer which contains the longest
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * possible path (with install_root and basedir prepended. The pointers
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * are to the subpaths within the string. This was added so that the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * eptlist could be produced with all relevant paths defined without
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * repeated calls and string scans. For example, given a path of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * haberdasher/crute we may return
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * server_ptr -----> /export/root/client1/opt/SUNWhab/haberdasher/crute
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * client_ptr --------------------------- |
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * map_ptr -------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * We construct the new path based upon the established environment
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and the type of path that was passed. Here are the possibilities:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * | | relative path | absolute path |
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * | --------------------------------|---------------|---------------|
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * | is_an_inst_root | 1 | 2 |
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * V ! an_inst_root && is_a_basedir | 1 | 3 |
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ! an_inst_root && ! a_basedir | X | 3 |
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 1. Prepend the basedir to the path (the basedir is guaranteed to exist
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * whenever there's an install_root).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 2. Prepend the install_root (not the basedir) to the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 3. Return the path as unchanged.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * X. THIS CAN'T HAPPEN
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandeval_path(char **server_ptr, char **client_ptr, char **map_ptr, char *path)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is the offset from the beginning of the evaluated
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path to the start of the relative path. Note that we
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * are accounting for the '/' inserted between the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * basedir and the path with the '+ 1'. If there is a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * relative path, then there is always a basedir. The
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * only way this will come up '0' is if this is an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * absolute package.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland orig_offset_rel = (is_a_basedir()) ? (strlen(basedir) +
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is the position of the client-relative path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in that it points to the '/' beginning the base
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory or the absolute path. Once the basedir has
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * been afixed, the path is absolute. For that reason,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the client path is the same thing as the original path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if it were absolute.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland client_offset = (is_an_inst_root()) ? install_root_len : 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If we've evaluated the base directory and come up trumps,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then we can procede with this operation, otherwise, the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * available data is too ambiguous to resolve the issue.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Figure out how long our buffer will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * have to be.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path_size = orig_offset_rel + strlen(path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* LINTED warning: variable format specifier */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ptext(stderr, gettext(ERR_RELINABS), path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else { /* NOT RELATIVE */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*client_ptr = *server_ptr + client_offset) == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Put the variables found in a clients INST_RELEASE file into the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * package environment so procedure scripts can know what
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * release/version/revision a client is running. Also this function
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * doesn't return state since the INST_RELEASE file may not exist in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * some package installation environments
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland len = strlen(root_path) + strlen(INST_RELEASE) + 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(inst_release_path, len, "%s/%s", root_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((inst_fp = fopen(inst_release_path, "r")) != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Increment variable indicating the installation is from a partially spooled
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return variable indicating that the installation is from a partially spooled
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: !0 for true
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 for false
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Increment variable indicating that only the depend and pkginfo DB's are to be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return variable indicating that the installation only updates the depend
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and pkginfo DB's.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: !0 for true
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 for false
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Increment variable indicating that packages should not be spooled in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * var/sadm/pkg/<pkgabbrev>/save/pspool/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return variable indicating whether or not the partial spool directory
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * should be created.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: 1 for true
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * 0 for false