]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
cd to cache directory instead of prefixing every path
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Mon, 7 Oct 2024 22:00:35 +0000 (16:00 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 8 Oct 2024 21:03:18 +0000 (15:03 -0600)
Reduces busywork, memory usage and allows the cache to be moved.

14 files changed:
src/cache.c
src/cachetmp.c
src/common.c
src/common.h
src/config.c
src/file.c
src/file.h
src/main.c
src/rrdp.c
src/rrdp.h
src/types/path.c
src/types/path.h
test/cache_test.c
test/rrdp_update_test.c

index e1f2d4c18aff55372c3999f63c082b29b695d336..bf89c17efaf9c07e4efece2b13f98e2b91567e45 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdbool.h>
 #include <sys/queue.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 #include "alloc.h"
 #include "cachetmp.h"
@@ -37,7 +38,7 @@ struct cache_node {
 typedef int (*dl_cb)(struct cache_node *rpp);
 
 struct cache_table {
-       char const *name;
+       char *name;
        bool enabled;
        struct cache_sequence seq;
        struct cache_node *nodes; /* Hash Table */
@@ -91,27 +92,6 @@ delete_node(struct cache_table *tbl, struct cache_node *node)
        free(node);
 }
 
-static char *
-get_cache_filename(char const *name, bool fatal)
-{
-       struct path_builder pb;
-       int error;
-
-       error = pb_init_cache(&pb, name);
-       if (error) {
-               if (fatal) {
-                       pr_crit("Cannot create path to %s: %s", name,
-                           strerror(error));
-               } else {
-                       pr_op_err("Cannot create path to %s: %s", name,
-                           strerror(error));
-                       return NULL;
-               }
-       }
-
-       return pb.string;
-}
-
 char *
 get_rsync_module(char const *url)
 {
@@ -179,12 +159,12 @@ static int dl_http(struct cache_node *);
 static int dl_rrdp(struct cache_node *);
 
 static void
-init_table(struct cache_table *tbl, char const *name, bool enabled, dl_cb dl)
+init_table(struct cache_table *tbl, char *name, bool enabled, dl_cb dl)
 {
        memset(tbl, 0, sizeof(*tbl));
        tbl->name = name;
        tbl->enabled = enabled;
-       cseq_init(&tbl->seq, path_join(config_get_local_repository(), name));
+       cseq_init(&tbl->seq, name, false);
        tbl->download = dl;
 }
 
@@ -200,88 +180,84 @@ init_tables(void)
 static void
 init_cache_metafile(void)
 {
-       char *filename;
        json_t *root;
        json_error_t jerror;
        char const *file_version;
        int error;
 
-       filename = get_cache_filename(CACHE_METAFILE, true);
-       root = json_load_file(filename, 0, &jerror);
+       root = json_load_file(CACHE_METAFILE, 0, &jerror);
 
        if (root == NULL) {
                if (json_error_code(&jerror) == json_error_cannot_open_file)
-                       pr_op_debug("%s does not exist.", filename);
+                       pr_op_debug(CACHE_METAFILE " does not exist.");
                else
-                       pr_op_err("Json parsing failure at %s (%d:%d): %s",
-                           filename, jerror.line, jerror.column, jerror.text);
+                       pr_op_err("Json parsing failure at " CACHE_METAFILE
+                           " (%d:%d): %s", jerror.line, jerror.column,
+                           jerror.text);
                goto invalid_cache;
        }
        if (json_typeof(root) != JSON_OBJECT) {
-               pr_op_err("The root tag of %s is not an object.", filename);
+               pr_op_err(CACHE_METAFILE "'s root tag is not an object.");
                goto invalid_cache;
        }
 
        error = json_get_str(root, TAGNAME_VERSION, &file_version);
        if (error) {
                if (error > 0)
-                       pr_op_err("%s is missing the " TAGNAME_VERSION " tag.",
-                           filename);
+                       pr_op_err(CACHE_METAFILE " is missing the "
+                           TAGNAME_VERSION " tag.");
                goto invalid_cache;
        }
 
-       if (strcmp(file_version, PACKAGE_VERSION) == 0)
-               goto end;
+       if (strcmp(file_version, PACKAGE_VERSION) != 0)
+               goto invalid_cache;
 
-invalid_cache:
-       pr_op_info("The cache appears to have been built by a different version of Fort. I'm going to clear it, just to be safe.");
-       file_rm_rf(config_get_local_repository());
+       json_decref(root);
+       return;
 
-end:   json_decref(root);
-       free(filename);
+invalid_cache:
+       pr_op_info("The cache seems to have been built by a different version of Fort. "
+           "I'm going to clear it, just to be safe.");
+       file_rm_rf(".");
+       json_decref(root);
 }
 
 static void
 init_cachedir_tag(void)
 {
-       char *filename;
-
-       filename = get_cache_filename("CACHEDIR.TAG", false);
-       if (filename == NULL)
-               return;
-
+       static char const *filename = "CACHEDIR.TAG";
        if (file_exists(filename) == ENOENT)
                write_simple_file(filename,
                   "Signature: 8a477f597d28d172789f06886806bc55\n"
                   "# This file is a cache directory tag created by Fort.\n"
                   "# For information about cache directory tags, see:\n"
                   "#   https://bford.info/cachedir/\n");
-
-       free(filename);
 }
 
 static int
 init_tmp_dir(void)
 {
-       char *dirname;
        int error;
 
-       dirname = get_cache_filename(CACHE_TMPDIR, true);
-
-       if (mkdir(dirname, CACHE_FILEMODE) < 0) {
+       if (mkdir(CACHE_TMPDIR, CACHE_FILEMODE) < 0) {
                error = errno;
                if (error != EEXIST)
                        return pr_op_err("Cannot create '%s': %s",
-                           dirname, strerror(error));
+                           CACHE_TMPDIR, strerror(error));
        }
 
-       free(dirname);
        return 0;
 }
 
 int
 cache_setup(void)
 {
+       if (chdir(config_get_local_repository()) < 0) {
+               pr_op_err("Cannot cd to the cache directory: %s",
+                   strerror(errno));
+               return errno;
+       }
+
        // XXX Lock the cache directory
        init_tables();
        init_cache_metafile();
@@ -293,22 +269,9 @@ cache_setup(void)
 void
 cache_teardown(void)
 {
-       char *filename;
-
-       filename = get_cache_filename(CACHE_METAFILE, false);
-       if (filename == NULL)
-               return;
-
-       write_simple_file(filename, "{ \"" TAGNAME_VERSION "\": \""
+       // XXX catch result?
+       write_simple_file(CACHE_METAFILE, "{ \"" TAGNAME_VERSION "\": \""
            PACKAGE_VERSION "\" }\n");
-       free(filename);
-}
-
-static char *
-get_tal_json_filename(void)
-{
-       struct path_builder pb;
-       return pb_init_cache(&pb, TAL_METAFILE) ? NULL : pb.string;
 }
 
 static struct cache_node *
@@ -370,7 +333,6 @@ json2tbl(json_t *root, struct cache_table *tbl)
 static void
 load_tal_json(void)
 {
-       char *filename;
        json_t *root;
        json_error_t jerror;
 
@@ -379,24 +341,21 @@ load_tal_json(void)
         * without killing itself. It's just a cache of a cache.
         */
 
-       filename = get_tal_json_filename();
-       if (filename == NULL)
-               return;
-
-       pr_op_debug("Loading %s.", filename);
+       pr_op_debug("Loading " TAL_METAFILE ".");
 
-       root = json_load_file(filename, 0, &jerror);
+       root = json_load_file(TAL_METAFILE, 0, &jerror);
 
        if (root == NULL) {
                if (json_error_code(&jerror) == json_error_cannot_open_file)
-                       pr_op_debug("%s does not exist.", filename);
+                       pr_op_debug(TAL_METAFILE " does not exist.");
                else
                        pr_op_err("Json parsing failure at %s (%d:%d): %s",
-                           filename, jerror.line, jerror.column, jerror.text);
+                           TAL_METAFILE, jerror.line, jerror.column,
+                           jerror.text);
                goto end;
        }
        if (json_typeof(root) != JSON_OBJECT) {
-               pr_op_err("The root tag of %s is not an object.", filename);
+               pr_op_err("The root tag of " TAL_METAFILE " is not an object.");
                goto end;
        }
 
@@ -406,7 +365,6 @@ load_tal_json(void)
        json2tbl(root, &cache.fallback);
 
 end:   json_decref(root);
-       free(filename);
 }
 
 void
@@ -498,22 +456,16 @@ fail:     json_decref(json);
 static void
 write_tal_json(void)
 {
-       char *filename;
        struct json_t *json;
 
        json = build_tal_json();
        if (json == NULL)
                return;
 
-       filename = get_tal_json_filename();
-       if (filename == NULL)
-               goto end;
-
-       if (json_dump_file(json, filename, JSON_INDENT(2)))
-               pr_op_err("Unable to write %s; unknown cause.", filename);
+       if (json_dump_file(json, TAL_METAFILE, JSON_INDENT(2)))
+               pr_op_err("Unable to write " TAL_METAFILE "; unknown cause.");
 
-end:   json_decref(json);
-       free(filename);
+       json_decref(json);
 }
 
 static int
@@ -919,20 +871,15 @@ rmf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 static void
 cleanup_tmp(void)
 {
-       char *tmpdir = get_cache_filename(CACHE_TMPDIR, true);
-       if (nftw(tmpdir, rmf, 32, FTW_DEPTH | FTW_PHYS))
+       if (nftw(CACHE_TMPDIR, rmf, 32, FTW_DEPTH | FTW_PHYS))
                pr_op_warn("Cannot empty the cache's tmp directory: %s",
                    strerror(errno));
-       free(tmpdir);
 }
 
 static bool
 is_fallback(char const *path)
 {
-       // XXX just cd to the freaking cache, ffs
-       path += strlen(config_get_local_repository());
-       return str_starts_with(path, "fallback/") ||
-              str_starts_with(path, "/fallback/");
+       return str_starts_with(path, "fallback/");
 }
 
 /* Hard-links @rpp's approved files into the fallback directory. */
@@ -1092,19 +1039,11 @@ remove_abandoned(void)
 {
        // XXX no need to recurse anymore.
        /*
-       char *rootpath;
-
-       rootpath = join_paths(config_get_local_repository(), "rsync");
-
        nftw_root = cache.rsync;
-       nftw(rootpath, nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
-
-       strcpy(rootpath + strlen(rootpath) - 5, "https");
+       nftw("rsync", nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
 
        nftw_root = cache.https;
-       nftw(rootpath, nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
-
-       free(rootpath);
+       nftw("https", nftw_remove_abandoned, 32, FTW_DEPTH | FTW_PHYS); // XXX
        */
 }
 
@@ -1158,10 +1097,6 @@ cache_commit(void)
        cleanup_cache();
        write_tal_json();
        cache_foreach(delete_node);
-       free(cache.rsync.seq.prefix);
-       free(cache.https.seq.prefix);
-       free(cache.rrdp.seq.prefix);
-       free(cache.fallback.seq.prefix);
 }
 
 void
index 9547152dda67ea2e627f4c070a02b9a42244da61..856248f4ace1f440a3971bf77d7b07e5461f02a5 100644 (file)
@@ -23,16 +23,18 @@ cache_tmpfile(char **filename)
        struct path_builder pb;
        int error;
 
-       error = pb_init_cache(&pb, CACHE_TMPDIR);
-       if (error)
-               return error;
+       pb_init(&pb);
 
+       error = pb_append(&pb, CACHE_TMPDIR);
+       if (error)
+               goto fail;
        error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u));
-       if (error) {
-               pb_cleanup(&pb);
-               return error;
-       }
+       if (error)
+               goto fail;
 
        *filename = pb.string;
        return 0;
+
+fail:  pb_cleanup(&pb);
+       return error;
 }
index ca10dc5cc14c0ae1457e6ac76e40bf40218564ef..e73ddc03634eceda796178d1ae70ec96d9cee354 100644 (file)
@@ -315,70 +315,6 @@ end:       free(path);
        return result;
 }
 
-/*
- * Delete @path.
- * If path's parent is now empty, delete parent as well.
- * If parent's parent is now empty, delete parent's parent.
- * And so on.
- *
- * XXX this should be done by the cache cleaner instead.
- */
-int
-delete_dir_recursive_bottom_up(char const *path)
-{
-       char *config_repo;
-       char *work_loc, *tmp;
-       size_t config_len;
-       int error;
-
-       if (remove(path) < 0) {
-               error = errno;
-               pr_val_err("Couldn't delete '%s': %s", path, strerror(error));
-               return error;
-       }
-
-       config_repo = pstrdup(config_get_local_repository());
-
-       /* Stop dir removal when the work_dir has this length */
-       config_len = strlen(config_repo);
-       if (config_repo[config_len - 1] == '/')
-               config_len--;
-       free(config_repo);
-
-       work_loc = pstrdup(path);
-
-       do {
-               tmp = strrchr(work_loc, '/');
-               if (tmp == NULL)
-                       break;
-               *tmp = '\0';
-
-               /* Stop if the root dir is reached */
-               if (strlen(work_loc) == config_len)
-                       break;
-
-               errno = 0;
-               error = rmdir(work_loc);
-               if (!error)
-                       continue; /* Keep deleting up */
-
-               /* Stop if there's content in the dir */
-               error = errno;
-               if (error == ENOTEMPTY || error == EEXIST)
-                       break;
-
-               pr_op_err_st("Couldn't delete directory '%s': %s", work_loc,
-                   strerror(error));
-               goto release_str;
-       } while (true);
-
-       free(work_loc);
-       return 0;
-release_str:
-       free(work_loc);
-       return error;
-}
-
 time_t
 time_nonfatal(void)
 {
index 4ed0b2647c92e5601615060da673df968fcb0e5a..3bc5c1d8226f62601358cca572c1820e98dc2bfc 100644 (file)
@@ -48,7 +48,6 @@ int foreach_file(char const *, char const *, bool, foreach_file_cb, void *);
 bool valid_file_or_dir(char const *, bool);
 
 int mkdir_p(char const *, bool);
-int delete_dir_recursive_bottom_up(char const *);
 
 time_t time_nonfatal(void);
 time_t time_fatal(void);
index e21ebbd13d1935a79d9af00408ad5f4c5be482e1..bcfe64b1eeaf01b199332393d42ec29c5d06fdf7 100644 (file)
@@ -4,7 +4,9 @@
 #include <errno.h>
 #include <getopt.h>
 #include <libxml/xmlreader.h>
+#include <limits.h>
 #include <openssl/opensslv.h>
+#include <stdlib.h>
 #include <syslog.h>
 
 #include "alloc.h"
@@ -1139,6 +1141,25 @@ handle_opt(int opt)
        return -ESRCH;
 }
 
+static int
+become_absolute_path(char **_path)
+{
+       char *relative = *_path;
+       char *absolute;
+
+       if (relative == NULL)
+               return 0;
+
+       absolute = realpath(relative, NULL);
+       if (!absolute)
+               return pr_op_err("Cannot resolve the absolute path of %s: %s",
+                   relative, strerror(errno));
+
+       free(relative);
+       *_path = absolute;
+       return 0;
+}
+
 int
 handle_flags_config(int argc, char **argv)
 {
@@ -1168,6 +1189,16 @@ handle_flags_config(int argc, char **argv)
        if (error)
                goto end;
 
+       error = become_absolute_path(&rpki_config.tal);
+       if (error)
+               goto end;
+       error = become_absolute_path(&rpki_config.slurm);
+       if (error)
+               goto end;
+       error = become_absolute_path(&rpki_config.http.ca_path);
+       if (error)
+               goto end;
+
        /* If present, nothing else is done */
        if (rpki_config.init_tals || rpki_config.init_tal0s) {
                if (rpki_config.init_tals)
index 140d11740b959f2799c7d48335eb02de4710723b..e256f79b0bc625639403b0d1da13ed211512fdf5 100644 (file)
@@ -277,11 +277,12 @@ file_rm_rf(char const *path)
 }
 
 void
-cseq_init(struct cache_sequence *seq, char *prefix)
+cseq_init(struct cache_sequence *seq, char *prefix, bool free_prefix)
 {
        seq->prefix = prefix;
        seq->next_id = 0;
        seq->pathlen = strlen(prefix) + 4;
+       seq->free_prefix = free_prefix;
 }
 
 char *
index bcebcd3b97cb8add23bf1283e8b5c960c2929382..eca2a3182ca397d2404a3267345cf45f80e0a483 100644 (file)
@@ -41,9 +41,10 @@ struct cache_sequence {
        char *prefix;
        unsigned long next_id;
        size_t pathlen;
+       bool free_prefix;
 };
 
-void cseq_init(struct cache_sequence *, char *);
+void cseq_init(struct cache_sequence *, char *, bool);
 char *cseq_next(struct cache_sequence *);
 
 /*
index 0184d209c3e812b4a37ab4da5a4c22cbe46b8a5b..db09bea5659e7aff309e93b49c266cdf30fe28e4 100644 (file)
@@ -129,6 +129,7 @@ main(int argc, char **argv)
        error = handle_flags_config(argc, argv);
        if (error)
                goto revert_log;
+
        error = nid_init();
        if (error)
                goto revert_config;
index affd1b95d60ed6a0e25990c0ff33d0ee86fb7e88..6912919fab52bdcacee2eacd6af82d01ce441d5a 100644 (file)
@@ -1218,7 +1218,7 @@ rrdp_update(struct cache_mapping const *notif, time_t mtim, bool *changed,
 
                old = pzalloc(sizeof(struct rrdp_state));
                /* session postponed! */
-               cseq_init(&old->seq, cage);
+               cseq_init(&old->seq, cage, true);
                STAILQ_INIT(&old->delta_hashes);
 
                error = handle_snapshot(&new, old);
@@ -1292,8 +1292,7 @@ rrdp_file(struct rrdp_state *state, char const *url)
 }
 
 char const *
-rrdp_create_fallback(char const *cage, struct rrdp_state **_state,
-    char const *url)
+rrdp_create_fallback(char *cage, struct rrdp_state **_state, char const *url)
 {
        struct rrdp_state *state;
        struct cache_file *file;
@@ -1302,7 +1301,7 @@ rrdp_create_fallback(char const *cage, struct rrdp_state **_state,
        state = *_state;
        if (state == NULL) {
                *_state = state = pzalloc(sizeof(struct rrdp_state));
-               cseq_init(&state->seq, pstrdup(cage));
+               cseq_init(&state->seq, cage, false);
        }
 
        file = pzalloc(sizeof(struct cache_file));
@@ -1554,7 +1553,8 @@ rrdp_state_free(struct rrdp_state *state)
                map_cleanup(&file->map);
                free(file);
        }
-       free(state->seq.prefix);
+       if (state->seq.free_prefix)
+               free(state->seq.prefix);
        clear_delta_hashes(state);
        free(state);
 }
index 64ee1820c5ba8fcad9d8a754e3b472bebafa6673..804bbe1a051a5dc135cec7238421bfa476dd74fe 100644 (file)
@@ -14,8 +14,7 @@ int rrdp_update(struct cache_mapping const *, time_t, bool *,
     struct cache_sequence *, struct rrdp_state **);
 char const *rrdp_file(struct rrdp_state *, char const *);
 
-char const *rrdp_create_fallback(char const *, struct rrdp_state **,
-    char const *);
+char const *rrdp_create_fallback(char *, struct rrdp_state **, char const *);
 
 json_t *rrdp_state2json(struct rrdp_state *);
 int rrdp_json2state(json_t *, struct rrdp_state **);
index 1fe54acf6dc62e58d2e32aa87b8452a22cd6c928..2a17a1703ba45f23452a003de175d90c1a3b1a28 100644 (file)
@@ -49,27 +49,6 @@ __pb_init(struct path_builder *pb, size_t reserve)
        pb->capacity = INITIAL_CAPACITY;
 }
 
-int
-pb_init_cache(struct path_builder *pb, char const *subdir)
-{
-       int error;
-
-       pb_init(pb);
-
-       error = pb_append(pb, config_get_local_repository());
-       if (error)
-               goto cancel;
-       error = pb_append(pb, subdir);
-       if (error)
-               goto cancel;
-
-       return 0;
-
-cancel:
-       pb_cleanup(pb);
-       return error;
-}
-
 static int
 pb_grow(struct path_builder *pb, size_t total_len, char const *addend)
 {
index 7c9619beef88fefedbf3763d2d341a647f7a5cd3..84bcdd091a4dec156c36c1474bb9c73e6e34c274 100644 (file)
@@ -31,7 +31,6 @@ struct path_builder {
 
 void __pb_init(struct path_builder *, size_t);
 #define pb_init(pb) __pb_init(pb, 0)
-int pb_init_cache(struct path_builder *, char const *);
 
 /*
  * The appends are atomic.
index 47f72610904f6e0b6cce11ce85133e9f78608451..b2ccd57c9acf393c00f930018e5dd2388e28ef35 100644 (file)
@@ -55,9 +55,9 @@ static void
 setup_test(void)
 {
        dl_error = 0;
-       ck_assert_int_eq(0, system("rm -rf tmp"));
        init_tables();
-       ck_assert_int_eq(0, system("mkdir -p tmp/rsync tmp/https tmp/rrdp tmp/fallback"));
+       ck_assert_int_eq(0, system("rm -rf rsync/ https/ rrdp/ fallback/"));
+       ck_assert_int_eq(0, system("mkdir rsync/ https/ rrdp/ fallback/"));
 }
 
 static struct cache_cage *
@@ -128,7 +128,7 @@ print_tree(void)
        printf("\n");
 
        printf("Files in cache:\n");
-       ck_assert_int_eq(0, nftw("tmp/", print_file, 32, FTW_PHYS));
+       ck_assert_int_eq(0, nftw(".", print_file, 32, FTW_PHYS));
        printf("\n");
 }
 
@@ -324,7 +324,7 @@ new_iteration(bool outdate)
 
        pr_op_debug("--- Unfreshening... ---");
        cache_foreach(unfreshen);
-       ck_assert_int_eq(0, nftw("tmp/rsync", nftw_unfreshen, 32, FTW_PHYS));
+       ck_assert_int_eq(0, nftw(".", nftw_unfreshen, 32, FTW_PHYS));
 
        pr_op_debug("---- Tree now stale. ----");
        cache_print();
@@ -349,17 +349,17 @@ START_TEST(test_cache_download_rsync)
        printf("==== Startup ====\n");
        cage = run_dl_rsync("rsync://a.b.c/d", 1);
        ck_assert_ptr_ne(NULL, cage);
-       ck_cage(cage, "rsync://a.b.c/d", "tmp/rsync/0", NULL);
-       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "tmp/rsync/0/e/f.cer", NULL);
-       init_node_rsync(&nodes[0], "rsync://a.b.c/d", "tmp/rsync/0", 1, 0);
+       ck_cage(cage, "rsync://a.b.c/d", "rsync/0", NULL);
+       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "rsync/0/e/f.cer", NULL);
+       init_node_rsync(&nodes[0], "rsync://a.b.c/d", "rsync/0", 1, 0);
        ck_cache_rsync(nodes);
        free(cage);
 
        printf("==== Redownload same file, nothing should happen ====\n");
        cage = run_dl_rsync("rsync://a.b.c/d", 0);
        ck_assert_ptr_ne(NULL, cage);
-       ck_cage(cage, "rsync://a.b.c/d", "tmp/rsync/0", NULL);
-       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "tmp/rsync/0/e/f.cer", NULL);
+       ck_cage(cage, "rsync://a.b.c/d", "rsync/0", NULL);
+       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "rsync/0/e/f.cer", NULL);
        ck_cache_rsync(nodes);
        free(cage);
 
@@ -370,8 +370,8 @@ START_TEST(test_cache_download_rsync)
        printf("==== Don't redownload child ====\n");
        cage = run_dl_rsync("rsync://a.b.c/d/e", 0);
        ck_assert_ptr_ne(NULL, cage);
-       ck_cage(cage, "rsync://a.b.c/d", "tmp/rsync/0", NULL);
-       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "tmp/rsync/0/e/f.cer", NULL);
+       ck_cage(cage, "rsync://a.b.c/d", "rsync/0", NULL);
+       ck_cage(cage, "rsync://a.b.c/d/e/f.cer", "rsync/0/e/f.cer", NULL);
        ck_cache_rsync(nodes);
        free(cage);
 
@@ -384,18 +384,18 @@ START_TEST(test_cache_download_rsync)
        printf("==== rsync truncated ====\n");
        cage = run_dl_rsync("rsync://x.y.z/m/n/o", 1);
        ck_assert_ptr_ne(NULL, cage);
-       ck_cage(cage, "rsync://x.y.z/m", "tmp/rsync/1", NULL);
-       ck_cage(cage, "rsync://x.y.z/m/n/o", "tmp/rsync/1/n/o", NULL);
-       init_node_rsync(&nodes[1], "rsync://x.y.z/m", "tmp/rsync/1", 1, 0);
+       ck_cage(cage, "rsync://x.y.z/m", "rsync/1", NULL);
+       ck_cage(cage, "rsync://x.y.z/m/n/o", "rsync/1/n/o", NULL);
+       init_node_rsync(&nodes[1], "rsync://x.y.z/m", "rsync/1", 1, 0);
        ck_cache_rsync(nodes);
        free(cage);
 
        printf("==== Sibling ====\n");
        cage = run_dl_rsync("rsync://a.b.c/e/f", 1);
        ck_assert_ptr_ne(NULL, cage);
-       ck_cage(cage, "rsync://a.b.c/e", "tmp/rsync/2", NULL);
-       ck_cage(cage, "rsync://a.b.c/e/f/x/y/z", "tmp/rsync/2/f/x/y/z", NULL);
-       init_node_rsync(&nodes[2], "rsync://a.b.c/e", "tmp/rsync/2", 1, 0);
+       ck_cage(cage, "rsync://a.b.c/e", "rsync/2", NULL);
+       ck_cage(cage, "rsync://a.b.c/e/f/x/y/z", "rsync/2/f/x/y/z", NULL);
+       init_node_rsync(&nodes[2], "rsync://a.b.c/e", "rsync/2", 1, 0);
        ck_cache_rsync(nodes);
        free(cage);
 
@@ -409,8 +409,8 @@ START_TEST(test_cache_download_rsync_error)
 
        setup_test();
 
-       init_node_rsync(&nodes[0], "rsync://a.b.c/d", "tmp/rsync/0", 1, 0);
-       init_node_rsync(&nodes[1], "rsync://a.b.c/e", "tmp/rsync/1", 1, EINVAL);
+       init_node_rsync(&nodes[0], "rsync://a.b.c/d", "rsync/0", 1, 0);
+       init_node_rsync(&nodes[1], "rsync://a.b.c/e", "rsync/1", 1, EINVAL);
 
        printf("==== Startup ====\n");
        dl_error = 0;
@@ -437,61 +437,62 @@ START_TEST(test_rsync_commit)
 
        setup_test();
 
-       ck_assert_int_eq(0, system("mkdir -p tmp/rsync/0 tmp/rsync/1 tmp/rsync/2 tmp/rsync/3"));
+       ck_assert_int_eq(0, system("mkdir rsync/0 rsync/1 rsync/2 rsync/3"));
 
        /* RPP0: Will remain constant */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/0/0", "A"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/0/1", "B"));
+       ck_assert_int_eq(0, write_simple_file("rsync/0/0", "A"));
+       ck_assert_int_eq(0, write_simple_file("rsync/0/1", "B"));
        /* RPP1: Will be added in its second cycle */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/1/0", "C"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/1/1", "D"));
+       ck_assert_int_eq(0, write_simple_file("rsync/1/0", "C"));
+       ck_assert_int_eq(0, write_simple_file("rsync/1/1", "D"));
        /* RPP2: Will be removed in its second cycle */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/2/0", "E"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/2/1", "F"));
+       ck_assert_int_eq(0, write_simple_file("rsync/2/0", "E"));
+       ck_assert_int_eq(0, write_simple_file("rsync/2/1", "F"));
        /* RPP3: Will be updated in its second cycle */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/3/0", "G")); /* Keeper */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/3/1", "H")); /* Added */
-       ck_assert_int_eq(0, write_simple_file("tmp/rsync/3/2", "I")); /* Removed */
+       ck_assert_int_eq(0, write_simple_file("rsync/3/0", "G")); /* Keeper */
+       ck_assert_int_eq(0, write_simple_file("rsync/3/1", "H")); /* Added */
+       ck_assert_int_eq(0, write_simple_file("rsync/3/2", "I")); /* Removed */
 
        /* Commit 1: Empty -> Empty */
        /* Commit 2: Empty -> Empty (just free noise) */
        for (i = 0; i < 2; i++) {
                commit_fallbacks();
-               ck_filesystem("tmp/fallback", NULL);
+               ck_filesystem("fallback", NULL);
 
                new_iteration(false);
        }
 
        /* Commit 3: Empty -> Populated */
-       queue_commit("rsync://domain/mod/rpp0", "tmp/rsync/0/0", "tmp/rsync/0/1");
-       queue_commit("rsync://domain/mod/rpp2", "tmp/rsync/2/0", "tmp/rsync/2/1");
-       queue_commit("rsync://domain/mod/rpp3", "tmp/rsync/3/0", "tmp/rsync/3/2");
+       queue_commit("rsync://domain/mod/rpp0", "rsync/0/0", "rsync/0/1");
+       queue_commit("rsync://domain/mod/rpp2", "rsync/2/0", "rsync/2/1");
+       queue_commit("rsync://domain/mod/rpp3", "rsync/3/0", "rsync/3/2");
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           /* RPP0 */ "tmp/fallback/0/0", "A", "tmp/fallback/0/1", "B",
-           /* RPP2 */ "tmp/fallback/1/0", "E", "tmp/fallback/1/1", "F",
-           /* RPP3 */ "tmp/fallback/2/0", "G", "tmp/fallback/2/1", "I",
+       ck_filesystem("fallback",
+           /* RPP0 */ "fallback/0/0", "A", "fallback/0/1", "B",
+           /* RPP2 */ "fallback/1/0", "E", "fallback/1/1", "F",
+           /* RPP3 */ "fallback/2/0", "G", "fallback/2/1", "I",
            NULL);
 
        new_iteration(false);
 
        /* Commit 4: Populated -> Populated */
        /* XXX check the refresh does, in fact, only return fallbacks when the RPP doesn't change */
-       queue_commit("rsync://domain/mod/rpp0", "tmp/fallback/0/0", "tmp/fallback/0/1");
-       queue_commit("rsync://domain/mod/rpp1", "tmp/rsync/1/0", "tmp/rsync/1/1");
-       queue_commit("rsync://domain/mod/rpp3", "tmp/fallback/2/0", "tmp/rsync/3/1");
+       queue_commit("rsync://domain/mod/rpp0", "fallback/0/0", "fallback/0/1");
+       queue_commit("rsync://domain/mod/rpp1", "rsync/1/0", "rsync/1/1");
+       queue_commit("rsync://domain/mod/rpp3", "fallback/2/0", "rsync/3/1");
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           /* RPP0 */ "tmp/fallback/0/0", "A", "tmp/fallback/0/1", "B",
-           /* RPP3 */ "tmp/fallback/2/0", "G", "tmp/fallback/2/2", "H",
-           /* RPP1 */ "tmp/fallback/3/0", "C", "tmp/fallback/3/1", "D",
+
+       ck_filesystem("fallback",
+           /* RPP0 */ "fallback/0/0", "A", "fallback/0/1", "B",
+           /* RPP3 */ "fallback/2/0", "G", "fallback/2/2", "H",
+           /* RPP1 */ "fallback/3/0", "C", "fallback/3/1", "D",
            NULL);
 
        new_iteration(false);
 
        /* Commit 5: Populated -> Empty */
        commit_fallbacks();
-       ck_filesystem("tmp/fallback", NULL);
+       ck_filesystem("fallback", NULL);
 
        cache_foreach(delete_node);
 }
@@ -504,22 +505,22 @@ START_TEST(test_cache_download_https)
        setup_test();
 
        printf("==== Download file ====\n");
-       run_dl_https("https://a.b.c/d/e", 1, "tmp/https/0");
-       init_node_https(&nodes[0], "https://a.b.c/d/e", "tmp/https/0", 1, 0);
+       run_dl_https("https://a.b.c/d/e", 1, "https/0");
+       init_node_https(&nodes[0], "https://a.b.c/d/e", "https/0", 1, 0);
        ck_cache_https(nodes);
 
        printf("==== Download same file ====\n");
-       run_dl_https("https://a.b.c/d/e", 0, "tmp/https/0");
+       run_dl_https("https://a.b.c/d/e", 0, "https/0");
        ck_cache_https(nodes);
 
        printf("==== Download something else 1 ====\n");
-       run_dl_https("https://a.b.c/e", 1, "tmp/https/1");
-       init_node_https(&nodes[1], "https://a.b.c/e", "tmp/https/1", 1, 0);
+       run_dl_https("https://a.b.c/e", 1, "https/1");
+       init_node_https(&nodes[1], "https://a.b.c/e", "https/1", 1, 0);
        ck_cache_https(nodes);
 
        printf("==== Download something else 2 ====\n");
-       run_dl_https("https://x.y.z/e", 1, "tmp/https/2");
-       init_node_https(&nodes[2], "https://x.y.z/e", "tmp/https/2", 1, 0);
+       run_dl_https("https://x.y.z/e", 1, "https/2");
+       init_node_https(&nodes[2], "https://x.y.z/e", "https/2", 1, 0);
        ck_cache_https(nodes);
 
        cleanup_test();
@@ -532,22 +533,22 @@ START_TEST(test_cache_download_https_error)
 
        setup_test();
 
-       init_node_https(&nodes[0], "https://a.b.c/d", "tmp/https/0", 1, 0);
-       init_node_https(&nodes[1], "https://a.b.c/e", "tmp/https/1", 1, EINVAL);
+       init_node_https(&nodes[0], "https://a.b.c/d", "https/0", 1, 0);
+       init_node_https(&nodes[1], "https://a.b.c/e", "https/1", 1, EINVAL);
 
        printf("==== Startup ====\n");
        dl_error = 0;
-       run_dl_https("https://a.b.c/d", 1, "tmp/https/0");
+       run_dl_https("https://a.b.c/d", 1, "https/0");
        dl_error = EINVAL;
        run_dl_https("https://a.b.c/e", 1, NULL);
        ck_cache_https(nodes);
 
        printf("==== Regardless of error, not reattempted because same iteration ====\n");
        dl_error = -EINVAL;
-       run_dl_https("https://a.b.c/d", 0, "tmp/https/0");
+       run_dl_https("https://a.b.c/d", 0, "https/0");
        run_dl_https("https://a.b.c/e", 0, NULL);
        dl_error = 0;
-       run_dl_https("https://a.b.c/d", 0, "tmp/https/0");
+       run_dl_https("https://a.b.c/d", 0, "https/0");
        run_dl_https("https://a.b.c/e", 0, NULL);
        ck_cache_https(nodes);
 
@@ -563,51 +564,45 @@ START_TEST(test_https_commit)
 
        setup_test();
 
-       ck_assert_int_eq(0, write_simple_file("tmp/https/50", "A")); /* Keeper */
-       ck_assert_int_eq(0, write_simple_file("tmp/https/51", "B")); /* Added */
-       ck_assert_int_eq(0, write_simple_file("tmp/https/52", "C")); /* Removed */
+       ck_assert_int_eq(0, write_simple_file("https/50", "A")); /* Keeper */
+       ck_assert_int_eq(0, write_simple_file("https/51", "B")); /* Added */
+       ck_assert_int_eq(0, write_simple_file("https/52", "C")); /* Removed */
 
        /* 1, 2 */
        for (i = 0; i < 2; i++) {
                commit_fallbacks();
-               ck_filesystem("tmp/fallback", NULL);
+               ck_filesystem("fallback", NULL);
 
                new_iteration(false);
        }
 
        /* 3 */
        map.url = "https://domain/rpki/ta50.cer";
-       map.path = "tmp/https/50";
+       map.path = "https/50";
        cache_commit_file(&map);
        map.url = "https://domain/rpki/ta52.cer";
-       map.path = "tmp/https/52";
+       map.path = "https/52";
        cache_commit_file(&map);
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           "tmp/fallback/0", "A",
-           "tmp/fallback/1", "C",
-           NULL);
+       ck_filesystem("fallback", "fallback/0", "A", "fallback/1", "C", NULL);
 
        new_iteration(false);
 
        /* 4 */
        map.url = "https://domain/rpki/ta50.cer";
-       map.path = "tmp/fallback/0";
+       map.path = "fallback/0";
        cache_commit_file(&map);
        map.url = "https://domain/rpki/ta51.cer";
-       map.path = "tmp/https/51";
+       map.path = "https/51";
        cache_commit_file(&map);
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           "tmp/fallback/0", "A",
-           "tmp/fallback/2", "B",
-           NULL);
+       ck_filesystem("fallback", "fallback/0", "A", "fallback/2", "B", NULL);
 
        new_iteration(false);
 
        /* 5 */
        commit_fallbacks();
-       ck_filesystem("tmp/fallback", NULL);
+       ck_filesystem("fallback", NULL);
 
        cache_foreach(delete_node);
 }
@@ -620,55 +615,55 @@ START_TEST(test_rrdp_commit)
 
        setup_test();
 
-       ck_assert_int_eq(0, system("mkdir -p tmp/rrdp/0 tmp/rrdp/1 tmp/rrdp/2 tmp/rrdp/3"));
+       ck_assert_int_eq(0, system("mkdir rrdp/0 rrdp/1 rrdp/2 rrdp/3"));
 
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/0/0", "A"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/0/1", "B"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/1/0", "C"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/1/1", "D"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/2/0", "E"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/2/1", "F"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/3/0", "G"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/3/1", "H"));
-       ck_assert_int_eq(0, write_simple_file("tmp/rrdp/3/2", "I"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/0/0", "A"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/0/1", "B"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/1/0", "C"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/1/1", "D"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/2/0", "E"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/2/1", "F"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/3/0", "G"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/3/1", "H"));
+       ck_assert_int_eq(0, write_simple_file("rrdp/3/2", "I"));
 
        /* 1, 2 */
        for (i = 0; i < 2; i++) {
                commit_fallbacks();
-               ck_filesystem("tmp/fallback", NULL);
+               ck_filesystem("fallback", NULL);
 
                new_iteration(false);
        }
 
        /* 3 */
-       queue_commit("rsync://domain/mod/rpp0", "tmp/rrdp/0/0", "tmp/rrdp/0/1");
-       queue_commit("rsync://domain/mod/rpp2", "tmp/rrdp/2/0", "tmp/rrdp/2/1");
-       queue_commit("rsync://domain/mod/rpp3", "tmp/rrdp/3/0", "tmp/rrdp/3/2");
+       queue_commit("rsync://domain/mod/rpp0", "rrdp/0/0", "rrdp/0/1");
+       queue_commit("rsync://domain/mod/rpp2", "rrdp/2/0", "rrdp/2/1");
+       queue_commit("rsync://domain/mod/rpp3", "rrdp/3/0", "rrdp/3/2");
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           "tmp/fallback/0/0", "A", "tmp/fallback/0/1", "B",
-           "tmp/fallback/1/0", "E", "tmp/fallback/1/1", "F",
-           "tmp/fallback/2/0", "G", "tmp/fallback/2/1", "I",
+       ck_filesystem("fallback",
+           "fallback/0/0", "A", "fallback/0/1", "B",
+           "fallback/1/0", "E", "fallback/1/1", "F",
+           "fallback/2/0", "G", "fallback/2/1", "I",
            NULL);
 
        new_iteration(false);
 
        /* 4 */
-       queue_commit("rsync://domain/mod/rpp0", "tmp/fallback/0/0", "tmp/fallback/0/1");
-       queue_commit("rsync://domain/mod/rpp1", "tmp/rrdp/1/0", "tmp/rrdp/1/1");
-       queue_commit("rsync://domain/mod/rpp3", "tmp/fallback/2/0", "tmp/rrdp/3/1");
+       queue_commit("rsync://domain/mod/rpp0", "fallback/0/0", "fallback/0/1");
+       queue_commit("rsync://domain/mod/rpp1", "rrdp/1/0", "rrdp/1/1");
+       queue_commit("rsync://domain/mod/rpp3", "fallback/2/0", "rrdp/3/1");
        commit_fallbacks();
-       ck_filesystem("tmp/fallback",
-           "tmp/fallback/0/0", "A", "tmp/fallback/0/1", "B",
-           "tmp/fallback/2/0", "G", "tmp/fallback/2/2", "H",
-           "tmp/fallback/3/0", "C", "tmp/fallback/3/1", "D",
+       ck_filesystem("fallback",
+           "fallback/0/0", "A", "fallback/0/1", "B",
+           "fallback/2/0", "G", "fallback/2/2", "H",
+           "fallback/3/0", "C", "fallback/3/1", "D",
            NULL);
 
        new_iteration(false);
 
        /* 5 */
        commit_fallbacks();
-       ck_filesystem("tmp/fallback", NULL);
+       ck_filesystem("fallback", NULL);
 
        cache_foreach(delete_node);
 }
@@ -708,8 +703,17 @@ int main(void)
        SRunner *runner;
        int tests_failed;
 
-       suite = create_suite();
        dls[0] = "Fort\n";
+       if (mkdir("tmp", CACHE_FILEMODE) < 0 && errno != EEXIST) {
+               fprintf(stderr, "mkdir('tmp/'): %s\n", strerror(errno));
+               return 1;
+       }
+       if (chdir("tmp") < 0) {
+               fprintf(stderr, "chdir('tmp/'): %s\n", strerror(errno));
+               return 1;
+       }
+
+       suite = create_suite();
 
        runner = srunner_create(suite);
        srunner_run_all(runner, CK_NORMAL);
index 5633b6a1ebb1a2c3753c7977e105afc4f092b89f..902c5dbd82d930d37c5cc51b1cdbd5501954c5c7 100644 (file)
@@ -89,6 +89,7 @@ START_TEST(startup)
        seq.prefix = "tmp/rrdp";
        seq.next_id = 0;
        seq.pathlen = strlen(seq.prefix);
+       seq.free_prefix = false;
 
        dls[0] = NHDR("3")
                NSS("https://host/9d-8/3/snapshot.xml",