X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Freapply_default_acl.c;h=a5e9d6cecc0f5ade5cb773f73a69a191dee5171f;hb=0175b9b5a508c68a9a34de46cfb6fe3b0c917c77;hp=a2b4307475752b061fd5304ffca8a18a6382bc05;hpb=9b560cbf082997fed089cbc24e994f94691fcd28;p=apply-default-acl.git diff --git a/src/reapply_default_acl.c b/src/reapply_default_acl.c index a2b4307..a5e9d6c 100644 --- a/src/reapply_default_acl.c +++ b/src/reapply_default_acl.c @@ -1,6 +1,10 @@ +/* On Linux, ftw.h needs this special voodoo to work. */ +#define _XOPEN_SOURCE 500 + #include -#include /* dirname() */ -#include /* PATH_MAX */ +#include /* nftw() et al. */ +#include /* dirname() */ +#include /* PATH_MAX */ #include #include #include @@ -415,7 +419,7 @@ int reapply_default_acl(const char* path) { int ace_result = any_can_execute(path); if (ace_result == -1) { - perror("reapply_default_acl_ng (any_can_execute)"); + perror("reapply_default_acl (any_can_execute)"); return -1; } @@ -424,7 +428,7 @@ int reapply_default_acl(const char* path) { acl_t defacl = acl_get_file(parent, ACL_TYPE_DEFAULT); if (defacl == (acl_t)NULL) { - perror("reapply_default_acl_ng (acl_get_file)"); + perror("reapply_default_acl (acl_get_file)"); return -1; } @@ -433,7 +437,7 @@ int reapply_default_acl(const char* path) { int wipe_result = wipe_acls(path); if (wipe_result == -1) { - perror("reapply_default_acl_ng (wipe_acls)"); + perror("reapply_default_acl (wipe_acls)"); result = -1; goto cleanup; } @@ -442,14 +446,14 @@ int reapply_default_acl(const char* path) { ACL with this one. */ acl_t acl = acl_get_file(path, ACL_TYPE_ACCESS); if (acl == (acl_t)NULL) { - perror("reapply_default_acl_ng (acl_get_file)"); + perror("reapply_default_acl (acl_get_file)"); return -1; } /* If it's a directory, inherit the parent's default. */ int inherit_result = inherit_default_acl(path, parent); if (inherit_result == -1) { - perror("reapply_default_acl_ng (inherit_acls)"); + perror("reapply_default_acl (inherit_acls)"); result = -1; goto cleanup; } @@ -472,7 +476,7 @@ int reapply_default_acl(const char* path) { acl_permset_t permset; int ps_result = acl_get_permset(entry, &permset); if (ps_result == -1) { - perror("reapply_default_acl_ng (acl_get_permset)"); + perror("reapply_default_acl (acl_get_permset)"); result = -1; goto cleanup; } @@ -488,14 +492,14 @@ int reapply_default_acl(const char* path) { masked, we have to do it manually. */ int d_result = acl_delete_perm(permset, ACL_EXECUTE); if (d_result == -1) { - perror("reapply_default_acl_ng (acl_delete_perm)"); + perror("reapply_default_acl (acl_delete_perm)"); result = -1; goto cleanup; } int sp_result = acl_set_permset(entry, permset); if (sp_result == -1) { - perror("reapply_default_acl_ng (acl_set_permset)"); + perror("reapply_default_acl (acl_set_permset)"); result = -1; goto cleanup; } @@ -505,7 +509,7 @@ int reapply_default_acl(const char* path) { /* Finally, add the permset to the access ACL. */ int set_result = acl_set_entry(&acl, entry); if (set_result == -1) { - perror("reapply_default_acl_ng (acl_set_entry)"); + perror("reapply_default_acl (acl_set_entry)"); result = -1; goto cleanup; } @@ -516,14 +520,14 @@ int reapply_default_acl(const char* path) { /* Catches the first acl_get_entry as well as the ones at the end of the loop. */ if (ge_result == -1) { - perror("reapply_default_acl_ng (acl_get_entry)"); + perror("reapply_default_acl (acl_get_entry)"); result = -1; goto cleanup; } int sf_result = acl_set_file(path, ACL_TYPE_ACCESS, acl); if (sf_result == -1) { - perror("reapply_default_acl_ng (acl_set_file)"); + perror("reapply_default_acl (acl_set_file)"); result = -1; goto cleanup; } @@ -540,20 +544,55 @@ void usage(char* program_name) { */ printf("Reapply any applicable default ACLs to the given files or " "directories.\n\n"); - printf("Usage: %s [ [ ...]]\n", program_name); + printf("Usage: %s [flags] [ [ ...]]\n\n", + program_name); + printf("Flags:\n"); + printf(" -h, --help Print this help message\n"); + printf(" -r, --recursive Act on any given directories recursively\n"); } -bool asked_for_help(int argc, char* argv[]) { +bool asked_for_flag(int argc, + char* argv[], + const char* short_flag, + const char* long_flag) { /* - * Check argv for either form of the "help" flag, -h or --help. + * Check argv for either form of the flag, e.g. -h or --help. */ int arg_index = 1; for (arg_index = 1; arg_index < argc; arg_index++) { - if (!strcmp(argv[arg_index], "-h")) { + if (!strcmp(argv[arg_index], short_flag)) { + return true; + } + if (!strcmp(argv[arg_index], long_flag)) { return true; } - if (!strcmp(argv[arg_index], "--help")) { + } + + return false; +} + + +bool asked_for_help(int argc, char* argv[]) { + return asked_for_flag(argc, argv, "-h", "--help"); +} + +bool asked_for_recursive(int argc, char* argv[]) { + return asked_for_flag(argc, argv, "-r", "--recursive"); +} + +bool is_flag(const char* arg) { + /* + * Is arg a command-line flag (e.g. --recursive)? + */ + char valid_flags[4][32] = { "-h", + "--help", + "-r", + "--recursive" }; + + int flag_index = 0; + for (flag_index = 0; flag_index < 4; flag_index++) { + if (!strcmp(arg, valid_flags[flag_index])) { return true; } } @@ -562,6 +601,61 @@ bool asked_for_help(int argc, char* argv[]) { } +int reapply_default_acl_nftw(const char *target, + const struct stat *s, + int info, + struct FTW *ftw) { + /* A wrapper around the reapply_default_acl() function for use with + * nftw(). We need to adjust the return value so that nftw() doesn't + * think we've failed. + */ + bool reapp_result = reapply_default_acl(target); + if (reapp_result) { + return 0; + } + else { + return 1; + } +} + + +bool reapply_default_acl_recursive(const char *target) { + /* Attempt to reapply default ACLs recursively. If target is a + * directory, we recurse through its entries. If not, we just + * reapply the default ACL to target. + * + * We ignore symlinks for consistency with chmod -r. + * + */ + if (!is_directory(target)) { + return reapply_default_acl(target); + } + + int max_levels = 256; + int flags = FTW_PHYS; /* Don't follow links. */ + + int nftw_result = nftw(target, + reapply_default_acl_nftw, + max_levels, + flags); + + if (nftw_result == 0) { + /* Success */ + return true; + } + + /* nftw will return -1 on error, or if the supplied function + * (reapply_default_acl_nftw) returns a non-zero result, nftw will + * return that. + */ + if (nftw_result == -1) { + perror("reapply_default_acl_recursive (nftw)"); + } + + return false; +} + + int main(int argc, char* argv[]) { /* * Call reapply_default_acl on each command-line argument. @@ -578,10 +672,27 @@ int main(int argc, char* argv[]) { int result = EXIT_SUCCESS; + bool recursive = asked_for_recursive(argc, argv); + int arg_index = 1; for (arg_index = 1; arg_index < argc; arg_index++) { + /* Don't bother stripping the flags from argv; just ignore + * an argument if it's one of our flags. + */ + if (is_flag(argv[arg_index])) { + continue; + } + const char* target = argv[arg_index]; - bool reapp_result = reapply_default_acl(target); + bool reapp_result = false; + + if (recursive) { + reapp_result = reapply_default_acl_recursive(target); + } + else { + /* It's either normal file, or we're not operating recursively. */ + reapp_result = reapply_default_acl(target); + } if (!reapp_result) { result = EXIT_FAILURE;