From 0620d473c2df34d02137fb22c23fb0f166b0e1a1 Mon Sep 17 00:00:00 2001 From: NRK Date: Thu, 20 Jun 2024 10:50:19 +0000 Subject: allow {white,black}listing thumbnail cache dirs (#461) this adds the cli flags --cache-{allow,deny} along with corresponding config.h vars which allows the user to control which directories will have thumbnail cache written. this is a more general version of the `cache-whitelist` patch that existed in the nsxiv-extra repo: https://codeberg.org/nsxiv/nsxiv-extra/src/commit/21cb27cee7/patches/cache-whitelist Closes: https://codeberg.org/nsxiv/nsxiv/issues/454 --- thumbs.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'thumbs.c') diff --git a/thumbs.c b/thumbs.c index 9909333..f55a152 100644 --- a/thumbs.c +++ b/thumbs.c @@ -75,7 +75,26 @@ static Imlib_Image tns_cache_load(const char *filepath, bool *outdated) return im; } -static void tns_cache_write(Imlib_Image im, const char *filepath, bool force) +static bool tns_cache_whitelisted(tns_t *tns, const char *filepath) +{ + ptrdiff_t i, dir_len = strrchr(filepath, '/') - filepath; + dir_len = MAX(dir_len, 1); /* account for "/file" */ + + if (tns->filters_cnt == 0) + return true; /* no cache list, cache everything */ + + for (i = 0; i < tns->filters_cnt; ++i) { + thumb_filter_t *f = tns->filters + i; + if ((f->recursive ? (dir_len >= f->len) : (dir_len == f->len)) && + memcmp(filepath, f->path, f->len) == 0) + { /* in blacklist mode, finding a match means we shouldn't cache */ + return tns->filters_is_blacklist ? false : true; + } + } + return tns->filters_is_blacklist; /* no match */ +} + +static void tns_cache_write(tns_t *tns, Imlib_Image im, const char *filepath, bool force) { char *cfile, *dirend; int tmpfd; @@ -83,7 +102,7 @@ static void tns_cache_write(Imlib_Image im, const char *filepath, bool force) struct utimbuf times; Imlib_Load_Error err; - if (options->private_mode) + if (options->private_mode || !tns_cache_whitelisted(tns, filepath)) return; if (stat(filepath, &fstats) < 0) @@ -167,6 +186,34 @@ void tns_init(tns_t *tns, fileinfo_t *tns_files, const int *cnt, int *sel, win_t tns->zl = THUMB_SIZE; tns_zoom(tns, 0); + tns->filters = NULL; + tns->filters_cnt = 0; + tns->filters_is_blacklist = options->tns_filters_is_blacklist; + if (options->tns_filters != NULL && options->tns_filters[0] != '\0') { + int allocated = 0; + char *save, *tok, *s = estrdup(options->tns_filters); + for (tok = strtok_r(s, ":", &save); tok != NULL; + tok = strtok_r(NULL, ":", &save)) + { + thumb_filter_t *f; + if (tns->filters_cnt == allocated) { + allocated = allocated > 0 ? (allocated * 2) : 4; + tns->filters = erealloc(tns->filters, + allocated * sizeof(*tns->filters)); + } + f = tns->filters + tns->filters_cnt++; + f->recursive = *tok == '*'; + f->path = realpath(tok + f->recursive, NULL); + if (f->path == NULL) { + error(EXIT_FAILURE, errno, "--cache-%s: `%s`", + tns->filters_is_blacklist ? "deny" : "allow", + tok + f->recursive); + } + f->len = strlen(f->path); + } + free(s); + } + if ((homedir = getenv("XDG_CACHE_HOME")) == NULL || homedir[0] == '\0') { homedir = getenv("HOME"); dsuffix = "/.cache"; @@ -196,6 +243,12 @@ CLEANUP void tns_free(tns_t *tns) tns->thumbs = NULL; } + for (i = 0; i < tns->filters_cnt; ++i) + free((void *)tns->filters[i].path); + tns->filters_cnt = 0; + free(tns->filters); + tns->filters = NULL; + free(cache_dir); cache_dir = NULL; free(cache_tmpfile); @@ -335,7 +388,7 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only) im = tns_scale_down(im, maxwh); imlib_context_set_image(im); if (imlib_image_get_width() == maxwh || imlib_image_get_height() == maxwh) - tns_cache_write(im, file->path, true); + tns_cache_write(tns, im, file->path, true); } if (cache_only) { -- cgit v1.2.3-70-g09d2