aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--thumbs.c27
-rw-r--r--util.c43
-rw-r--r--util.h1
3 files changed, 58 insertions, 13 deletions
diff --git a/thumbs.c b/thumbs.c
index 6b37526..820fd4b 100644
--- a/thumbs.c
+++ b/thumbs.c
@@ -327,7 +327,6 @@ int tns_cache_enabled() {
char* tns_cache_filename(const char *filename) {
size_t len;
- int i;
char *cfile, *abspath;
if (!cache_dir || !filename)
@@ -341,13 +340,7 @@ char* tns_cache_filename(const char *filename) {
strcpy(abspath, filename);
}
- len = strlen(abspath);
- for (i = 0; i < len; ++i) {
- if (abspath[i] == '/')
- abspath[i] = '%';
- }
-
- len += strlen(cache_dir) + 6;
+ len = strlen(cache_dir) + strlen(abspath) + 6;
cfile = (char*) s_malloc(len);
snprintf(cfile, len, "%s/%s.png", cache_dir, abspath + 1);
@@ -380,10 +373,10 @@ Imlib_Image* tns_cache_load(const char *filename) {
}
void tns_cache_write(thumb_t *t, Bool force) {
- char *cfile;
+ char *cfile, *dirend;
struct stat cstats, fstats;
struct timeval times[2];
- Imlib_Load_Error err;
+ Imlib_Load_Error err = 0;
if (!t || !t->im || !t->filename)
return;
@@ -395,9 +388,17 @@ void tns_cache_write(thumb_t *t, Bool force) {
cstats.st_mtim.tv_sec != fstats.st_mtim.tv_sec ||
cstats.st_mtim.tv_nsec != fstats.st_mtim.tv_nsec)
{
- imlib_context_set_image(t->im);
- imlib_image_set_format("png");
- imlib_save_image_with_error_return(cfile, &err);
+ if ((dirend = strrchr(cfile, '/'))) {
+ *dirend = '\0';
+ err = create_dir_rec(cfile);
+ *dirend = '/';
+ }
+
+ if (!err) {
+ imlib_context_set_image(t->im);
+ imlib_image_set_format("png");
+ imlib_save_image_with_error_return(cfile, &err);
+ }
if (err) {
warn("could not cache thumbnail: %s", t->filename);
diff --git a/util.c b/util.c
index 517b4ba..42d1384 100644
--- a/util.c
+++ b/util.c
@@ -18,6 +18,8 @@
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
@@ -156,6 +158,47 @@ end:
return path;
}
+int create_dir_rec(const char *path) {
+ char *dir, *d;
+ struct stat stats;
+ int err = 0;
+
+ if (!path || !*path)
+ return -1;
+
+ if (!stat(path, &stats)) {
+ if (S_ISDIR(stats.st_mode)) {
+ return 0;
+ } else {
+ warn("not a directory: %s", path);
+ return -1;
+ }
+ }
+
+ d = dir = (char*) s_malloc(strlen(path) + 1);
+ strcpy(dir, path);
+
+ while (d != NULL && !err) {
+ d = strchr(d + 1, '/');
+ if (d != NULL)
+ *d = '\0';
+ if (access(dir, F_OK) && errno == ENOENT) {
+ if (mkdir(dir, 0755)) {
+ warn("could not create directory: %s", dir);
+ err = -1;
+ }
+ } else if (stat(dir, &stats) || !S_ISDIR(stats.st_mode)) {
+ warn("not a directory: %s", dir);
+ err = -1;
+ }
+ if (d != NULL)
+ *d = '/';
+ }
+ free(dir);
+
+ return err;
+}
+
char* readline(FILE *stream) {
size_t len;
char *buf, *s, *end;
diff --git a/util.h b/util.h
index e3cdef9..b6efd5a 100644
--- a/util.h
+++ b/util.h
@@ -44,6 +44,7 @@ void die(const char*, ...);
void size_readable(float*, const char**);
char* absolute_path(const char*);
+int create_dir_rec(const char*);
char* readline(FILE*);