From a605ae954b9b9c378d6a0b21058f4b4b410f8ab7 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 27 Sep 2016 15:23:33 -0400 Subject: [PATCH] Print an error if any targets do not exist. This commit fixes the last known bug, that apply-default-acl can be called on a file that does not exist and no error is output. A new function, path_accessible(), was added and it uses the faccessat() POSIX call to check whether or not the current effective user/group can access a path. We then call the new path_accessible() on every target given on the command line. If any do not exist, an error is printed: $ ./apply-default-acl derp ./apply-default-acl: derp: no such file or directory Along with this change comes a version bump to v0.0.5 in configure.ac. Some minor reorganization was done in configure.ac as well. --- configure.ac | 14 ++++++------ src/apply-default-acl.c | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 0ec9c63..4f4f2da 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT([apply-default-acl], [0.0.4], [michael@orlitzky.com]) +AC_INIT([apply-default-acl], [0.0.5], [michael@orlitzky.com]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/apply-default-acl.c]) AC_CONFIG_FILES([Makefile src/Makefile]) @@ -10,12 +10,14 @@ AC_CONFIG_FILES([Makefile src/Makefile]) # Checks for programs. AC_PROG_CC -# Checks for header files. -AC_CHECK_HEADERS([limits.h stdlib.h string.h sys/acl.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_HEADER_STDBOOL +# Predefined header checks. +AC_HEADER_STAT # sys/stat.h +AC_HEADER_STDBOOL # stdbool.h +AC_HEADER_STDC # stdlib.h string.h (implied: errno.h limits.h stdio.h) AC_TYPE_MODE_T +# Check for header files not covered by the predefined macros above. +AC_CHECK_HEADERS([ fcntl.h ftw.h getopt.h libgen.h sys/acl.h sys/libacl.h ]) +AC_CHECK_HEADERS([ sys/types.h unistd.h ]) AC_OUTPUT diff --git a/src/apply-default-acl.c b/src/apply-default-acl.c index 6900a63..0c43af7 100644 --- a/src/apply-default-acl.c +++ b/src/apply-default-acl.c @@ -10,6 +10,7 @@ #define _GNU_SOURCE #include +#include /* AT_FOO constants */ #include /* nftw() et al. */ #include #include /* dirname() */ @@ -88,6 +89,42 @@ bool is_regular_file(const char* path) { +/** + * @brief Determine whether or not the given path is accessible. + * + * @param path + * The path to test. + * + * @return true if @c path is accessible to the current effective + * user/group, false otherwise. + */ +bool path_accessible(const char* path) { + if (path == NULL) { + return false; + } + + /* Test for access using the effective user and group rather than + the real one. */ + int flags = AT_EACCESS; + + /* Don't follow symlinks when checking for a path's existence, + since we won't follow them to set its ACLs either. */ + flags |= AT_SYMLINK_NOFOLLOW; + + /* If the path is relative, interpret it relative to the current + working directory (just like the access() system call). */ + int result = faccessat(AT_FDCWD, path, F_OK, flags); + + if (result == 0) { + return true; + } + else { + return false; + } +} + + + /** * @brief Determine whether or not the given path is a directory. * @@ -971,6 +1008,17 @@ int main(int argc, char* argv[]) { const char* target = argv[arg_index]; bool reapp_result = false; + /* Make sure we can access the given path before we go out of our + * way to please it. Doing this check outside of + * apply_default_acl() lets us spit out a better error message for + * typos, too. + */ + if (!path_accessible(target)) { + fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], target); + result = EXIT_FAILURE; + continue; + } + if (recursive) { reapp_result = apply_default_acl_recursive(target, no_exec_mask); } -- 2.44.2