4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews/* Copyright (c) 2007 The NetBSD Foundation, Inc.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * All rights reserved.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Redistribution and use in source and binary forms, with or without
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * modification, are permitted provided that the following conditions
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * are met:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 1. Redistributions of source code must retain the above copyright
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * notice, this list of conditions and the following disclaimer.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * 2. Redistributions in binary form must reproduce the above copyright
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * notice, this list of conditions and the following disclaimer in the
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * documentation and/or other materials provided with the distribution.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#include "atf-c/detail/fs.h"
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#if defined(HAVE_CONFIG_H)
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#include "config.h"
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#endif
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <sys/types.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <sys/param.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <sys/mount.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <sys/stat.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <sys/wait.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <dirent.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <errno.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <libgen.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <stdarg.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <stdio.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <stdlib.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <string.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include <unistd.h>
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Hunt#include "atf-c/defs.h"
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#include "atf-c/detail/sanity.h"
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#include "atf-c/detail/text.h"
4a53e3c2b83c476a93148eaee0272649beb221caMark Andrews#include "atf-c/detail/user.h"
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#include "atf-c/error.h"
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Prototypes for auxiliary functions.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic bool check_umask(const mode_t, const mode_t);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic atf_error_t copy_contents(const atf_fs_path_t *, char **);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic mode_t current_umask(void);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic atf_error_t do_mkdtemp(char *);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic atf_error_t normalize(atf_dynstr_t *, char *);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic void replace_contents(atf_fs_path_t *, const char *);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic const char *stat_type_to_string(const int);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The "invalid_umask" error type.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstruct invalid_umask_error_data {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* One of atf_fs_stat_*_type. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt int m_type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* The original path causing the error. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* XXX: Ideally this would be an atf_fs_path_t, but if we create it
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * from the error constructor, we cannot delete the path later on.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Can't remember why atf_error_new does not take a hook for
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * deletion. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char m_path[1024];
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* The umask that caused the error. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt mode_t m_umask;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt};
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunttypedef struct invalid_umask_error_data invalid_umask_error_data_t;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntinvalid_umask_format(const atf_error_t err, char *buf, size_t buflen)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const invalid_umask_error_data_t *data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(atf_error_is(err, "invalid_umask"));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data = atf_error_data(err);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt snprintf(buf, buflen, "Could not create the temporary %s %s because "
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt "it will not have enough access rights due to the current "
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt "umask %05o", stat_type_to_string(data->m_type),
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data->m_path, (unsigned int)data->m_umask);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntinvalid_umask_error(const atf_fs_path_t *path, const int type,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const mode_t failing_mask)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt invalid_umask_error_data_t data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data.m_type = type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt strncpy(data.m_path, atf_fs_path_cstring(path), sizeof(data.m_path));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data.m_path[sizeof(data.m_path) - 1] = '\0';
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data.m_umask = failing_mask;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_error_new("invalid_umask", &data, sizeof(data),
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt invalid_umask_format);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The "unknown_file_type" error type.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstruct unknown_type_error_data {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *m_path;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt int m_type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt};
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunttypedef struct unknown_type_error_data unknown_type_error_data_t;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntunknown_type_format(const atf_error_t err, char *buf, size_t buflen)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const unknown_type_error_data_t *data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(atf_error_is(err, "unknown_type"));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data = atf_error_data(err);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt snprintf(buf, buflen, "Unknown file type %d of %s", data->m_type,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data->m_path);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntunknown_type_error(const char *path, int type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unknown_type_error_data_t data;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data.m_path = path;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt data.m_type = type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_error_new("unknown_type", &data, sizeof(data),
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt unknown_type_format);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Auxiliary functions.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntcheck_umask(const mode_t exp_mode, const mode_t min_mode)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const mode_t actual_mode = (~current_umask() & exp_mode);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return (actual_mode & min_mode) == min_mode;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntcopy_contents(const atf_fs_path_t *p, char **buf)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *str;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = (char *)malloc(atf_dynstr_length(&p->m_data) + 1);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (str == NULL)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_memory_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt strcpy(str, atf_dynstr_cstring(&p->m_data));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *buf = str;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntmode_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntcurrent_umask(void)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const mode_t current = umask(0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt (void)umask(current);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return current;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdo_mkdtemp(char *tmpl)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(strstr(tmpl, "XXXXXX") != NULL);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (mkdtemp(tmpl) == NULL)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot create temporary directory "
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt "with template '%s'", tmpl);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdo_mkstemp(char *tmpl, int *fdout)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(strstr(tmpl, "XXXXXX") != NULL);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *fdout = mkstemp(tmpl);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (*fdout == -1)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot create temporary file "
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt "with template '%s'", tmpl);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntnormalize(atf_dynstr_t *d, char *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *ptr;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *last;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt bool first;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(strlen(p) > 0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(atf_dynstr_length(d) == 0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (p[0] == '/')
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_append_fmt(d, "/");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt first = true;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt last = NULL; /* Silence GCC warning. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ptr = strtok_r(p, "/", &last);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt while (!atf_is_error(err) && ptr != NULL) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (strlen(ptr) > 0) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_append_fmt(d, "%s%s", first ? "" : "/", ptr);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt first = false;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ptr = strtok_r(NULL, "/", &last);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntnormalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *str;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_list ap2;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_init(d);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_copy(ap2, ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_text_format_ap(&str, p, ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_end(ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_dynstr_fini(d);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = normalize(d, str);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt free(str);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntreplace_contents(atf_fs_path_t *p, const char *buf)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(atf_dynstr_length(&p->m_data) == strlen(buf));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_dynstr_clear(&p->m_data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_append_fmt(&p->m_data, "%s", buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INV(!atf_is_error(err));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstatic
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst char *
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntstat_type_to_string(const int type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *str;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (type == atf_fs_stat_blk_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "block device";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_chr_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "character device";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_dir_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "directory";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_fifo_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "named pipe";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_lnk_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "symbolic link";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_reg_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "regular file";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_sock_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "socket";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (type == atf_fs_stat_wht_type)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = "whiteout";
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt UNREACHABLE;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt str = NULL;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return str;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The "atf_fs_path" type.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Constructors/destructors.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_init_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_list ap2;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_copy(ap2, ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = normalize_ap(&p->m_data, fmt, ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_end(ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_init_fmt(atf_fs_path_t *p, const char *fmt, ...)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_list ap;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_start(ap, fmt);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_init_ap(p, fmt, ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_end(ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_copy(atf_fs_path_t *dest, const atf_fs_path_t *src)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_dynstr_copy(&dest->m_data, &src->m_data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_fini(atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_dynstr_fini(&p->m_data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Getters.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_branch_path(const atf_fs_path_t *p, atf_fs_path_t *bp)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const size_t endpos = atf_dynstr_rfind_ch(&p->m_data, '/');
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (endpos == atf_dynstr_npos)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_init_fmt(bp, ".");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else if (endpos == 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_init_fmt(bp, "/");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_init_substr(&bp->m_data, &p->m_data, 0, endpos);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#if defined(HAVE_CONST_DIRNAME)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INV(atf_equal_dynstr_cstring(&bp->m_data,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dirname(atf_dynstr_cstring(&p->m_data))));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#endif /* defined(HAVE_CONST_DIRNAME) */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst char *
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_cstring(const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_dynstr_cstring(&p->m_data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_leaf_name(const atf_fs_path_t *p, atf_dynstr_t *ln)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt size_t begpos = atf_dynstr_rfind_ch(&p->m_data, '/');
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (begpos == atf_dynstr_npos)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt begpos = 0;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt begpos++;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_init_substr(ln, &p->m_data, begpos, atf_dynstr_npos);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#if defined(HAVE_CONST_BASENAME)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INV(atf_equal_dynstr_cstring(ln,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt basename(atf_dynstr_cstring(&p->m_data))));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#endif /* defined(HAVE_CONST_BASENAME) */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_is_absolute(const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_dynstr_cstring(&p->m_data)[0] == '/';
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_is_root(const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_equal_dynstr_cstring(&p->m_data, "/");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Modifiers.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_append_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_dynstr_t aux;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_list ap2;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_copy(ap2, ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = normalize_ap(&aux, fmt, ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_end(ap2);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!atf_is_error(err)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *auxstr = atf_dynstr_cstring(&aux);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const bool needslash = auxstr[0] != '/';
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_dynstr_append_fmt(&p->m_data, "%s%s",
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt needslash ? "/" : "", auxstr);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_dynstr_fini(&aux);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_append_fmt(atf_fs_path_t *p, const char *fmt, ...)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_list ap;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_start(ap, fmt);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_append_ap(p, fmt, ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt va_end(ap);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_append_path(atf_fs_path_t *p, const atf_fs_path_t *p2)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_fs_path_append_fmt(p, "%s", atf_dynstr_cstring(&p2->m_data));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_path_to_absolute(const atf_fs_path_t *p, atf_fs_path_t *pa)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(!atf_fs_path_is_absolute(p));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_getcwd(pa);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_append_path(pa, p);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_fs_path_fini(pa);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Operators.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool atf_equal_fs_path_fs_path(const atf_fs_path_t *p1,
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const atf_fs_path_t *p2)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return atf_equal_dynstr_dynstr(&p1->m_data, &p2->m_data);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * The "atf_fs_path" type.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Constants.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_blk_type = 1;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_chr_type = 2;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_dir_type = 3;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_fifo_type = 4;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_lnk_type = 5;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_reg_type = 6;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_sock_type = 7;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_stat_wht_type = 8;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Constructors/destructors.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_init(atf_fs_stat_t *st, const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *pstr = atf_fs_path_cstring(p);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (lstat(pstr, &st->m_sb) == -1) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot get information of %s; "
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt "lstat(2) failed", pstr);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt int type = st->m_sb.st_mode & S_IFMT;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt switch (type) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFBLK: st->m_type = atf_fs_stat_blk_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFCHR: st->m_type = atf_fs_stat_chr_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFDIR: st->m_type = atf_fs_stat_dir_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFIFO: st->m_type = atf_fs_stat_fifo_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFLNK: st->m_type = atf_fs_stat_lnk_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFREG: st->m_type = atf_fs_stat_reg_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFSOCK: st->m_type = atf_fs_stat_sock_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#if defined(S_IFWHT)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt case S_IFWHT: st->m_type = atf_fs_stat_wht_type; break;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#endif
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt default:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = unknown_type_error(pstr, type);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_copy(atf_fs_stat_t *dest, const atf_fs_stat_t *src)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dest->m_type = src->m_type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt dest->m_sb = src->m_sb;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntvoid
a747113422afaa29ce72d2c5ba7f0b7ea9ec2054Evan Huntatf_fs_stat_fini(atf_fs_stat_t *st ATF_DEFS_ATTRIBUTE_UNUSED)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Getters.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntdev_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_get_device(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_dev;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntino_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_get_inode(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_ino;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntmode_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_get_mode(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & ~S_IFMT;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntoff_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_get_size(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_size;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntint
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_get_type(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_type;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_owner_readable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IRUSR;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_owner_writable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IWUSR;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_owner_executable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IXUSR;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_group_readable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IRGRP;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_group_writable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IWGRP;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_group_executable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IXGRP;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_other_readable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IROTH;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_other_writable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IWOTH;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntbool
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_stat_is_other_executable(const atf_fs_stat_t *st)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return st->m_sb.st_mode & S_IXOTH;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/* ---------------------------------------------------------------------
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Free functions.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * --------------------------------------------------------------------- */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_access_f = 1 << 0;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_access_r = 1 << 1;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_access_w = 1 << 2;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntconst int atf_fs_access_x = 1 << 3;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt/*
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * An implementation of access(2) but using the effective user value
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * instead of the real one. Also avoids false positives for root when
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * asking for execute permissions, which appear in SunOS.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_eaccess(const atf_fs_path_t *p, int mode)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt struct stat st;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt bool ok;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt PRE(mode & atf_fs_access_f || mode & atf_fs_access_r ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt mode & atf_fs_access_w || mode & atf_fs_access_x);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (lstat(atf_fs_path_cstring(p), &st) == -1) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot get information from file %s",
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_fs_path_cstring(p));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* Early return if we are only checking for existence and the file
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * exists (stat call returned). */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (mode & atf_fs_access_f)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = false;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_user_is_root()) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok && !(mode & atf_fs_access_x)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* Allow root to read/write any file. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = true;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* Allow root to execute the file if any of its execution bits
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * are set. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = true;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok && (atf_user_euid() == st.st_uid)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRUSR)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_w) && (st.st_mode & S_IWUSR)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_x) && (st.st_mode & S_IXUSR));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok && atf_user_is_member_of_group(st.st_gid)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRGRP)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_w) && (st.st_mode & S_IWGRP)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_x) && (st.st_mode & S_IXGRP));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok && ((atf_user_euid() != st.st_uid) &&
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt !atf_user_is_member_of_group(st.st_gid))) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IROTH)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_w) && (st.st_mode & S_IWOTH)) ||
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt ((mode & atf_fs_access_x) && (st.st_mode & S_IXOTH));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!ok)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(EACCES, "Access check failed");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_exists(const atf_fs_path_t *p, bool *b)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_eaccess(p, atf_fs_access_f);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_free(err);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *b = false;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *b = true;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_getcwd(atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *cwd;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#if defined(HAVE_GETCWD_DYN)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt cwd = getcwd(NULL, 0);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt cwd = getcwd(NULL, MAXPATHLEN);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt#endif
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (cwd == NULL) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot determine current directory");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_fs_path_init_fmt(p, "%s", cwd);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt free(cwd);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_mkdtemp(atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *buf;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!check_umask(S_IRWXU, S_IRWXU)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask());
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = copy_contents(p, &buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = do_mkdtemp(buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out_buf;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt replace_contents(p, buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INV(!atf_is_error(err));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout_buf:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt free(buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt char *buf;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt int fd;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (!check_umask(S_IRWXU, S_IRWXU)) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask());
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = copy_contents(p, &buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = do_mkstemp(buf, &fd);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (atf_is_error(err))
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt goto out_buf;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt replace_contents(p, buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt *fdout = fd;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt INV(!atf_is_error(err));
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout_buf:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt free(buf);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntout:
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_rmdir(const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (rmdir(atf_fs_path_cstring(p))) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (errno == EEXIST) {
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt /* Some operating systems (e.g. OpenSolaris 200906) return
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * EEXIST instead of ENOTEMPTY for non-empty directories.
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * Homogenize the return value so that callers don't need
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt * to bother about differences in operating systems. */
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt errno = ENOTEMPTY;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt }
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot remove directory");
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt } else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_error_t
ef421f66f47224a42073deaf087378c5d0c9952eEvan Huntatf_fs_unlink(const atf_fs_path_t *p)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt{
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt atf_error_t err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt const char *path;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt path = atf_fs_path_cstring(p);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt if (unlink(path) != 0)
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_libc_error(errno, "Cannot unlink file: '%s'", path);
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt else
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt err = atf_no_error();
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt return err;
ef421f66f47224a42073deaf087378c5d0c9952eEvan Hunt}