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/*
6e1ae2a33c618c4c2b14aec7d2f21743ddea5837Gary Pennington * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
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 * *****************************************************************************
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * global external (public) functions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * *****************************************************************************
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}