]> gitweb.michael.orlitzky.com - apply-default-acl.git/commitdiff
Print an error if any targets do not exist.
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 27 Sep 2016 19:23:33 +0000 (15:23 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 27 Sep 2016 19:23:33 +0000 (15:23 -0400)
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
src/apply-default-acl.c

index 0ec9c63bb5cd01c718720895e1bacd88d78adac9..4f4f2da7161199ee4d851a7ee4bcef7bac92b21d 100644 (file)
@@ -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
index 6900a636e3ddc94b5045df620c8bf3ab772e73a6..0c43af7d975088c06019c8a44e69b66f14cdf63a 100644 (file)
@@ -10,6 +10,7 @@
 #define _GNU_SOURCE
 
 #include <errno.h>
+#include <fcntl.h>  /* AT_FOO constants */
 #include <ftw.h>    /* nftw() et al. */
 #include <getopt.h>
 #include <libgen.h> /* 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);
     }