#include "libadacl.h"
+/* We exit with EXIT_FAILURE for small errors, but we need something
+ * else for big ones. */
+#define EXIT_ERROR 2
#define NFTW_ERROR -1
int info,
struct FTW *ftw) {
- if (apply_default_acl_ex(target, sp, false)) {
- return FTW_CONTINUE;
- }
- else {
- return FTW_STOP;
+ if (apply_default_acl_ex(target, sp, 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;
}
int info,
struct FTW *ftw) {
- if (apply_default_acl_ex(target, sp, true)) {
- return FTW_CONTINUE;
- }
- else {
- return FTW_STOP;
+ if (apply_default_acl_ex(target, sp, 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;
}
* 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.
*
* 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.
+ * If @c nftw() fails with a serious error (returns NFTW_ERROR),
+ * then we return @c ACL_ERROR. Otherwise, we return @c ACL_SUCCESS.
*/
-bool apply_default_acl_recursive(const char *target, bool no_exec_mask) {
+int apply_default_acl_recursive(const char *target, bool no_exec_mask) {
int max_levels = 256;
- int flags = FTW_PHYS; /* Don't follow links. */
+ 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(),
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.
- */
+ /* 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;
}
- return false;
+ /* Beware: nftw indicates success with 0, but ACL_SUCCESS != 0. */
+ return ACL_SUCCESS;
}
int arg_index = 1;
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
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);
- }
+ int (*f)(const char *, bool) = recursive ? apply_default_acl_recursive
+ : apply_default_acl;
+ int reapp_result = f(target, no_exec_mask);
- 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;