diff --git a/parser/parser_main.c b/parser/parser_main.c index ec70bea9c..1548fc27c 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -80,6 +80,8 @@ int mru_skip_cache = 1; int debug_cache = 0; struct timespec mru_tstamp; +static char *cacheloc = NULL; + /* Make sure to update BOTH the short and long_options */ static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:"; struct option long_options[] = { @@ -691,7 +693,7 @@ int test_for_dir_mode(const char *basename, const char *linkdir) return rc; } -int process_profile(int option, const char *profilename) +int process_profile(int option, const char *profilename, const char *cachedir) { int retval = 0; autofree const char *cachename = NULL; @@ -735,7 +737,7 @@ int process_profile(int option, const char *profilename) /* setup cachename and tstamp */ if (!force_complain && !skip_cache) { - cachename = cache_filename(cacheloc, basename); + cachename = cache_filename(cachedir, basename); valid_read_cache(cachename); } @@ -820,32 +822,37 @@ out: return retval; } -/* data - name of parent dir */ +struct dir_cb_data { + const char *dirname; /* name of the parent dir */ + const char *cachedir; /* path to the cache sub directory */ +}; + +/* data - pointer to a dir_cb_data */ static int profile_dir_cb(DIR *dir unused, const char *name, struct stat *st, void *data) { int rc = 0; if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { - const char *dirname = (const char *)data; + struct dir_cb_data *cb_data = (struct dir_cb_data *)data; autofree char *path = NULL; - if (asprintf(&path, "%s/%s", dirname, name) < 0) + if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) PERROR(_("Out of memory")); - rc = process_profile(option, path); + rc = process_profile(option, path, cb_data->cachedir); } return rc; } -/* data - name of parent dir */ +/* data - pointer to a dir_cb_data */ static int binary_dir_cb(DIR *dir unused, const char *name, struct stat *st, void *data) { int rc = 0; if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { - const char *dirname = (const char *)data; + struct dir_cb_data *cb_data = (struct dir_cb_data *)data; autofree char *path = NULL; - if (asprintf(&path, "%s/%s", dirname, name) < 0) + if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) PERROR(_("Out of memory")); rc = process_binary(option, path); } @@ -870,6 +877,7 @@ static void setup_flags(void) int main(int argc, char *argv[]) { + autofree char *cachedir = NULL; int retval, last_error; int i; int optind; @@ -902,7 +910,7 @@ int main(int argc, char *argv[]) setup_flags(); - setup_cache(); + cachedir = setup_cache(cacheloc); retval = last_error = 0; for (i = optind; i <= argc; i++) { @@ -927,15 +935,20 @@ int main(int argc, char *argv[]) if (profilename && S_ISDIR(stat_file.st_mode)) { int (*cb)(DIR *dir, const char *name, struct stat *st, void *data); + struct dir_cb_data cb_data; + + cb_data.dirname = profilename; + cb_data.cachedir = cachedir; cb = binary_input ? binary_dir_cb : profile_dir_cb; - if ((retval = dirat_for_each(NULL, profilename, profilename, cb))) { + if ((retval = dirat_for_each(NULL, profilename, + &cb_data, cb))) { PDEBUG("Failed loading profiles from %s\n", profilename); } } else if (binary_input) { retval = process_binary(option, profilename); } else { - retval = process_profile(option, profilename); + retval = process_profile(option, profilename, cachedir); } if (profilename) free(profilename); diff --git a/parser/policy_cache.c b/parser/policy_cache.c index aa1455c35..b9aa795f8 100644 --- a/parser/policy_cache.c +++ b/parser/policy_cache.c @@ -34,8 +34,6 @@ #include "parser.h" #include "policy_cache.h" -char *cacheloc = NULL; - #define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x))) const char header_string[] = "\004\010\000version\000\002"; @@ -149,11 +147,11 @@ error: return -1; } -char *cache_filename(const char *cacheloc, const char *basename) +char *cache_filename(const char *cachedir, const char *basename) { char *cachename; - if (asprintf(&cachename, "%s/%s", cacheloc, basename) < 0) { + if (asprintf(&cachename, "%s/%s", cachedir, basename) < 0) { PERROR(_("Memory allocation error.")); exit(1); } @@ -230,21 +228,27 @@ void install_cache(const char *cachetmpname, const char *cachename) } } -void setup_cache(void) +char *setup_cache(const char *cacheloc) { autofree char *cache_features_path = NULL; autofree char *cache_flags = NULL; + char *cachedir; - /* create the cacheloc once and use it everywhere */ - if (!cacheloc) { - if (asprintf(&cacheloc, "%s/cache", basedir) == -1) { + if (cacheloc) { + cachedir = strdup(cacheloc); + if (!cachedir) { + PERROR(_("Memory allocation error.")); + exit(1); + } + } else { + if (asprintf(&cachedir, "%s/cache", basedir) == -1) { PERROR(_("Memory allocation error.")); exit(1); } } if (force_clear_cache) - exit(clear_cache_files(cacheloc)); + exit(clear_cache_files(cachedir)); /* * Deal with cache directory versioning: @@ -252,7 +256,7 @@ void setup_cache(void) * - If cache/.features exists, and does not match features_string, * force cache reading/writing off. */ - if (asprintf(&cache_features_path, "%s/.features", cacheloc) == -1) { + if (asprintf(&cache_features_path, "%s/.features", cachedir) == -1) { PERROR(_("Memory allocation error.")); exit(1); } @@ -261,7 +265,7 @@ void setup_cache(void) if (cache_flags) { if (strcmp(features_string, cache_flags) != 0) { if (write_cache && cond_clear_cache) { - if (create_cache(cacheloc, cache_features_path, + if (create_cache(cachedir, cache_features_path, features_string)) skip_read_cache = 1; } else { @@ -272,6 +276,8 @@ void setup_cache(void) } } } else if (write_cache) { - create_cache(cacheloc, cache_features_path, features_string); + create_cache(cachedir, cache_features_path, features_string); } + + return cachedir; } diff --git a/parser/policy_cache.h b/parser/policy_cache.h index 05b05bd20..76d2f16d7 100644 --- a/parser/policy_cache.h +++ b/parser/policy_cache.h @@ -35,18 +35,17 @@ extern int force_clear_cache; /* force clearing regargless of state */ extern int create_cache_dir; /* create the cache dir if missing? */ extern int mru_skip_cache; extern int debug_cache; -extern char *cacheloc; void set_mru_tstamp(struct timespec t); void update_mru_tstamp(FILE *file, const char *path); bool valid_cached_file_version(const char *cachename); int clear_cache_files(const char *path); int create_cache(const char *cachedir, const char *path, const char *features); -char *cache_filename(const char *cacheloc, const char *basename); +char *cache_filename(const char *cachedir, const char *basename); void valid_read_cache(const char *cachename); int cache_hit(const char *cachename); int setup_cache_tmp(const char **cachetmpname, const char *cachename); void install_cache(const char *cachetmpname, const char *cachename); -void setup_cache(void); +char *setup_cache(const char *cacheloc); #endif /* __AA_POLICY_CACHE_H */