zones_paths.c revision af1222373b60d56d6b0e630911372d4162b7787b
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
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 *
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 *
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 *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * System includes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <limits.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl#include <libgen.h>
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl#include <errno.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <fcntl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/stat.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <signal.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <assert.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <locale.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libintl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * local includes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "instzones_lib.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "zones_strings.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define isdot(x) ((x[0] == '.') && (!x[1] || (x[1] == '/')))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define isdotdot(x) ((x[0] == '.') && (x[1] == '.') && \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (!x[2] || (x[2] == '/')))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * forward declarations
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char **inheritedFileSystems = (char **)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic size_t *inheritedFileSystemsLen = (size_t *)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int numInheritedFileSystems = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * *****************************************************************************
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * global external (public) functions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * *****************************************************************************
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: z_get_inherited_file_systems
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Return list of file systems inherited from the global zone;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * These file systems are entered into the list when the function
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pkgAddInheritedFileSystem() is called.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: char **
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - pointer to array of character pointers, each pointer
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * being a pointer to a string representing a file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * system that is inherited from the global zone
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the last entry will be (char *)NULL
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * - (char **)NULL - no file systems inherited
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandchar **
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_get_inherited_file_systems(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (inheritedFileSystems);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: z_add_inherited_file_system
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Add specified package to internal list of inherited file systems
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: a_inheritedFileSystem - absolute path to file systen "inherited"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function is called to register a directory (or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file system) as being inherited from the global zone
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * into the non-global zone being operated on. The
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * inherited directory must be specified relative to the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * root file system ("/"). For example, if "/usr" is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * inherited, then the path specified would be "/usr".
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Any path subsequently checked for being present in a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory inherited read-only from the global zone:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- will NOT have $PKG_INSTALL_ROOT prepended to it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- if $PKG_INSTALL_ROOT is set and $BASEDIR is not set.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- WILL have $BASEDIR prepended to it (if set).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- $BASEDIR always has $PKG_INSTALL_ROOT included in it.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- For example, if $PKG_INSTALL_ROOT is set to /a, and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- the base install directory is set to "/opt", then the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- $BASEDIR variable will be set to "/a/opt".
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Any path that is checked for being present in an inherited
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory will be specified relative to the root file system
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * of the non-global zone in which the path is located.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When a path to update is checked for being present in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * an inherited directory, $PKG_INSTALL_ROOT is stripped
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * off the path before it is checked.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the non-global zone is not running, the scratch zone
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is used to access the non-global zone. In this case,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * $PKG_INSTALL_ROOT will be set to "/a" and both the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * non-global zone's root file system and all inherited
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directories will be mounted on "/a". When a path is checked
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for being inherited, it will have $PKG_INSTALL_ROOT stripped
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * from the beginning, so any inherited directories must be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * specified relative to "/" and not $PKG_INSTALL_ROOT.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the non-global zone is running, the non-global zone
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is used directly. In this case, $PKG_INSTALL_ROOT will
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * be set to "/" and both the non-global zone's root file
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * system and all inherited directories will be mounted on
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "/". $PKG_INSTALL_ROOT is set to "/" so the path is unchanged
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * before being checked against the list of inherited directories.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: boolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_TRUE - file system successfully added to list
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_FALSE - failed to add file system to list
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandboolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_add_inherited_file_system(char *a_inheritedFileSystem)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define IPSLOP 2 /* for trailing '/' and '\0' */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define IPMAX ((sizeof (rp))-IPSLOP)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char rp[PATH_MAX+1+IPSLOP] = {'\0'};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* file system cannot be empty */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (a_inheritedFileSystem == NULL || *a_inheritedFileSystem == '\0') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_program_error(ERR_INHERITED_PATH_NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* file system must be absolute */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*a_inheritedFileSystem != '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_program_error(ERR_INHERITED_PATH_NOT_ABSOLUTE,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a_inheritedFileSystem);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* make a local copy of the path and canonize it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = strlcpy(rp, a_inheritedFileSystem, IPMAX);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n > IPMAX) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_program_error(ERR_INHERITED_PATH_TOO_LONG,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strlen(a_inheritedFileSystem), IPMAX,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a_inheritedFileSystem);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland assert(n > 0); /* path must have at least 1 byte in it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland z_path_canonize(rp); /* remove duplicate "/"s, ./, etc */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* add trailing "/" if it's not already there */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = strlen(rp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (rp[n-1] != '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rp[n++] = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* null terminate the string */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rp[n] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* add file system to internal list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (inheritedFileSystems == (char **)NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems = (char **)_z_calloc(
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland 2 * (sizeof (char **)));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen =
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (size_t *)_z_calloc(2 * (sizeof (size_t *)));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems = (char **)_z_realloc(inheritedFileSystems,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sizeof (char **)*(numInheritedFileSystems+2));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen = (size_t *)_z_realloc(
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sizeof (size_t *)*(numInheritedFileSystems+2));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* add this entry to the end of the list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen[numInheritedFileSystems] = strlen(rp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems[numInheritedFileSystems] = _z_strdup(rp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland numInheritedFileSystems++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* make sure end of the list is properly terminated */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen[numInheritedFileSystems] = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems[numInheritedFileSystems] = (char *)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* exit debugging info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_echoDebug(DBG_PATHS_ADD_FS, numInheritedFileSystems,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems[numInheritedFileSystems-1]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_TRUE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: z_path_is_inherited
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Determine if the specified path is in a file system that is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the internal list of inherited file systems
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: a_path - pointer to string representing path to verify
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_ftype - file "type" if known otherwise '\0'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Type can be "f" (file), or "d" (directory)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_rootDir - pointer to string representing root directory where
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a_path is relative to - typically this would either be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "/" or the path specified as an alternative root to -R
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: boolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_TRUE - the path is in inherited file system space
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * B_FALSE - the path is NOT in inherited file system space
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandboolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_path_is_inherited(char *a_path, char a_ftype, char *a_rootDir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl int n;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl char *cp, *path2use;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl char real_path[PATH_MAX];
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl char path_copy[PATH_MAX];
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl boolean_t found = B_FALSE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* entry assertions */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland assert(a_path != (char *)NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland assert(*a_path != '\0');
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* if no inherited file systems, there can be no match */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (numInheritedFileSystems == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_echoDebug(DBG_PATHS_NOT_INHERITED, a_path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* normalize root directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((a_rootDir == (char *)NULL) || (*a_rootDir == '\0')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland a_rootDir = "/";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * The loop below represents our best effort to identify real path of
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * a file, which doesn't need to exist. realpath() returns error for
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * nonexistent path, therefore we need to cut off trailing components
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * of path until we get path which exists and can be resolved by
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * realpath(). Lookup of "/dir/symlink/nonexistent-file" would fail
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * to resolve symlink without this.
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl */
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl (void) strlcpy(path_copy, a_path, PATH_MAX);
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl for (cp = dirname(path_copy); strlen(cp) > 1; cp = dirname(cp)) {
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl if (realpath(cp, real_path) != NULL) {
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl found = B_TRUE;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl break;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl } else if (errno != ENOENT)
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl break;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl }
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl if (found) {
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl /*
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * In the loop above we always strip trailing path component,
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * so the type of real_path is always 'd'.
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl */
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl a_ftype = 'd';
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl path2use = real_path;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl } else {
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl path2use = a_path;
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl }
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl /*
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl * if path resides on an inherited filesystem then
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * it must be read-only.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl if (z_isPathWritable(path2use) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * remove the root path from the target path before comparing:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Example 1:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- path is "/export/zone1/root/usr/test"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- root path is "/export/zone1/root"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --- final path should be "/usr/test"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Example 2:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- path is "/usr/test"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -- root path is "/"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * --- final path should be "/usr/test"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* advance past given root directory if path begins with it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = strlen(a_rootDir);
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl if (strncmp(a_rootDir, path2use, n) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *p;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* advance past the root path */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl p = path2use + n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* go back to the first occurance of the path separator */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl while ((*p != '/') && (p > path2use)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland p--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* use this location in the path to compare */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl path2use = p;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * see if this path is in any inherited file system path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * note that all paths in the inherited list are directories
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * so they end in "/" to prevent a partial match, such as
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * comparing "/usr/libx" with "/usr/lib" - by making the comparison
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "/usr/libx" with "/usr/lib/" the partial false positive will not
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * occur. This complicates matters when the object to compare is a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory - in this case, comparing "/usr" with "/usr/" will fail,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * so if the object is a directory, compare one less byte from the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * inherited file system so that the trailing "/" is ignored.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (n = 0; n < numInheritedFileSystems; n++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int fslen;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* get target fs len; adjust -1 if directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fslen = inheritedFileSystemsLen[n];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((a_ftype == 'd') && (fslen > 1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fslen--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
af1222373b60d56d6b0e630911372d4162b7787bJan Kryl if (strncmp(path2use, inheritedFileSystems[n], fslen) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_echoDebug(DBG_PATHS_IS_INHERITED, a_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems[n]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_TRUE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* path is not in inherited file system space */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland _z_echoDebug(DBG_PATHS_IS_NOT_INHERITED, a_path, a_rootDir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: z_make_zone_root
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Given its zonepath, generate a string representing the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * mountpoint of where the root path for a nonglobal zone is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * mounted. The zone is mounted using 'zoneadm', which mounts
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the zone's filesystems wrt <zonepath>/lu/a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: zone_path - non-NULL pointer to string representing zonepath
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: char * - pointer to string representing zonepath of zone
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NULL - if zone_path is NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Notes: The string returned is in static storage and should not be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free()ed by the caller.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandchar *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_make_zone_root(char *zone_path)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland static char zone_root_buf[MAXPATHLEN];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (zone_path == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(zone_root_buf, MAXPATHLEN, "%s%slu/a", zone_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (zone_path[0] != '\0' &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland zone_path[strlen(zone_path) - 1] == '/') ? "" : "/");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (zone_root_buf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_path_canonize(char *a_file)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *last;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int level;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* remove references such as "./" and "../" and "//" */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (pt = a_file; *pt; /* void */) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (isdot(pt)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(pt, pt[1] ? pt+2 : pt+1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (isdotdot(pt)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland level = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland last = pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland do {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland level++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland last += 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*last) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland last++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } while (isdotdot(last));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland --pt; /* point to previous '/' */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (level--) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pt <= a_file) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while ((*--pt != '/') && (pt > a_file))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pt == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(pt, last);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*pt && (*pt != '/')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pt == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (pt[1] == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(pt, pt+1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((--pt > a_file) && (*pt == '/')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_canoninplace(char *src)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *dst;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *src_start;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* keep a ptr to the beginning of the src string */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland src_start = src;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dst = src;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*src) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*src == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *dst++ = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*src == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland src++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *dst++ = *src++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * remove any trailing slashes, unless the whole string is just "/".
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the whole string is "/" (i.e. if the last '/' cahr in dst
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the beginning of the original string), just terminate it
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and return "/".
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*(dst - 1) == '/') && ((dst - 1) != src_start))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dst--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *dst = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandz_free_inherited_file_systems(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < numInheritedFileSystems; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(inheritedFileSystems[i]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(inheritedFileSystems);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystems = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(inheritedFileSystemsLen);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland inheritedFileSystemsLen = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland numInheritedFileSystems = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}