]> gitweb.michael.orlitzky.com - apply-default-acl.git/blobdiff - src/apply-default-acl.c
Replace nftw() with manual recursion in apply_default_acl().
[apply-default-acl.git] / src / apply-default-acl.c
index d83e428756cadbe4d94d666bdee739e6a7c46a76..68de557b1511fbe90e117bab1175194d3b6069ea 100644 (file)
@@ -5,13 +5,8 @@
  *
  */
 
-/* On Linux, ftw.h needs this special voodoo to work. */
-#define _XOPEN_SOURCE 500
-#define _GNU_SOURCE
-
 #include <errno.h>   /* EINVAL */
 #include <fcntl.h>   /* AT_FOO constants */
-#include <ftw.h>     /* nftw() et al. */
 #include <getopt.h>  /* getopt_long() */
 #include <stdbool.h> /* the "bool" type */
 #include <stdio.h>   /* perror() */
@@ -24,8 +19,6 @@
  * else for big ones. */
 #define EXIT_ERROR 2
 
-#define NFTW_ERROR -1
-
 
 /**
  * @brief Determine whether or not the given path is accessible.
@@ -86,124 +79,6 @@ void usage(const char* program_name) {
 }
 
 
-/**
- * @brief Wrapper around @c apply_default_acl() for use with @c nftw().
- *
- * For parameter information, see the @c nftw man page.
- *
- * @return If the ACL was applied to @c target successfully, we return
- *   @c FTW_CONTINUE to signal to @ nftw() that we should proceed onto
- *   the next file or directory. Otherwise, we return @c FTW_STOP to
- *   signal failure.
- *
- */
-int apply_default_acl_nftw(const char *target,
-                           const struct stat *sp,
-                           int info,
-                           struct FTW *ftw) {
-
-  if (target == NULL) {
-    errno = EINVAL;
-    perror("apply_default_acl_nftw (args)");
-    return ACL_ERROR;
-  }
-
-
-  /* The apply_default_acl() function could make use of the stat
-     struct pointer sp, but for safety we choose to stat the result of
-     safe_open() ourselves. */
-  if (apply_default_acl(target, false) == ACL_ERROR) {
-    /* I guess we do want to bail out for serious/unexpected errors? */
-    return ACL_ERROR;
-  }
-
-  /* We don't want to kill the tree walk because we it a symlink. */
-  return 0;
-}
-
-
-
-/**
- * @brief Wrapper around @c apply_default_acl() for use with @c nftw().
- *
- * This is identical to @c apply_default_acl_nftw(), except it passes
- * @c true to @c apply_default_acl() as its no_exec_mask argument.
- *
- */
-int apply_default_acl_nftw_x(const char *target,
-                             const struct stat *sp,
-                             int info,
-                             struct FTW *ftw) {
-
-  if (target == NULL) {
-    errno = EINVAL;
-    perror("apply_default_acl_nftw_x (args)");
-    return ACL_ERROR;
-  }
-
-  /* The apply_default_acl() function could make use of the stat
-     struct pointer sp, but for safety we choose to stat the result of
-     safe_open() ourselves. */
-  if (apply_default_acl(target, true) == ACL_ERROR) {
-    /* I guess we do want to bail out for serious/unexpected errors? */
-    return ACL_ERROR;
-  }
-
-  /* We don't want to kill the tree walk because we it a symlink. */
-  return 0;
-}
-
-
-
-/**
- * @brief Recursive version of @c apply_default_acl().
- *
- * If @c target is a directory, we use @c nftw() to call @c
- * apply_default_acl() recursively on all of its children. Otherwise,
- * we just delegate to @c apply_default_acl().
- *
- * @param target
- *   The root (path) of the recursive application.
- *
- * @param no_exec_mask
- *   The value (either true or false) of the --no-exec-mask flag.
- *
- * @return
- *   If @c nftw() fails with a serious error (returns NFTW_ERROR),
- *   then we return @c ACL_ERROR. Otherwise, we return @c ACL_SUCCESS.
- */
-int apply_default_acl_recursive(const char *target, bool no_exec_mask) {
-  if (target == NULL) {
-    errno = EINVAL;
-    perror("apply_default_acl_recursive (args)");
-    return ACL_ERROR;
-  }
-
-  int max_levels = 256;
-  int flags = FTW_MOUNT | FTW_PHYS;
-
-  /* There are two separate functions that could be passed to
-     nftw(). One passes no_exec_mask = true to apply_default_acl(),
-     and the other passes no_exec_mask = false. Since the function we
-     pass to nftw() cannot have parameters, we have to create separate
-     options and make the decision here. */
-  int (*fn)(const char *, const struct stat *, int, struct FTW *) = NULL;
-  fn = no_exec_mask ? apply_default_acl_nftw_x : apply_default_acl_nftw;
-
-  int nftw_result = nftw(target, fn, max_levels, flags);
-
-  /* nftw will itself return NFTW_ERROR on errors like malloc failure,
-     and since the only non-success value that "fn" can return us
-     ACL_ERROR == NFTW_ERROR, this covers all error cases. */
-  if (nftw_result == NFTW_ERROR) {
-    perror("apply_default_acl_recursive (nftw)");
-    return ACL_ERROR;
-  }
-
-  /* Beware: nftw indicates success with 0, but ACL_SUCCESS != 0. */
-  return ACL_SUCCESS;
-}
-
 
 
 /**
@@ -254,6 +129,7 @@ int main(int argc, char* argv[]) {
   int result = EXIT_SUCCESS;
 
   int arg_index = 1;
+  int reapp_result = ACL_SUCCESS;
   for (arg_index = optind; arg_index < argc; arg_index++) {
     const char* target = argv[arg_index];
 
@@ -268,9 +144,7 @@ int main(int argc, char* argv[]) {
       continue;
     }
 
-    int (*f)(const char *, bool) = recursive ? apply_default_acl_recursive
-                                             : apply_default_acl;
-    int reapp_result = f(target, no_exec_mask);
+    reapp_result = apply_default_acl(target, no_exec_mask, recursive);
 
     if (result == EXIT_SUCCESS && reapp_result == ACL_FAILURE) {
       /* We don't want to turn an error into a (less-severe) failure. */