diff --git a/src/config.c b/src/config.c index 24f4a59..b3fcd2b 100644 --- a/src/config.c +++ b/src/config.c @@ -53,6 +53,8 @@ void Config_init(void) CONFIG.insecure_tls = 0; + CONFIG.refresh_timeout = DEFAULT_REFRESH_TIMEOUT; + /*--------------- Cache related ---------------*/ CONFIG.cache_enabled = 0; diff --git a/src/config.h b/src/config.h index 2629e74..9a8c9e2 100644 --- a/src/config.h +++ b/src/config.h @@ -23,6 +23,11 @@ */ #define DEFAULT_NETWORK_MAX_CONNS 10 +/** + * \brief The default refresh_timeout + */ +#define DEFAULT_REFRESH_TIMEOUT 86400 + /** * \brief Operation modes */ @@ -67,6 +72,8 @@ typedef struct { int insecure_tls; /** \brief Server certificate file */ char *cafile; + /** \brief Refresh directory listing after refresh_timeout seconds*/ + int refresh_timeout; /*--------------- Cache related ---------------*/ /** \brief Whether cache mode is enabled */ int cache_enabled; diff --git a/src/fuse_local.c b/src/fuse_local.c index 9873513..c2ecfd4 100644 --- a/src/fuse_local.c +++ b/src/fuse_local.c @@ -44,7 +44,7 @@ static int fs_getattr(const char *path, struct stat *stbuf) if (!link) { return -ENOENT; } - struct timespec spec; + struct timespec spec = {0}; spec.tv_sec = link->time; #if defined(__APPLE__) && defined(__MACH__) stbuf->st_mtimespec = spec; @@ -138,15 +138,12 @@ fs_readdir(const char *path, void *buf, fuse_fill_dir_t dir_add, (void) fi; LinkTable *linktbl; - if (!strcmp(path, "/")) { - linktbl = ROOT_LINK_TBL; - } else { - linktbl = path_to_Link_LinkTable_new(path); - if (!linktbl) { - return -ENOENT; - } + linktbl = path_to_Link_LinkTable_new(path); + if (!linktbl) { + return -ENOENT; } + /* * start adding the links */ diff --git a/src/link.c b/src/link.c index 1742dbf..1d69a2c 100644 --- a/src/link.c +++ b/src/link.c @@ -501,11 +501,15 @@ static void LinkTable_invalid_reset(LinkTable *linktbl) void LinkTable_free(LinkTable *linktbl) { - for (int i = 0; i < linktbl->num; i++) { - FREE(linktbl->links[i]); + if (linktbl) + { + for (int i = 0; i < linktbl->num; i++) { + LinkTable_free(linktbl->links[i]->next_table); + FREE(linktbl->links[i]); + } + FREE(linktbl->links); + FREE(linktbl); } - FREE(linktbl->links); - FREE(linktbl); } void LinkTable_print(LinkTable *linktbl) @@ -538,6 +542,10 @@ void LinkTable_print(LinkTable *linktbl) LinkTable *LinkTable_alloc(const char *url) { LinkTable *linktbl = CALLOC(1, sizeof(LinkTable)); + linktbl->num = 0; + linktbl->index_time = 0; + linktbl->links = NULL; + /* * populate the base URL @@ -552,6 +560,7 @@ LinkTable *LinkTable_alloc(const char *url) LinkTable *LinkTable_new(const char *url) { LinkTable *linktbl = LinkTable_alloc(url); + linktbl->index_time = time(NULL); /* * start downloading the base URL @@ -733,24 +742,50 @@ LinkTable *LinkTable_disk_open(const char *dirn) LinkTable *path_to_Link_LinkTable_new(const char *path) { - Link *link = path_to_Link(path); - LinkTable *next_table = link->next_table; + struct Link *link = NULL, *tmp_link = NULL; + struct Link linkcpy = {0}; + LinkTable *next_table = NULL; + if (!strcmp(path, "/")) { + next_table = ROOT_LINK_TBL; + linkcpy = *next_table->links[0]; + tmp_link = &linkcpy; + } else { + link = path_to_Link(path); + tmp_link = link; + LinkTable *next_table = link->next_table; + } + + if (next_table) + { + time_t time_now = time(NULL); + if (time_now - next_table->index_time > CONFIG.refresh_timeout) + { + // refresh directory contents + LinkTable_free(next_table); + next_table = NULL; + if (link) + link->next_table = NULL; + } + } if (!next_table) { if (CONFIG.mode == NORMAL) { - next_table = LinkTable_new(link->f_url); + next_table = LinkTable_new(tmp_link->f_url); } else if (CONFIG.mode == SONIC) { if (!CONFIG.sonic_id3) { - next_table = sonic_LinkTable_new_index(link->sonic.id); + next_table = sonic_LinkTable_new_index(tmp_link->sonic.id); } else { next_table = - sonic_LinkTable_new_id3(link->sonic.depth, - link->sonic.id); + sonic_LinkTable_new_id3(tmp_link->sonic.depth, + tmp_link->sonic.id); } } else { lprintf(fatal, "Invalid CONFIG.mode\n"); } } - link->next_table = next_table; + if (link) + link->next_table = next_table; + else + ROOT_LINK_TBL = next_table; return next_table; } diff --git a/src/link.h b/src/link.h index 313c5dd..91372d2 100644 --- a/src/link.h +++ b/src/link.h @@ -33,6 +33,7 @@ typedef enum { */ struct LinkTable { int num; + time_t index_time; Link **links; }; diff --git a/src/main.c b/src/main.c index 8723d28..d4827b0 100644 --- a/src/main.c +++ b/src/main.c @@ -201,6 +201,7 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc) { "single-file-mode", required_argument, NULL, 'L' }, /* 22 */ { "cacert", required_argument, NULL, 'L' }, /* 23 */ { "proxy-cacert", required_argument, NULL, 'L' }, /* 24 */ + { "refresh-timeout", required_argument, NULL, 'L' }, /* 25 */ { 0, 0, 0, 0 } }; while ((c = @@ -304,6 +305,9 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc) case 24: CONFIG.proxy_cafile = strdup(optarg); break; + case 25: + CONFIG.refresh_timeout = atoi(optarg); + break; default: fprintf(stderr, "see httpdirfs -h for usage\n"); return 1; @@ -370,6 +374,7 @@ HTTPDirFS options:\n\ to 1TB in size using the default segment size.\n\ --max-conns Set maximum number of network connections that\n\ libcurl is allowed to make. (default: 10)\n\ + --refresh-timeout X Refresh directories after X seconds\n\ --retry-wait Set delay in seconds before retrying an HTTP request\n\ after encountering an error. (default: 5)\n\ --user-agent Set user agent string (default: \"HTTPDirFS\")\n\