summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-14 13:35:23 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-14 13:35:23 -0500
commit585a9dafe86b51a2d120d107bb04a77b34cc1af0 (patch)
tree7f715d1d8c8a4dd711548f3f19528722a739db00 /eval.c
parent94432cd2a3185ce97dfd28a6a1b236449d91268f (diff)
downloadbfs-585a9dafe86b51a2d120d107bb04a77b34cc1af0.tar.xz
Implement -lname and -ilname.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 63c1348..26596f0 100644
--- a/eval.c
+++ b/eval.c
@@ -308,6 +308,42 @@ bool eval_links(const struct expr *expr, struct eval_state *state) {
}
/**
+ * -i?lname test.
+ */
+bool eval_lname(const struct expr *expr, struct eval_state *state) {
+ struct BFTW *ftwbuf = state->ftwbuf;
+ if (ftwbuf->typeflag != BFTW_LNK) {
+ return false;
+ }
+
+ const struct stat *statbuf = fill_statbuf(state);
+ if (!statbuf) {
+ return false;
+ }
+
+ size_t size = statbuf->st_size + 1;
+ char *name = malloc(size);
+ if (!name) {
+ eval_error(state);
+ return false;
+ }
+
+ ssize_t ret = readlinkat(ftwbuf->at_fd, ftwbuf->at_path, name, size);
+ if (ret < 0) {
+ eval_error(state);
+ return false;
+ } else if (ret >= size) {
+ return false;
+ }
+
+ name[ret] = '\0';
+
+ bool match = fnmatch(expr->sdata, name, expr->idata) == 0;
+ free(name);
+ return match;
+}
+
+/**
* -i?name test.
*/
bool eval_name(const struct expr *expr, struct eval_state *state) {