X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmod_url.c;h=1943b04dd23f20d16683b6abeb1a4d565ce77397;hb=refs%2Fheads%2Fmaster;hp=5c0f81f1b9755a370f5559c4fc0a01474228cb6f;hpb=47f73ee9117686e9d3d0b5bf6c664215dfe1bf8d;p=assman diff --git a/src/mod_url.c b/src/mod_url.c index 5c0f81f..1943b04 100644 --- a/src/mod_url.c +++ b/src/mod_url.c @@ -9,6 +9,7 @@ #ifdef BUILD_MOD_URL #include #include +#include enum { DL_UNKNOWN, @@ -38,6 +39,7 @@ static void exit_cleanup(void); static void download(void *data); static size_t recv_callback(char *ptr, size_t size, size_t nmemb, void *udata); static const char *get_temp_dir(void); +static int mkdir_path(const char *path); static char *tmpdir, *cachedir; static struct thread_pool *tpool; @@ -47,7 +49,8 @@ struct ass_fileops *ass_alloc_url(const char *url) { static int done_init; struct ass_fileops *fop; - int i; + int i, len; + char *ptr; if(!done_init) { curl_global_init(CURL_GLOBAL_ALL); @@ -58,11 +61,16 @@ struct ass_fileops *ass_alloc_url(const char *url) } tmpdir = (char*)get_temp_dir(); if(!(cachedir = malloc(strlen(ass_mod_url_cachedir) + strlen(tmpdir) + 2))) { - fprintf(stderr, "assman: failed to allocate cachedir path buffer\n"); + fprintf(stderr, "assman mod_url: failed to allocate cachedir path buffer\n"); goto init_failed; } sprintf(cachedir, "%s/%s", tmpdir, ass_mod_url_cachedir); + if(mkdir_path(cachedir) == -1) { + fprintf(stderr, "assman mod_url: failed to create cache directory: %s\n", cachedir); + goto init_failed; + } + if(ass_mod_url_max_threads <= 0) { ass_mod_url_max_threads = 8; } @@ -89,11 +97,16 @@ struct ass_fileops *ass_alloc_url(const char *url) if(!(fop = malloc(sizeof *fop))) { return 0; } - if(!(fop->udata = malloc(strlen(url) + 1))) { + len = strlen(url); + if(!(fop->udata = malloc(len + 1))) { free(fop); return 0; } - strcpy(fop->udata, url); + memcpy(fop->udata, url, len + 1); + if(len) { + ptr = (char*)fop->udata + len - 1; + while(*ptr == '/') *ptr-- = 0; + } fop->open = fop_open; fop->close = fop_close; @@ -137,19 +150,15 @@ void ass_free_url(struct ass_fileops *fop) { } -static char *cache_filename(const char *fname, const char *url_prefix) +static char *cache_filename(const char *fname, const char *url) { MD4_CTX md4ctx; unsigned char sum[16]; char sumstr[33]; char *resfname; - int i; + int i, prefix_len; + int url_len = strlen(url); int fname_len = strlen(fname); - int prefix_len = strlen(url_prefix); - int url_len = fname_len + prefix_len + 1; - - char *url = alloca(url_len + 1); - sprintf(url, "%s/%s", url_prefix, fname); MD4Init(&md4ctx); MD4Update(&md4ctx, (unsigned char*)url, url_len); @@ -161,7 +170,7 @@ static char *cache_filename(const char *fname, const char *url_prefix) sumstr[32] = 0; prefix_len = strlen(cachedir); - if(!(resfname = malloc(prefix_len + fname_len + 20))) { + if(!(resfname = malloc(prefix_len + fname_len + 64))) { return 0; } sprintf(resfname, "%s/%s-%s", cachedir, fname, sumstr); @@ -172,20 +181,42 @@ static void *fop_open(const char *fname, void *udata) { struct file_info *file; int state; + char *prefix = udata; + + if(!fname || !*fname) { + ass_errno = ENOENT; + return 0; + } if(!(file = malloc(sizeof *file))) { ass_errno = ENOMEM; return 0; } - if(!(file->cache_fname = cache_filename(fname, udata))) { + + if(!(file->url = malloc(strlen(prefix) + strlen(fname) + 2))) { + perror("assman: mod_url: failed to allocate url buffer"); + ass_errno = errno; + free(file); + return 0; + } + if(prefix && *prefix) { + sprintf(file->url, "%s/%s", prefix, fname); + } else { + strcpy(file->url, fname); + } + + if(!(file->cache_fname = cache_filename(fname, file->url))) { + free(file->url); free(file); ass_errno = ENOMEM; return 0; } + printf("assman: mod_url cache file: %s\n", file->cache_fname); if(!(file->cache_file = fopen(file->cache_fname, "wb"))) { fprintf(stderr, "assman: mod_url: failed to open cache file (%s) for writing: %s\n", file->cache_fname, strerror(errno)); ass_errno = errno; + free(file->url); free(file->cache_fname); free(file); return 0; @@ -210,6 +241,7 @@ static void *fop_open(const char *fname, void *udata) fclose(file->cache_file); remove(file->cache_fname); free(file->cache_fname); + free(file->url); pthread_cond_destroy(&file->state_cond); pthread_mutex_destroy(&file->state_mutex); free(file); @@ -237,6 +269,7 @@ static void fop_close(void *fp, void *udata) fclose(file->cache_file); if(file->state == DL_ERROR) remove(file->cache_fname); free(file->cache_fname); + free(file->url); pthread_cond_destroy(&file->state_cond); pthread_mutex_destroy(&file->state_mutex); free(file); @@ -322,6 +355,34 @@ static const char *get_temp_dir(void) #endif +static int mkdir_path(const char *path) +{ + char *pathbuf, *dptr; + struct stat st; + + if(!path || !*path) return -1; + + pathbuf = dptr = alloca(strlen(path) + 1); + + while(*path) { + while(*path) { + int c = *path++; + *dptr++ = c; + + if(c == '/' || c == '\\') break; + } + *dptr = 0; + + if(stat(pathbuf, &st) == -1) { + /* path component does not exist, create it */ + if(mkdir(pathbuf, 0777) == -1) { + return -1; + } + } + } + + return 0; +} #else /* don't build mod_url */ struct ass_fileops *ass_alloc_url(const char *url)