X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fapply-default-acl.c;h=7989c985ab8bbf4a8329a64bedab1b7330336f71;hb=0e4810e0a4e3ca231c1c526729d74200d7fef031;hp=e5b989ad9a585fe6224f16da93e969b34d07358c;hpb=a662358647653b8d7f4f2dbfc5ca2802f38c60c8;p=apply-default-acl.git diff --git a/src/apply-default-acl.c b/src/apply-default-acl.c index e5b989a..7989c98 100644 --- a/src/apply-default-acl.c +++ b/src/apply-default-acl.c @@ -5,12 +5,8 @@ * */ -/* On Linux, ftw.h needs this special voodoo to work. */ -#define _XOPEN_SOURCE 500 -#define _GNU_SOURCE - +#include /* EINVAL */ #include /* AT_FOO constants */ -#include /* nftw() et al. */ #include /* getopt_long() */ #include /* the "bool" type */ #include /* perror() */ @@ -19,6 +15,13 @@ #include "libadacl.h" +/* We exit with EXIT_FAILURE for small errors, but we need something + * else for big ones. */ +#define EXIT_ERROR 2 + +/* Prototypes */ +bool path_accessible(const char* path); +void usage(const char* program_name); /** @@ -62,121 +65,23 @@ bool path_accessible(const char* path) { * */ void usage(const char* program_name) { + if (program_name == NULL) { + /* ??? */ + return; + } + printf("Apply any applicable default ACLs to the given files or " - "directories.\n\n"); + "directories.\n\n"); printf("Usage: %s [flags] [ [ ...]]\n\n", - program_name); + program_name); printf("Flags:\n"); printf(" -h, --help Print this help message\n"); printf(" -r, --recursive Act on any given directories recursively\n"); - printf(" -x, --no-exec-mask Apply execute permissions unconditionally\n"); return; } -/** - * @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 (apply_default_acl_ex(target, sp, false)) { - return FTW_CONTINUE; - } - else { - return FTW_STOP; - } -} - - - -/** - * @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 (apply_default_acl_ex(target, sp, true)) { - return FTW_CONTINUE; - } - else { - return FTW_STOP; - } -} - - - -/** - * @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(). - * - * We ignore symlinks for consistency with chmod -r. - * - * @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 target is not a directory, we return the result of - * calling @c apply_default_acl() on @c target. Otherwise, we convert - * the return value of @c nftw(). If @c nftw() succeeds (returns 0), - * then we return @c true. Otherwise, we return @c false. - * \n\n - * If there is an error, it will be reported via @c perror, but - * we still return @c false. - */ -bool apply_default_acl_recursive(const char *target, bool no_exec_mask) { - int max_levels = 256; - int flags = FTW_PHYS; /* Don't follow links. */ - - /* 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); - - if (nftw_result == 0) { - /* Success */ - return true; - } - - /* nftw will return NFTW_ERROR on error, or if the supplied function - * (apply_default_acl_nftw) returns a non-zero result, nftw will - * return that. - */ - if (nftw_result == NFTW_ERROR) { - perror("apply_default_acl_recursive (nftw)"); - } - - return false; -} - /** @@ -195,13 +100,11 @@ int main(int argc, char* argv[]) { } bool recursive = false; - bool no_exec_mask = false; struct option long_options[] = { /* These options set a flag. */ {"help", no_argument, NULL, 'h'}, {"recursive", no_argument, NULL, 'r'}, - {"no-exec-mask", no_argument, NULL, 'x'}, {NULL, 0, NULL, 0} }; @@ -215,9 +118,6 @@ int main(int argc, char* argv[]) { case 'r': recursive = true; break; - case 'x': - no_exec_mask = true; - break; default: usage(argv[0]); return EXIT_FAILURE; @@ -227,9 +127,9 @@ 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]; - 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 @@ -237,22 +137,21 @@ int main(int argc, char* argv[]) { * typos, too. */ if (!path_accessible(target)) { - fprintf(stderr, "%s: %s: No such file or directory\n", argv[0], target); + perror(target); result = EXIT_FAILURE; continue; } - if (recursive) { - reapp_result = apply_default_acl_recursive(target, no_exec_mask); - } - else { - /* It's either a normal file, or we're not operating recursively. */ - reapp_result = apply_default_acl(target, no_exec_mask); - } + reapp_result = apply_default_acl(target, recursive); - if (!reapp_result) { + if (result == EXIT_SUCCESS && reapp_result == ACL_FAILURE) { + /* We don't want to turn an error into a (less-severe) failure. */ result = EXIT_FAILURE; } + if (reapp_result == ACL_ERROR) { + /* Turn both success and failure into an error, if we encounter one. */ + result = EXIT_ERROR; + } } return result;