From 3def47c3317e731d799c8787408c4f5b28ce2bd0 Mon Sep 17 00:00:00 2001 From: Petr Pudlak <petr.mvd@gmail.com> Date: Wed, 10 Apr 2013 16:41:26 +0200 Subject: [PATCH] Add CACHEDIR.TAG support. A new command line parameter allows to filter out directories containing the proper `CACHEDIR.TAG` file. See http://www.brynosaurus.com/cachedir/ --- src/dir_scan.c | 4 ++++ src/exclude.c | 23 +++++++++++++++++++++++ src/global.h | 2 ++ src/main.c | 6 ++++++ 4 files changed, 35 insertions(+) diff --git a/src/dir_scan.c b/src/dir_scan.c index f3688c6..57f96b3 100644 --- a/src/dir_scan.c +++ b/src/dir_scan.c @@ -196,6 +196,10 @@ static int dir_scan_item(struct dir *d) { if(!(d->flags & (FF_ERR|FF_EXL))) stat_to_dir(d, &st); + if(cachedir_tags && (d->flags & FF_DIR) && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS))) + if(has_cachedir_tag(d->name)) + d->flags |= FF_EXL; + /* Recurse into the dir or output the item */ if(d->flags & FF_DIR && !(d->flags & (FF_ERR|FF_EXL|FF_OTHFS))) fail = dir_scan_recurse(d); diff --git a/src/exclude.c b/src/exclude.c index ecf40a8..d7b679d 100644 --- a/src/exclude.c +++ b/src/exclude.c @@ -99,3 +99,26 @@ void exclude_clear() { excludes = NULL; } + +/* + * Exclusion of directories that contain only cached information. + * See http://www.brynosaurus.com/cachedir/ + */ +static const char cachedir_tag_signature[] = + "Signature: 8a477f597d28d172789f06886806bc55"; + +int has_cachedir_tag(const char *name) { + char buf[1024]; + FILE *f; + int match = 0; + const int signature_l = strlen(cachedir_tag_signature); + + snprintf(buf, sizeof(buf), "%s/CACHEDIR.TAG", name); + f = fopen(buf, "rb"); + if (f != NULL) { + match = ((fread(buf, 1, signature_l, f) == signature_l) && + !strncmp(buf, cachedir_tag_signature, signature_l)); + fclose(f); + } + return match; +} diff --git a/src/global.h b/src/global.h index d6eb2cb..4bf0d55 100644 --- a/src/global.h +++ b/src/global.h @@ -86,6 +86,8 @@ extern int pstate; extern int read_only; /* minimum screen update interval when calculating, in ms */ extern long update_delay; +/* filter directories with CACHEDIR.TAG */ +extern int cachedir_tags; /* handle input from keyboard and update display */ int input_handle(int); diff --git a/src/main.c b/src/main.c index 109f2a1..54771b2 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,7 @@ int pstate; int read_only = 0; long update_delay = 100; +int cachedir_tags = 0; static int min_rows = 17, min_cols = 60; static int ncurses_init = 0; @@ -125,6 +126,7 @@ static void argv_parse(int argc, char **argv) { { '2', 0, "-2" }, { 1, 1, "--exclude" }, { 'X', 1, "-X,--exclude-from" }, + { 'C', 0, "-C,--cachedir-tag" }, {0,0,NULL} }; @@ -146,6 +148,7 @@ static void argv_parse(int argc, char **argv) { printf(" -0,-1,-2 UI to use when scanning (0=none,2=full ncurses)\n"); printf(" --exclude PATTERN Exclude files that match PATTERN\n"); printf(" -X, --exclude-from FILE Exclude files that match any pattern in FILE\n"); + printf(" -C, --cachedir-tag Exclude directories containing CACHEDIR.TAG\n"); exit(0); case 'q': update_delay = 2000; break; case 'v': @@ -165,6 +168,9 @@ static void argv_parse(int argc, char **argv) { exit(1); } break; + case 'C': + cachedir_tags = 1; + break; case -2: printf("ncdu: %s.\n", val); exit(1); -- GitLab