diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2015-08-30 14:38:01 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2015-08-30 14:38:01 -0400 |
commit | e24ffc3a9ea195016a9543d9cc4bf99049f245ce (patch) | |
tree | c0c3eafca7a2938bffec2ff128ee80422eea17f1 | |
parent | da4b02f9d020f1d701e22921702b156d3c810f4c (diff) | |
download | bfs-e24ffc3a9ea195016a9543d9cc4bf99049f245ce.tar.xz |
Add -type support.
Fixes #2.
-rw-r--r-- | bfs.c | 57 | ||||
-rw-r--r-- | bftw.c | 42 | ||||
-rw-r--r-- | bftw.h | 20 |
3 files changed, 103 insertions, 16 deletions
@@ -212,6 +212,59 @@ static bool eval_nohidden(const char *fpath, const struct BFTW *ftwbuf, const cm } /** + * -type test. + */ +static bool eval_type(const char *fpath, const struct BFTW *ftwbuf, const cmdline *cl, const expression *expr, int *ret) { + return ftwbuf->typeflag == expr->data; +} + +/** + * Parse -type [bcdpfls]. + */ +static expression *parse_type(parser_state *state) { + const char *arg = state->argv[state->i]; + if (!arg) { + fputs("-type needs a value.\n", stderr); + return NULL; + } + + int typeflag = BFTW_UNKNOWN; + + switch (arg[0]) { + case 'b': + typeflag = BFTW_BLK; + break; + case 'c': + typeflag = BFTW_CHR; + break; + case 'd': + typeflag = BFTW_DIR; + break; + case 'p': + typeflag = BFTW_FIFO; + break; + case 'f': + typeflag = BFTW_REG; + break; + case 'l': + typeflag = BFTW_LNK; + break; + case 's': + typeflag = BFTW_SOCK; + break; + } + + if (typeflag == BFTW_UNKNOWN || arg[1] != '\0') { + fprintf(stderr, "Unknown type flag '%s'.\n", arg); + return NULL; + } + + ++state->i; + + return new_expression(NULL, NULL, eval_type, typeflag); +} + +/** * LITERAL : OPTION * | TEST * | ACTION @@ -235,8 +288,10 @@ static expression *parse_literal(parser_state *state) { return new_expression(NULL, NULL, eval_print, 0); } else if (strcmp(arg, "-prune") == 0) { return new_expression(NULL, NULL, eval_prune, 0); + } else if (strcmp(arg, "-type") == 0) { + return parse_type(state); } else { - fprintf(stderr, "Unknown argument '%s'.\n", arg); + fprintf(stderr, "Unknown argument '%s'.\n", arg); return NULL; } } @@ -489,14 +489,26 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr) { #if defined(_DIRENT_HAVE_D_TYPE) || defined(DT_DIR) switch (de->d_type) { + case DT_BLK: + ftwbuf.typeflag = BFTW_BLK; + break; + case DT_CHR: + ftwbuf.typeflag = BFTW_CHR; + break; case DT_DIR: - ftwbuf.typeflag = BFTW_D; + ftwbuf.typeflag = BFTW_DIR; break; - case DT_REG: - ftwbuf.typeflag = BFTW_R; + case DT_FIFO: + ftwbuf.typeflag = BFTW_FIFO; break; case DT_LNK: - ftwbuf.typeflag = BFTW_SL; + ftwbuf.typeflag = BFTW_LNK; + break; + case DT_REG: + ftwbuf.typeflag = BFTW_REG; + break; + case DT_SOCK: + ftwbuf.typeflag = BFTW_SOCK; break; } #endif @@ -508,14 +520,26 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr) { ftwbuf.statbuf = &sb; switch (sb.st_mode & S_IFMT) { + case S_IFBLK: + ftwbuf.typeflag = BFTW_BLK; + break; + case S_IFCHR: + ftwbuf.typeflag = BFTW_CHR; + break; case S_IFDIR: - ftwbuf.typeflag = BFTW_D; + ftwbuf.typeflag = BFTW_DIR; break; - case S_IFREG: - ftwbuf.typeflag = BFTW_R; + case S_IFIFO: + ftwbuf.typeflag = BFTW_FIFO; break; case S_IFLNK: - ftwbuf.typeflag = BFTW_SL; + ftwbuf.typeflag = BFTW_LNK; + break; + case S_IFREG: + ftwbuf.typeflag = BFTW_REG; + break; + case S_IFSOCK: + ftwbuf.typeflag = BFTW_SOCK; break; } } @@ -525,7 +549,7 @@ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr) { switch (action) { case BFTW_CONTINUE: - if (ftwbuf.typeflag == BFTW_D) { + if (ftwbuf.typeflag == BFTW_DIR) { dircache_entry *next = dircache_add(&cache, current, de->d_name); if (!next) { goto fail; @@ -66,16 +66,24 @@ typedef int bftw_fn(const char *fpath, const struct BFTW *ftwbuf, void *ptr); */ int bftw(const char *dirpath, bftw_fn *fn, int nopenfd, int flags, void *ptr); +/** typeflag: Block device. */ +#define BFTW_BLK 0 +/** typeflag: Character device. */ +#define BFTW_CHR 1 /** typeflag: Directory. */ -#define BFTW_D 0 -/** typeflag: Regular file. */ -#define BFTW_R 1 +#define BFTW_DIR 2 +/** typeflag: Pipe. */ +#define BFTW_FIFO 3 /** typeflag: Symbolic link. */ -#define BFTW_SL 2 +#define BFTW_LNK 4 +/** typeflag: Regular file. */ +#define BFTW_REG 5 +/** typeflag: Socket. */ +#define BFTW_SOCK 6 /** typeflag: Unknown type. */ -#define BFTW_UNKNOWN 3 +#define BFTW_UNKNOWN 7 /** typeflag: An error occurred for this file. */ -#define BFTW_ERROR 4 +#define BFTW_ERROR 8 /** action: Keep walking. */ #define BFTW_CONTINUE 0 |