]> gitweb.michael.orlitzky.com - apply-default-acl.git/blobdiff - src/apply-default-acl.c
Print an error if any targets do not exist.
[apply-default-acl.git] / src / apply-default-acl.c
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);
     }