diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vind.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/vind.c b/src/vind.c new file mode 100644 index 0000000..445613f --- /dev/null +++ b/src/vind.c @@ -0,0 +1,134 @@ +#include <assert.h> +#include <ftw.h> +#include <getopt.h> +#include <limits.h> +#include <pwd.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#include "util/versie.h" + +int ftmap = 0; +int max_depth = -1; + +ssize_t min_size = 0; +ssize_t max_size = SSIZE_MAX; + +static void usage(FILE *f) { + fprintf(f, + "Gebruik: vind [-thV] [STARTPUNTEN]...\n" + "\n" + "TODO\n" + "\n" + " -t Bestandtypes om weer te geven, kan zijn b(estand), m(apje) of een combinatie gescheiden door komma's\n" + " -d Maximale diepte\n" + " -o Omvang van n beten (+, - voor meer of minder)\n" + " -h Toon deze hulptekst\n" + " -V Toon versienummer\n"); +} + +enum filetype_flags { + FT_FILE = 1 << 0, + FT_DIR = 1 << 1, +}; + +static int parse_filetypes(char *s) { + int res = 0; + + char *pat = NULL; + while ((pat = strtok(s, "\n")) != NULL) { + s = NULL; + + if (!strcmp(pat, "b")) { + res |= FT_FILE; + } else if (!strcmp(pat, "m")) { + res |= FT_DIR; + } + } + + return res; +} + +// Returns pointer to argument array containing the starting points +static char** parse_options(int argc, char **argv) { + int opt; + while ((opt = getopt(argc, argv, "t:d:o:hV")) != -1) { + switch (opt) { + case 't': + ftmap = parse_filetypes(optarg); + break; + + case 'd': + max_depth = atoi(optarg); + break; + + case 'o': + if (optarg[0] == '+') { + min_size = atoi(optarg + 1); + } else if (optarg[0] == '-') { + max_size = atoi(optarg + 1); + } else { + min_size = max_size = atoi(optarg); + } + break; + + case 'h': + usage(stdout); + exit(0); + + case 'V': + drukkedoos_print_versie(stdout); + exit(0); + + case '?': + usage(stderr); + exit(1); + } + } + + return argv + optind; +} + +static int f(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { + bool skip = false; + switch (typeflag) { + case FTW_F: + skip = !(ftmap == 0 || (ftmap & FT_FILE)); + break; + case FTW_D: + case FTW_DNR: + case FTW_DP: + skip = !(ftmap == 0 || (ftmap & FT_DIR)); + break; + } + + if (skip) return 0; + if (max_depth >= 0 && ftwbuf->level >= max_depth) return 0; + + if (sb->st_size < min_size) return 0; + if (sb->st_size > max_size) return 0; + + puts(fpath); + return 0; +} + +int entry_vind(int argc, char **argv) { + char **args = parse_options(argc, argv); + + int flags = 0; + + if (*args == NULL) { + nftw(".", f, 4096, flags); + return 0; + } + + for (int i = 0; args[i]; i++) { + nftw(args[i], f, 4096, flags); + } + + return 0; +} |