summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Pudlak <petr.mvd@gmail.com>2013-04-10 16:41:26 +0200
committerPetr Pudlak <petr.mvd@gmail.com>2013-04-10 16:50:57 +0200
commit3def47c3317e731d799c8787408c4f5b28ce2bd0 (patch)
tree551244827e6795cd175ebab43aefdbc537065e45
parent9b4f2d8601baa1150b5beb219c93c1e68ccfabbe (diff)
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/
-rw-r--r--src/dir_scan.c4
-rw-r--r--src/exclude.c23
-rw-r--r--src/global.h2
-rw-r--r--src/main.c6
4 files changed, 35 insertions, 0 deletions
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);