static char * tth_cache_pathname(const struct tth *tth) { const char *hash; g_assert(tth); hash = tth_base32(tth); return h_strdup_printf("%s%c%2.2s%c%s", tth_cache_directory(), G_DIR_SEPARATOR, &hash[0], G_DIR_SEPARATOR, &hash[2]); }
/** * Main entry point for the thread that cleans up the TTH cache. */ static void * tth_cache_cleanup_thread(void *unused_arg) { hset_t *shared; const char *rootdir = tth_cache_directory(); pslist_t *dirstack; uint32 flags; ftw_status_t res; (void) unused_arg; if (!is_directory(rootdir)) goto done; /* No TTH cache */ /* * First pass: spot all file entries that are older than our start * time (i.e. were created in another session) and which cannot be * associated with a shared file. */ shared = share_tthset_get(); flags = FTW_O_PHYS | FTW_O_MOUNT | FTW_O_ALL; res = ftw_foreach(rootdir, flags, 0, tth_cache_cleanup_unlink, shared); share_tthset_free(shared); if (res != FTW_STATUS_OK) { g_warning("%s(): initial traversal failed with %d, aborting", G_STRFUNC, res); goto done; } /* * Second pass: spot empty directories and remove them. */ flags |= FTW_O_ENTRY | FTW_O_DEPTH; dirstack = NULL; (void) ftw_foreach(rootdir, flags, 0, tth_cache_cleanup_rmdir, &dirstack); pslist_free(dirstack); /* FALL THROUGH */ done: atomic_int_dec(&tth_cache_cleanups); return NULL; }