summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/boom.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/boom.c b/src/boom.c
new file mode 100644
index 0000000..5d2a6d7
--- /dev/null
+++ b/src/boom.c
@@ -0,0 +1,122 @@
+#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"
+
+static int max_depth = -1;
+
+static bool show_hidden = false;
+static bool dirs_only = false;
+
+static void usage(FILE *f) {
+ fprintf(f,
+ "Gebruik: boom [-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");
+}
+
+// Returns pointer to argument array containing the starting points
+static char** parse_options(int argc, char **argv) {
+ int opt;
+ while ((opt = getopt(argc, argv, "adhV")) != -1) {
+ switch (opt) {
+ case 'a':
+ show_hidden = true;
+ break;
+
+ case 'd':
+ dirs_only = true;
+ 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 prev_level = -1;
+static int skip_level = -1;
+
+static int f(const char *fpath, const struct stat *, int typeflag, struct FTW *ftwbuf) {
+ int level = ftwbuf->level;
+ bool is_dir
+ = typeflag == FTW_D
+ || typeflag == FTW_DNR
+ || typeflag == FTW_DP;
+
+ if (level < skip_level) {
+ skip_level = -1;
+ } else if (skip_level != -1 && level >= skip_level) {
+ return 0;
+ }
+
+ // check max depth
+ if (max_depth >= 0 && level >= max_depth) return 0;
+
+ const char *fname = basename(fpath);
+
+ // don't show hidden files
+ if (!show_hidden && fname[0] == '.' && strlen(fpath) > 2 && level != 0) {
+ skip_level = level + 1;
+ goto done;
+ }
+ // don't show files in dirs only mode
+ if (dirs_only && !is_dir) return 0;
+
+ for (int i = 1; i < level; i++) {
+ printf("| ");
+ }
+
+ if (level != 0) {
+ printf("|-- ");
+ }
+ puts(fname);
+
+done:
+ prev_level = level;
+ return 0;
+}
+
+int entry_boom(int argc, char **argv) {
+ char **args = parse_options(argc, argv);
+
+ int flags = 0;
+ flags |= FTW_PHYS;
+
+ if (*args == NULL) {
+ nftw(".", f, 4096, flags);
+ return 0;
+ }
+
+ for (int i = 0; args[i]; i++) {
+ nftw(args[i], f, 4096, flags);
+ }
+
+ return 0;
+}