405
const char *token;
406
};
407
408
+static void promisor_info_free(struct promisor_info *p)
409
+{
410
+ free((char *)p->name);
411
+ free((char *)p->url);
412
+ free((char *)p->filter);
413
+ free((char *)p->token);
414
+ free(p);
415
+}
416
+
417
static void promisor_info_list_clear(struct string_list *list)
418
{
410
- for (size_t i = 0; i < list->nr; i++) {
411
- struct promisor_info *p = list->items[i].util;
412
- free((char *)p->name);
413
- free((char *)p->url);
414
- free((char *)p->filter);
415
- free((char *)p->token);
416
- }
417
- string_list_clear(list, 1);
419
+ for (size_t i = 0; i < list->nr; i++)
420
+ promisor_info_free(list->items[i].util);
421
+ string_list_clear(list, 0);
422
}
423
424
static void set_one_field(struct promisor_info *p,
535
};
536
537
static int should_accept_remote(enum accept_promisor accept,
534
- const char *remote_name, const char *remote_url,
538
+ struct promisor_info *advertised,
539
struct string_list *config_info)
540
{
541
struct promisor_info *p;
542
struct string_list_item *item;
543
+ const char *remote_name = advertised->name;
544
+ const char *remote_url = advertised->url;
545
546
if (accept == ACCEPT_ALL)
547
return 1;
584
return 1;
585
}
586
587
+static struct promisor_info *parse_one_advertised_remote(const char *remote_info)
588
+{
589
+ struct promisor_info *info = xcalloc(1, sizeof(*info));
590
+ struct string_list elem_list = STRING_LIST_INIT_DUP;
591
+ struct string_list_item *item;
592
+
593
+ string_list_split(&elem_list, remote_info, ",", -1);
594
+
595
+ for_each_string_list_item(item, &elem_list) {
596
+ const char *elem = item->string;
597
+ const char *p = strchr(elem, '=');
598
+
599
+ if (!p) {
600
+ warning(_("invalid element '%s' from remote info"), elem);
601
+ continue;
602
+ }
603
+
604
+ if (skip_field_name_prefix(elem, promisor_field_name, &p))
605
+ info->name = url_percent_decode(p);
606
+ else if (skip_field_name_prefix(elem, promisor_field_url, &p))
607
+ info->url = url_percent_decode(p);
608
+ }
609
+
610
+ string_list_clear(&elem_list, 0);
611
+
612
+ if (!info->name || !info->url) {
613
+ warning(_("server advertised a promisor remote without a name or URL: %s"),
614
+ remote_info);
615
+ promisor_info_free(info);
616
+ return NULL;
617
+ }
618
+
619
+ return info;
620
+}
621
+
622
static void filter_promisor_remote(struct repository *repo,
623
struct strvec *accepted,
624
const char *info)
655
remotes = strbuf_split_str(info, ';', 0);
656
657
for (size_t i = 0; remotes[i]; i++) {
617
- struct strbuf **elems;
618
- const char *remote_name = NULL;
619
- const char *remote_url = NULL;
620
- char *decoded_name = NULL;
621
- char *decoded_url = NULL;
658
+ struct promisor_info *advertised;
659
660
strbuf_strip_suffix(remotes[i], ";");
624
- elems = strbuf_split(remotes[i], ',');
661
626
- for (size_t j = 0; elems[j]; j++) {
627
- strbuf_strip_suffix(elems[j], ",");
628
- if (!skip_field_name_prefix(elems[j]->buf, promisor_field_name, &remote_name))
629
- skip_field_name_prefix(elems[j]->buf, promisor_field_url, &remote_url);
630
- }
662
+ advertised = parse_one_advertised_remote(remotes[i]->buf);
663
632
- if (remote_name)
633
- decoded_name = url_percent_decode(remote_name);
634
- if (remote_url)
635
- decoded_url = url_percent_decode(remote_url);
664
+ if (!advertised)
665
+ continue;
666
637
- if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &config_info))
638
- strvec_push(accepted, decoded_name);
667
+ if (should_accept_remote(accept, advertised, &config_info))
668
+ strvec_push(accepted, advertised->name);
669
640
- strbuf_list_free(elems);
641
- free(decoded_name);
642
- free(decoded_url);
670
+ promisor_info_free(advertised);
671
}
672
673
promisor_info_list_clear(&config_info);