+static int fetch_alternates(char *base)
+{
+ int ret = 0;
+ struct buffer buffer;
+ char *url;
+ char *data;
+ int i = 0;
+ if (got_alternates)
+ return 0;
+ data = xmalloc(4096);
+ buffer.size = 4096;
+ buffer.posn = 0;
+ buffer.buffer = data;
+
+ if (get_verbosely)
+ fprintf(stderr, "Getting alternates list\n");
+
+ url = xmalloc(strlen(base) + 31);
+ sprintf(url, "%s/objects/info/http-alternates", base);
+
+ curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ if (curl_easy_perform(curl) || !buffer.posn) {
+ sprintf(url, "%s/objects/info/alternates", base);
+
+ curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ if (curl_easy_perform(curl)) {
+ return 0;
+ }
+ }
+
+ while (i < buffer.posn) {
+ int posn = i;
+ while (posn < buffer.posn && data[posn] != '\n')
+ posn++;
+ if (data[posn] == '\n') {
+ if (data[i] == '/') {
+ int serverlen = strchr(base + 8, '/') - base;
+ // skip 'objects' at end
+ char *target =
+ xmalloc(serverlen + posn - i - 6);
+ struct alt_base *newalt;
+ strncpy(target, base, serverlen);
+ strncpy(target + serverlen, data + i,
+ posn - i - 7);
+ target[serverlen + posn - i - 7] = '\0';
+ if (get_verbosely)
+ fprintf(stderr,
+ "Also look at %s\n", target);
+ newalt = xmalloc(sizeof(*newalt));
+ newalt->next = alt;
+ newalt->base = target;
+ newalt->got_indices = 0;
+ newalt->packs = NULL;
+ alt = newalt;
+ ret++;
+ }
+ }
+ i = posn + 1;
+ }
+ got_alternates = 1;
+
+ return ret;
+}
+
+static int fetch_indices(struct alt_base *repo)