}
static int
-traverse_tal(char const *tal_path)
+try_urls(struct tal *tal, bool (*url_is_protocol)(char const *),
+ char *(*get_path)(char const *))
{
- struct tal tal;
char **url;
struct cache_mapping map;
- int error;
-
- fnstack_push(tal_path);
-
- error = tal_init(&tal, tal_path);
- if (error)
- goto end1;
- /* Online attempts */
- ARRAYLIST_FOREACH(&tal.urls, url) {
+ ARRAYLIST_FOREACH(&tal->urls, url) {
map.url = *url;
+ if (!url_is_protocol(map.url))
+ continue;
// XXX if this is rsync, it seems this will queue and fail
- map.path = cache_refresh_by_url(*url);
+ map.path = get_path(*url);
if (!map.path)
continue;
- if (validate_ta(&tal, &map) != 0)
+ if (validate_ta(tal, &map) != 0)
continue;
cache_commit_file(&map);
- goto end2; /* Happy path */
+ return 0;
}
+ return ESRCH;
+}
+
+static int
+traverse_tal(char const *tal_path)
+{
+ struct tal tal;
+ int error;
+
+ fnstack_push(tal_path);
+
+ error = tal_init(&tal, tal_path);
+ if (error)
+ goto end1;
+
+ /* Online attempts */
+ if (try_urls(&tal, url_is_https, cache_refresh_by_url) == 0)
+ goto end2;
+ if (try_urls(&tal, url_is_rsync, cache_refresh_by_url) == 0)
+ goto end2;
/* Offline fallback attempts */
- ARRAYLIST_FOREACH(&tal.urls, url) {
- map.url = *url;
- map.path = cache_get_fallback(*url);
- if (!map.path)
- continue;
- if (validate_ta(&tal, &map) != 0)
- continue;
- cache_commit_file(&map);
- goto end2; /* Happy path */
- }
+ if (try_urls(&tal, url_is_https, cache_get_fallback) == 0)
+ goto end2;
+ if (try_urls(&tal, url_is_rsync, cache_get_fallback) == 0)
+ goto end2;
pr_op_err("None of the TAL URIs yielded a successful traversal.");
error = EINVAL;