diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2016-02-14 13:35:23 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2016-02-14 13:35:23 -0500 |
commit | 585a9dafe86b51a2d120d107bb04a77b34cc1af0 (patch) | |
tree | 7f715d1d8c8a4dd711548f3f19528722a739db00 /eval.c | |
parent | 94432cd2a3185ce97dfd28a6a1b236449d91268f (diff) | |
download | bfs-585a9dafe86b51a2d120d107bb04a77b34cc1af0.tar.xz |
Implement -lname and -ilname.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -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) { |