summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-14 16:56:36 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-14 16:56:36 -0500
commit9cba8770a2f08457735556b480164fcea2853de8 (patch)
treea61c3d48de40029d189cd598bfffd6ebae709f92
parent30d7fa271c1b0a2fdcc9ae4123c902a72aa4b926 (diff)
downloadbfs-9cba8770a2f08457735556b480164fcea2853de8.tar.xz
Implement -user and -group.
-rw-r--r--parse.c83
-rwxr-xr-xtests.sh18
2 files changed, 100 insertions, 1 deletions
diff --git a/parse.c b/parse.c
index e1e3c62..86404c9 100644
--- a/parse.c
+++ b/parse.c
@@ -10,10 +10,13 @@
*********************************************************************/
#include "bfs.h"
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
+#include <grp.h>
#include <limits.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -428,6 +431,82 @@ static struct expr *parse_depth(struct parser_state *state, const char *option,
}
/**
+ * Parse -group.
+ */
+static struct expr *parse_group(struct parser_state *state, const char *option) {
+ struct expr *expr = parse_test_sdata(state, option, eval_gid);
+ if (!expr) {
+ return NULL;
+ }
+
+ const char *error;
+
+ errno = 0;
+ struct group *grp = getgrnam(expr->sdata);
+ if (grp) {
+ expr->idata = grp->gr_gid;
+ } else if (errno != 0) {
+ error = strerror(errno);
+ goto error;
+ } else if (isdigit(expr->sdata[0])) {
+ if (!parse_int(state, expr->sdata, &expr->idata)) {
+ goto fail;
+ }
+ } else {
+ error = "No such group";
+ goto error;
+ }
+
+ return expr;
+
+error:
+ pretty_error(state->cmdline->stderr_colors,
+ "%s %s: %s\n", option, expr->sdata, error);
+
+fail:
+ free_expr(expr);
+ return NULL;
+}
+
+/**
+ * Parse -user.
+ */
+static struct expr *parse_user(struct parser_state *state, const char *option) {
+ struct expr *expr = parse_test_sdata(state, option, eval_uid);
+ if (!expr) {
+ return NULL;
+ }
+
+ const char *error;
+
+ errno = 0;
+ struct passwd *pwd = getpwnam(expr->sdata);
+ if (pwd) {
+ expr->idata = pwd->pw_uid;
+ } else if (errno != 0) {
+ error = strerror(errno);
+ goto error;
+ } else if (isdigit(expr->sdata[0])) {
+ if (!parse_int(state, expr->sdata, &expr->idata)) {
+ goto fail;
+ }
+ } else {
+ error = "No such user";
+ goto error;
+ }
+
+ return expr;
+
+error:
+ pretty_error(state->cmdline->stderr_colors,
+ "%s %s: %s\n", option, expr->sdata, error);
+
+fail:
+ free_expr(expr);
+ return NULL;
+}
+
+/**
* Set the FNM_CASEFOLD flag, if supported.
*/
static struct expr *set_fnm_casefold(const struct parser_state *state, const char *option, struct expr *expr, bool casefold) {
@@ -680,6 +759,8 @@ static struct expr *parse_literal(struct parser_state *state) {
case 'g':
if (strcmp(arg, "-gid") == 0) {
return parse_test_icmp(state, arg, eval_gid);
+ } else if (strcmp(arg, "-group") == 0) {
+ return parse_group(state, arg);
}
break;
@@ -786,6 +867,8 @@ static struct expr *parse_literal(struct parser_state *state) {
case 'u':
if (strcmp(arg, "-uid") == 0) {
return parse_test_icmp(state, arg, eval_uid);
+ } else if (strcmp(arg, "-user") == 0) {
+ return parse_user(state, arg);
}
break;
diff --git a/tests.sh b/tests.sh
index e6b52be..baaac3e 100755
--- a/tests.sh
+++ b/tests.sh
@@ -239,7 +239,23 @@ function test_0042() {
find_diff -L "$links" -lname '[AQ]' 2>/dev/null
}
-for i in {1..42}; do
+function test_0043() {
+ find_diff -L "$basic" -user "$(id -un)"
+}
+
+function test_0044() {
+ find_diff -L "$basic" -user "$(id -u)"
+}
+
+function test_0045() {
+ find_diff -L "$basic" -group "$(id -gn)"
+}
+
+function test_0046() {
+ find_diff -L "$basic" -group "$(id -g)"
+}
+
+for i in {1..46}; do
test="test_$(printf '%04d' $i)"
"$test" "$dir"
status=$?