summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-10-29 16:24:23 -0400
committerTavian Barnes <tavianator@tavianator.com>2016-10-29 16:35:53 -0400
commite07cbd10f59a8197a0b5fc789ea3781a863548e8 (patch)
treeb6233560681d578072173a2bc97eddefcf70e3d2 /eval.c
parent9def6eb2932fef0d049e7b2996e5c69b07f1ca20 (diff)
downloadbfs-e07cbd10f59a8197a0b5fc789ea3781a863548e8.tar.xz
Implement -perm.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index f930bac..54d9a7c 100644
--- a/eval.c
+++ b/eval.c
@@ -636,6 +636,37 @@ bool eval_path(const struct expr *expr, struct eval_state *state) {
}
/**
+ * -perm test.
+ */
+bool eval_perm(const struct expr *expr, struct eval_state *state) {
+ const struct stat *statbuf = fill_statbuf(state);
+ if (!statbuf) {
+ return false;
+ }
+
+ mode_t mode = statbuf->st_mode;
+ mode_t target;
+ if (state->ftwbuf->typeflag == BFTW_DIR) {
+ target = expr->dir_mode;
+ } else {
+ target = expr->file_mode;
+ }
+
+ switch (expr->mode_cmp) {
+ case MODE_EXACT:
+ return (mode & 07777) == target;
+
+ case MODE_ALL:
+ return (mode & target) == target;
+
+ case MODE_ANY:
+ return !(mode & target) == !target;
+ }
+
+ return false;
+}
+
+/**
* -print action.
*/
bool eval_print(const struct expr *expr, struct eval_state *state) {