summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmdline.h14
-rw-r--r--diag.c10
-rw-r--r--exec.c11
-rw-r--r--exec.h4
-rw-r--r--fsade.c88
-rw-r--r--parse.c55
6 files changed, 95 insertions, 87 deletions
diff --git a/cmdline.h b/cmdline.h
index 422fc6c..bb75798 100644
--- a/cmdline.h
+++ b/cmdline.h
@@ -87,16 +87,18 @@ struct cmdline {
/** bftw() search strategy. */
enum bftw_strategy strategy;
- /** Optimization level. */
+ /** Optimization level (-O). */
int optlevel;
- /** Debugging flags. */
+ /** Debugging flags (-D). */
enum debug_flags debug;
- /** Whether to only handle paths with xargs-safe characters. */
- bool xargs_safe;
- /** Whether to ignore deletions that race with bfs. */
+ /** Whether to ignore deletions that race with bfs (-ignore_readdir_race). */
bool ignore_races;
- /** Whether to only return unique files. */
+ /** Whether to only return unique files (-unique). */
bool unique;
+ /** Whether to print warnings (-warn/-nowarn). */
+ bool warn;
+ /** Whether to only handle paths with xargs-safe characters (-X). */
+ bool xargs_safe;
/** The command line expression. */
struct expr *expr;
diff --git a/diag.c b/diag.c
index bdbf98e..f43ed2e 100644
--- a/diag.c
+++ b/diag.c
@@ -47,12 +47,14 @@ void bfs_verror(const struct cmdline *cmdline, const char *format, va_list args)
}
void bfs_vwarning(const struct cmdline *cmdline, const char *format, va_list args) {
- int error = errno;
+ if (cmdline->warn) {
+ int error = errno;
- bfs_warning_prefix(cmdline);
+ bfs_warning_prefix(cmdline);
- errno = error;
- cvfprintf(cmdline->cerr, format, args);
+ errno = error;
+ cvfprintf(cmdline->cerr, format, args);
+ }
}
void bfs_error_prefix(const struct cmdline *cmdline) {
diff --git a/exec.c b/exec.c
index ce42f1a..3c791d7 100644
--- a/exec.c
+++ b/exec.c
@@ -37,7 +37,7 @@
/** Print some debugging info. */
BFS_FORMATTER(2, 3)
static void bfs_exec_debug(const struct bfs_exec *execbuf, const char *format, ...) {
- if (!(execbuf->flags & BFS_EXEC_DEBUG)) {
+ if (!(execbuf->cmdline->debug & DEBUG_EXEC)) {
return;
}
@@ -123,6 +123,7 @@ struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, const st
}
execbuf->flags = flags;
+ execbuf->cmdline = cmdline;
execbuf->argv = NULL;
execbuf->argc = 0;
execbuf->argv_cap = 0;
@@ -133,10 +134,6 @@ struct bfs_exec *parse_bfs_exec(char **argv, enum bfs_exec_flags flags, const st
execbuf->wd_len = 0;
execbuf->ret = 0;
- if (cmdline->debug & DEBUG_EXEC) {
- execbuf->flags |= BFS_EXEC_DEBUG;
- }
-
size_t i;
for (i = 1; ; ++i) {
const char *arg = argv[i];
@@ -391,9 +388,9 @@ fail:
}
} else if (WIFSIGNALED(wstatus)) {
int sig = WTERMSIG(wstatus);
- bfs_exec_debug(execbuf, "Command '%s' terminated by signal %d\n", execbuf->argv[0], sig);
+ bfs_warning(execbuf->cmdline, "Command '${ex}%s${rs}' terminated by signal %d\n", execbuf->argv[0], sig);
} else {
- bfs_exec_debug(execbuf, "Command '%s' terminated abnormally\n", execbuf->argv[0]);
+ bfs_warning(execbuf->cmdline, "Command '${ex}%s${rs}' terminated abnormally\n", execbuf->argv[0]);
}
errno = 0;
diff --git a/exec.h b/exec.h
index 78cdbd2..ab3f59a 100644
--- a/exec.h
+++ b/exec.h
@@ -36,8 +36,6 @@ enum bfs_exec_flags {
BFS_EXEC_CHDIR = 1 << 1,
/** Pass multiple files at once to the command (-exec ... {} +). */
BFS_EXEC_MULTI = 1 << 2,
- /** Print debugging information (-D exec). */
- BFS_EXEC_DEBUG = 1 << 3,
};
/**
@@ -47,6 +45,8 @@ struct bfs_exec {
/** Flags for this exec buffer. */
enum bfs_exec_flags flags;
+ /** The overall command line. */
+ const struct cmdline *cmdline;
/** Command line template. */
char **tmpl_argv;
/** Command line template size. */
diff --git a/fsade.c b/fsade.c
index 668f586..a4c50ee 100644
--- a/fsade.c
+++ b/fsade.c
@@ -126,29 +126,10 @@ static bool is_absence_error(int error) {
#if BFS_CAN_CHECK_ACL
-/** Check if any ACLs of the given type are non-trivial. */
-static int bfs_check_acl_type(const char *path, acl_type_t type) {
- acl_t acl = acl_get_file(path, type);
- if (!acl) {
- if (is_absence_error(errno)) {
- return 0;
- } else {
- return -1;
- }
- }
-
+/** Check if a POSIX.1e ACL is non-trivial. */
+static int bfs_check_posix1e_acl(acl_t acl, bool ignore_required) {
int ret = 0;
-#if __FreeBSD__
- int trivial;
- if (acl_is_trivial_np(acl, &trivial) < 0) {
- ret = -1;
- } else if (trivial) {
- ret = 0;
- } else {
- ret = 1;
- }
-#else
acl_entry_t entry;
for (int status = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
#if __APPLE__
@@ -160,27 +141,46 @@ static int bfs_check_acl_type(const char *path, acl_type_t type) {
#endif
status = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
#if defined(ACL_USER_OBJ) && defined(ACL_GROUP_OBJ) && defined(ACL_OTHER)
- acl_tag_t tag;
- if (acl_get_tag_type(entry, &tag) != 0) {
- continue;
- }
- if (tag != ACL_USER_OBJ && tag != ACL_GROUP_OBJ && tag != ACL_OTHER) {
- ret = 1;
- break;
+ if (ignore_required) {
+ acl_tag_t tag;
+ if (acl_get_tag_type(entry, &tag) != 0) {
+ ret = -1;
+ continue;
+ }
+ if (tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER) {
+ continue;
+ }
}
-#else
+#endif
+
ret = 1;
break;
-#endif
}
-#endif // !__FreeBSD__
- int error = errno;
- acl_free(acl);
- errno = error;
return ret;
}
+/** Check if an ACL of the given type is non-trivial. */
+static int bfs_check_acl_type(acl_t acl, acl_type_t type) {
+ if (type == ACL_TYPE_DEFAULT) {
+ // For directory default ACLs, any entries make them non-trivial
+ return bfs_check_posix1e_acl(acl, false);
+ }
+
+#if __FreeBSD__
+ int trivial;
+ if (acl_is_trivial_np(acl, &trivial) < 0) {
+ return -1;
+ } else if (trivial) {
+ return 0;
+ } else {
+ return 1;
+ }
+#endif
+
+ return bfs_check_posix1e_acl(acl, true);
+}
+
int bfs_check_acl(const struct BFTW *ftwbuf) {
static const acl_type_t acl_types[] = {
#if __APPLE__
@@ -205,18 +205,30 @@ int bfs_check_acl(const struct BFTW *ftwbuf) {
const char *path = fake_at(ftwbuf);
- int ret = -1;
+ int ret = -1, error = 0;
for (size_t i = 0; i < n_acl_types && ret <= 0; ++i) {
- if (acl_types[i] == ACL_TYPE_DEFAULT && ftwbuf->typeflag != BFTW_DIR) {
+ acl_type_t type = acl_types[i];
+
+ if (type == ACL_TYPE_DEFAULT && ftwbuf->typeflag != BFTW_DIR) {
// ACL_TYPE_DEFAULT is supported only for directories,
// otherwise acl_get_file() gives EACCESS
continue;
}
- ret = bfs_check_acl_type(path, acl_types[i]);
+ acl_t acl = acl_get_file(path, type);
+ if (!acl) {
+ error = errno;
+ if (is_absence_error(error)) {
+ ret = 0;
+ }
+ continue;
+ }
+
+ ret = bfs_check_acl_type(acl, type);
+ error = errno;
+ acl_free(acl);
}
- int error = errno;
free_fake_at(ftwbuf, path);
errno = error;
return ret;
diff --git a/parse.c b/parse.c
index 891e6e1..f68eaf2 100644
--- a/parse.c
+++ b/parse.c
@@ -337,8 +337,6 @@ struct parser_state {
enum use_color use_color;
/** Whether a -print action is implied. */
bool implicit_print;
- /** Whether warnings are enabled (see -warn, -nowarn). */
- bool warn;
/** Whether the expression has started. */
bool expr_started;
/** Whether any non-option arguments have been encountered. */
@@ -704,7 +702,7 @@ static struct expr *parse_unary_flag(struct parser_state *state) {
static struct expr *parse_option(struct parser_state *state, size_t argc) {
const char *arg = *parser_advance(state, T_OPTION, argc);
- if (state->warn && state->non_option_seen) {
+ if (state->non_option_seen) {
parse_warning(state,
"The '%s' option applies to the entire command line. For clarity, place\n"
"it before any non-option arguments.\n\n",
@@ -961,7 +959,7 @@ static struct expr *parse_optlevel(struct parser_state *state, int arg1, int arg
return NULL;
}
- if (state->warn && *optlevel > 4) {
+ if (*optlevel > 4) {
parse_warning(state, "%s is the same as -O4.\n\n", state->argv[0]);
}
@@ -1569,12 +1567,10 @@ static struct expr *parse_ls(struct parser_state *state, int arg1, int arg2) {
* Parse -mount.
*/
static struct expr *parse_mount(struct parser_state *state, int arg1, int arg2) {
- if (state->warn) {
- parse_warning(state,
- "In the future, %s will skip mount points entirely, unlike\n"
- "-xdev, due to http://austingroupbugs.net/view.php?id=1133.\n\n",
- state->argv[0]);
- }
+ parse_warning(state,
+ "In the future, %s will skip mount points entirely, unlike\n"
+ "-xdev, due to http://austingroupbugs.net/view.php?id=1133.\n\n",
+ state->argv[0]);
state->cmdline->flags |= BFTW_XDEV;
state->mount_arg = state->argv[0];
@@ -1783,10 +1779,7 @@ static struct expr *parse_nohidden(struct parser_state *state, int arg1, int arg
* Parse -noleaf.
*/
static struct expr *parse_noleaf(struct parser_state *state, int arg1, int arg2) {
- if (state->warn) {
- parse_warning(state, "bfs does not apply the optimization that %s inhibits.\n\n", state->argv[0]);
- }
-
+ parse_warning(state, "bfs does not apply the optimization that %s inhibits.\n\n", state->argv[0]);
return parse_nullary_option(state);
}
@@ -2493,7 +2486,7 @@ fail:
* Parse -(no)?warn.
*/
static struct expr *parse_warn(struct parser_state *state, int warn, int arg2) {
- state->warn = warn;
+ state->cmdline->warn = warn;
return parse_nullary_positional_option(state);
}
@@ -3310,23 +3303,21 @@ static struct expr *parse_whole_expr(struct parser_state *state) {
}
}
- if (state->warn) {
- if (state->mount_arg && state->xdev_arg) {
- parse_warning(state, "%s is redundant in the presence of %s.\n\n", state->xdev_arg, state->mount_arg);
- }
+ if (state->mount_arg && state->xdev_arg) {
+ parse_warning(state, "%s is redundant in the presence of %s.\n\n", state->xdev_arg, state->mount_arg);
+ }
- if (state->depth_arg && state->prune_arg) {
- parse_warning(state, "%s does not work in the presence of %s.\n", state->prune_arg, state->depth_arg);
+ if (state->cmdline->warn && state->depth_arg && state->prune_arg) {
+ parse_warning(state, "%s does not work in the presence of %s.\n", state->prune_arg, state->depth_arg);
- if (state->interactive) {
- fprintf(stderr, "Do you want to continue? ");
- if (ynprompt() == 0) {
- goto fail;
- }
+ if (state->interactive) {
+ fprintf(stderr, "Do you want to continue? ");
+ if (ynprompt() == 0) {
+ goto fail;
}
-
- fprintf(stderr, "\n");
}
+
+ fprintf(stderr, "\n");
}
return expr;
@@ -3488,9 +3479,10 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
cmdline->strategy = BFTW_BFS;
cmdline->optlevel = 3;
cmdline->debug = 0;
- cmdline->xargs_safe = false;
cmdline->ignore_races = false;
cmdline->unique = false;
+ cmdline->warn = false;
+ cmdline->xargs_safe = false;
cmdline->expr = &expr_true;
cmdline->nopen_files = 0;
@@ -3544,6 +3536,10 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
bool stdout_tty = isatty(STDOUT_FILENO);
bool stderr_tty = isatty(STDERR_FILENO);
+ if (!getenv("POSIXLY_CORRECT")) {
+ cmdline->warn = stdin_tty;
+ }
+
struct parser_state state = {
.cmdline = cmdline,
.argv = cmdline->argv + 1,
@@ -3553,7 +3549,6 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
.interactive = stdin_tty && stderr_tty,
.use_color = use_color,
.implicit_print = true,
- .warn = stdin_tty,
.non_option_seen = false,
.just_info = false,
.last_arg = NULL,