diff --git a/src/cache.c b/src/cache.c index 0d2c1fc..03c140f 100644 --- a/src/cache.c +++ b/src/cache.c @@ -520,10 +520,15 @@ static void Cache_free(Cache *cf) if (cf->path) { free(cf->path); } + if (cf->seg) { free(cf->seg); } + if (cf->fs_path) { + free(cf->fs_path); + } + free(cf); } @@ -664,8 +669,10 @@ static int Meta_create(Cache *cf) return 0; } -int Cache_create(Link *this_link) +int Cache_create(const char *path) { + Link *this_link = path_to_Link(path); + char *fn; if (!CONFIG.sonic_mode) { fn = curl_easy_unescape(NULL, this_link->f_url + ROOT_LINK_OFFSET, 0, @@ -732,21 +739,10 @@ Cache *Cache_open(const char *fn) /* Obtain the link structure memory pointer */ Link *link = path_to_Link(fn); if (!link) { + /* There is no associated link to the path */ return NULL; } - /* Check if both metadata and data file exist */ - if (!CONFIG.sonic_mode) { - if (!Cache_exist(fn)) { - return NULL; - } - } else { - if (!Cache_exist(link->sonic_id_str)) { - return NULL; - } - fn = link->sonic_id_str; - } - /*---------------- Cache_open() critical section -----------------*/ #ifdef CACHE_LOCK_DEBUG @@ -772,8 +768,28 @@ Cache *Cache_open(const char *fn) PTHREAD_MUTEX_UNLOCK(&cf_lock); /*----------------------------------------------------------------*/ + /* Check if both metadata and data file exist */ + if (!CONFIG.sonic_mode) { + if (!Cache_exist(fn)) { + return NULL; + } + } else { + if (!Cache_exist(link->sonic_id_str)) { + return NULL; + } + } + /* Create the cache in-memory data structure */ Cache *cf = Cache_alloc(); + + if (CONFIG.sonic_mode) { + /* Fill in the fs_path */ + cf->fs_path = calloc(MAX_PATH_LEN + 1, sizeof(char)); + strncpy(cf->fs_path, fn, MAX_PATH_LEN); + /* Set the path for the local cache file */ + fn = link->sonic_id_str; + } + cf->path = strndup(fn, MAX_PATH_LEN); /* Associate the cache structure with a link */ @@ -923,8 +939,14 @@ static void *Cache_bgdl(void *arg) PTHREAD_MUTEX_LOCK(&cf->w_lock); uint8_t *recv_buf = CALLOC(cf->blksz, sizeof(uint8_t)); fprintf(stderr, "Cache_bgdl(): thread %lu: ", pthread_self()); - long recv = path_download(cf->path, (char *) recv_buf, cf->blksz, + long recv = path_download(cf->fs_path, (char *) recv_buf, cf->blksz, cf->next_dl_offset); + if (recv < 0) { + fprintf(stderr, "\nCache_bgdl(): received %lu bytes, \ +which does't make sense\n", recv); + exit_failure(); + } + if ( (recv == cf->blksz) || (cf->next_dl_offset == (cf->content_length / cf->blksz * cf->blksz)) ) { @@ -964,7 +986,7 @@ long Cache_read(Cache *cf, char * const output_buf, const off_t len, } else { /* Wait for any other download thread to finish*/ #ifdef CACHE_LOCK_DEBUG - fprintf(stderr, "Cache_read(): thread %lu: locking w_lock;\n", + fprintf(stderr, "Cache_read(): thread %ld: locking w_lock;\n", pthread_self()); #endif PTHREAD_MUTEX_LOCK(&cf->w_lock); @@ -985,8 +1007,14 @@ long Cache_read(Cache *cf, char * const output_buf, const off_t len, uint8_t *recv_buf = CALLOC(cf->blksz, sizeof(uint8_t)); fprintf(stderr, "Cache_read(): thread %lu: ", pthread_self()); - long recv = path_download(cf->path, (char *) recv_buf, cf->blksz, + fprintf(stderr, "cf->fs_path: %s\n", cf->fs_path); + long recv = path_download(cf->fs_path, (char *) recv_buf, cf->blksz, dl_offset); + if (recv < 0) { + fprintf(stderr, "\nCache_read(): received %ld bytes, \ +which does't make sense\n", recv); + exit_failure(); + } /* * check if we have received enough data, write it to the disk * diff --git a/src/cache.h b/src/cache.h index 53d6d55..36ff667 100644 --- a/src/cache.h +++ b/src/cache.h @@ -27,11 +27,11 @@ typedef uint8_t Seg; * \brief cache data type in-memory data structure */ struct Cache { - /** \brief The FILE pointer for the data file*/ + /** \brief the FILE pointer for the data file*/ FILE *dfp; - /** \brief The FILE pointer for the metadata */ + /** \brief the FILE pointer for the metadata */ FILE *mfp; - /** \brief the path to the file on the web server */ + /** \brief the path to the local cache file */ char *path; /** \brief the Link associated with this cache data set */ Link *link; @@ -63,6 +63,9 @@ struct Cache { pthread_mutexattr_t bgt_lock_attr; /** \brief the offset of the next segment to be downloaded in background*/ off_t next_dl_offset; + + /** \brief the FUSE filesystem path to the remote file*/ + char *fs_path; }; /** @@ -116,7 +119,7 @@ void Cache_close(Cache *cf); * - -1, otherwise * \note Called by fs_open() */ -int Cache_create(Link *this_link); +int Cache_create(const char *path); /** * \brief delete a cache file set diff --git a/src/fuse_local.c b/src/fuse_local.c index 26bfc27..0ef4cd3 100644 --- a/src/fuse_local.c +++ b/src/fuse_local.c @@ -96,7 +96,7 @@ static int fs_open(const char *path, struct fuse_file_info *fi) * cache creation */ Cache_delete(path); - Cache_create(link); + Cache_create(path); fi->fh = (uint64_t) Cache_open(path); /* * The cache definitely cannot be opened for some reason. diff --git a/src/link.c b/src/link.c index 3f057be..e3403c9 100644 --- a/src/link.c +++ b/src/link.c @@ -677,6 +677,10 @@ Link *path_to_Link(const char *path) long path_download(const char *path, char *output_buf, size_t size, off_t offset) { + if (!path) { + fprintf(stderr, "\npath_download(): NULL path supplied\n"); + exit_failure(); + } Link *link; link = path_to_Link(path); if (!link) { @@ -746,5 +750,6 @@ range requests\n"); memmove(output_buf, buf.data, recv); curl_easy_cleanup(curl); free(buf.data); + return recv; } diff --git a/src/link.h b/src/link.h index 2971b04..39936e4 100644 --- a/src/link.h +++ b/src/link.h @@ -76,7 +76,7 @@ struct Link { /** * \brief Sonic Music Directory ID in string format */ - char sonic_id_str[MAX_FILENAME_LEN+1]; + char *sonic_id_str; }; struct LinkTable { diff --git a/src/sonic.c b/src/sonic.c index 8f2710c..7fa5398 100644 --- a/src/sonic.c +++ b/src/sonic.c @@ -141,6 +141,7 @@ static void XMLCALL XML_process_single_element(void *data, const char *elem, for (int i = 0; attr[i]; i += 2) { if (!strcmp("id", attr[i])) { link->sonic_id = atoi(attr[i+1]); + link->sonic_id_str = calloc(MAX_FILENAME_LEN, sizeof(char)); snprintf(link->sonic_id_str, MAX_FILENAME_LEN, "%d", link->sonic_id); id_set = 1;