Skip to content

Commit

Permalink
Fix segfault when HOME is not set
Browse files Browse the repository at this point in the history
  • Loading branch information
EyitopeIO authored and fangfufu committed Sep 1, 2024
1 parent ba7bb47 commit 09ebc82
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 38 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,20 @@ This feature was implemented due to Github
## Permanent cache system

You can cache the files you have accessed permanently on your hard drive by
using the ``--cache`` flag. The file it caches persist across sessions.
using the ``--cache`` flag. The file it caches persist across sessions, but
can clear the cache using ``--cache-clear``

> [!WARNING]
> If ``--cache-location <dir>`` appears before ``--cache-clear``, the entire
> directory ``<dir>`` will be deleted instead. Take caution when specifying
> non-empty directories to be used as cache.
By default, the cache files are stored under ``${XDG_CACHE_HOME}/httpdirfs``,
which by default is ``${HOME}/.cache/httpdirfs``. Each HTTP directory gets its
``${HOME}/.cache/httpdirfs``, or the current working directory ``./.cache``,
whichever is found first. By default, ``${XDG_CACHE_HOME}/httpdirfs`` is
normally ``${HOME}/.cache/httpdirfs``.

Each HTTP directory gets its
own cache folder, they are named using the escaped URL of the HTTP directory.

Once a segment of the file has been downloaded once, it won't be downloaded
Expand Down
59 changes: 38 additions & 21 deletions src/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,46 @@ static pthread_mutex_t cf_lock;
*/
static char *DATA_DIR;

static char *CacheSystem_get_cache_home()

char *CacheSystem_get_cache_dir()
{
if (CONFIG.cache_dir) {
return CONFIG.cache_dir;
}
char *xdg_cache_home = getenv("XDG_CACHE_HOME");
if (!xdg_cache_home) {
char *home = getenv("HOME");
char *xdg_cache_home_default = "/.cache";
xdg_cache_home = path_append(home, xdg_cache_home_default);

const char *default_cache_subdir = "/.cache";
char *cache_dir = NULL;

const char *xdg_cache_home = getenv("XDG_CACHE_HOME");
if (xdg_cache_home) {
cache_dir = strndup(xdg_cache_home, MAX_PATH_LEN);
} else {
const char *user_home = getenv("HOME");
if (user_home) {
cache_dir = path_append(user_home, default_cache_subdir);
} else {
lprintf(warning, "$HOME is unset\n");
/*
* XDG_CACHE_HOME and HOME already are full paths. Not relying
* on environment PWD since it too may be undefined.
*/
const char *cur_dir = realpath("./", NULL);
if (cur_dir) {
cache_dir = path_append(cur_dir, default_cache_subdir);
} else {
lprintf(fatal, "Could not create cache directory\n");
}
}
}
return xdg_cache_home;
return cache_dir;
}

/**
* \brief Calculate cache system directory path
*/
static char *CacheSystem_calc_dir(const char *url)
{
char *cache_home = CacheSystem_get_cache_home();
char *cache_home = CacheSystem_get_cache_dir();

if (mkdir
(cache_home, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
Expand Down Expand Up @@ -92,6 +112,7 @@ static char *CacheSystem_calc_dir(const char *url)
lprintf(fatal, "mkdir(): %s\n", strerror(errno));
}
FREE(fn);
FREE(cache_home);
FREE(cache_dir_root);
curl_free(escaped_url);
curl_easy_cleanup(c);
Expand Down Expand Up @@ -163,22 +184,18 @@ static int ntfw_cb(const char *fpath, const struct stat *sb, int typeflag, struc
return remove(fpath);
}

void CacheSystem_clear(const char *path)
void CacheSystem_clear()
{
char *cache_root_dir;
if (path) {
cache_root_dir = strdup(path);
char *cache_home = CacheSystem_get_cache_dir();
const char *cache_del;
lprintf(debug, "%s\n", cache_home);
if (CONFIG.cache_dir) {
cache_del = cache_home;
} else {
char *cache_home = CacheSystem_get_cache_home();
cache_root_dir = path_append(cache_home, "/httpdirfs/");
FREE(cache_home);
cache_del = path_append(cache_home, "/httpdirfs/");
}

lprintf(debug, "%s\n", path);

nftw(cache_root_dir, ntfw_cb, 64, FTW_DEPTH | FTW_PHYS | FTW_MOUNT);
FREE(cache_root_dir);

nftw(cache_del, ntfw_cb, 64, FTW_DEPTH | FTW_PHYS | FTW_MOUNT);
FREE(cache_home);
exit(EXIT_SUCCESS);
}

Expand Down
9 changes: 7 additions & 2 deletions src/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,12 @@ void CacheSystem_init(const char *path, int url_supplied);
/**
* \brief clear the content of the cache directory
*/
void CacheSystem_clear(const char *path);
void CacheSystem_clear();

/**
* \brief Return the fullpath to the cache directory
*/
char *CacheSystem_get_cache_dir();

/**
* \brief Create directories under the cache directory structure, if they do
Expand Down Expand Up @@ -148,4 +153,4 @@ void Cache_delete(const char *fn);
*/
long Cache_read(Cache *cf, char *const output_buf, const off_t len,
const off_t offset_start);
#endif
#endif
45 changes: 32 additions & 13 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,38 @@ activate Sonic mode.\n");
return 0;
}

static char *get_XDG_CONFIG_HOME()
{
const char *default_config_subdir = "/.config";
char *config_dir = NULL;

const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home) {
config_dir = strndup(xdg_config_home, MAX_PATH_LEN);
} else {
const char *user_home = getenv("HOME");
if (user_home) {
config_dir = path_append(user_home, default_config_subdir);
} else {
lprintf(warning, "$HOME is unset\n");
const char *cur_dir = realpath("./", NULL);
if (cur_dir) {
config_dir = path_append(cur_dir, default_config_subdir);
} else {
lprintf(warning, "Could not get config directory\n");
}
}
}
return config_dir;
}

void parse_config_file(char ***argv, int *argc)
{
char *full_path;
if (!config_path) {
char *xdg_config_home = getenv("XDG_CONFIG_HOME");
if (!xdg_config_home) {
char *home = getenv("HOME");
char *xdg_config_home_default = "/.config";
xdg_config_home = path_append(home, xdg_config_home_default);
}
char *xdg_config_home = get_XDG_CONFIG_HOME();
full_path = path_append(xdg_config_home, "/httpdirfs/config");
FREE(xdg_config_home);
} else {
full_path = config_path;
}
Expand Down Expand Up @@ -316,11 +337,7 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
curl_slist_append(CONFIG.http_headers, strdup(optarg));
break;
case 27:
if (CONFIG.cache_dir) {
CacheSystem_clear(CONFIG.cache_dir);
} else {
CacheSystem_clear(NULL);
}
CacheSystem_clear();
break;
default:
fprintf(stderr, "see httpdirfs -h for usage\n");
Expand Down Expand Up @@ -377,7 +394,9 @@ HTTPDirFS options:\n\
--cache Enable cache (default: off)\n\
--cache-location Set a custom cache location\n\
(default: \"${XDG_CACHE_HOME}/httpdirfs\")\n\
--cache-clear Clear cache directory and exit\n\
--cache-clear Delete the cache directory or the custom location\n\
specifid with `--cache-location`, if the option is\n\
seen first. Then exit in either case.\n\
--cacert Certificate authority for the server\n\
--dl-seg-size Set cache download segment size, in MB (default: 8)\n\
Note: this setting is ignored if previously\n\
Expand Down Expand Up @@ -412,4 +431,4 @@ HTTPDirFS options:\n\
using the insecure username / hex encoded password\n\
scheme\n\
\n");
}
}

0 comments on commit 09ebc82

Please sign in to comment.