const char *token;
};
+static void promisor_info_free(struct promisor_info *p)
+{
+ free((char *)p->name);
+ free((char *)p->url);
+ free((char *)p->filter);
+ free((char *)p->token);
+ free(p);
+}
+
static void promisor_info_list_clear(struct string_list *list)
{
- for (size_t i = 0; i < list->nr; i++) {
- struct promisor_info *p = list->items[i].util;
- free((char *)p->name);
- free((char *)p->url);
- free((char *)p->filter);
- free((char *)p->token);
- }
- string_list_clear(list, 1);
+ for (size_t i = 0; i < list->nr; i++)
+ promisor_info_free(list->items[i].util);
+ string_list_clear(list, 0);
}
static void set_one_field(struct promisor_info *p,
};
static int should_accept_remote(enum accept_promisor accept,
- const char *remote_name, const char *remote_url,
+ struct promisor_info *advertised,
struct string_list *config_info)
{
struct promisor_info *p;
struct string_list_item *item;
+ const char *remote_name = advertised->name;
+ const char *remote_url = advertised->url;
if (accept == ACCEPT_ALL)
return 1;
return 0;
}
+static struct promisor_info *parse_one_advertised_remote(struct strbuf *remote_info)
+{
+ struct promisor_info *info = xcalloc(1, sizeof(*info));
+ struct strbuf **elems = strbuf_split(remote_info, ',');
+
+ for (size_t i = 0; elems[i]; i++) {
+ char *elem = elems[i]->buf;
+ char *value;
+ char *p = strchr(elem, '=');
+
+ strbuf_strip_suffix(elems[i], ",");
+
+ if (!p) {
+ warning(_("invalid element '%s' from remote info"), elem);
+ continue;
+ }
+
+ *p = '\0';
+ value = url_percent_decode(p + 1);
+
+ if (!strcmp(elem, "name"))
+ info->name = value;
+ else if (!strcmp(elem, "url"))
+ info->url = value;
+ else
+ free(value);
+ }
+
+ strbuf_list_free(elems);
+
+ if (!info->name || !info->url) {
+ warning(_("server advertised a promisor remote without a name or URL: %s"),
+ remote_info->buf);
+ promisor_info_free(info);
+ return NULL;
+ }
+
+ return info;
+}
+
static void filter_promisor_remote(struct repository *repo,
struct strvec *accepted,
const char *info)
remotes = strbuf_split_str(info, ';', 0);
for (size_t i = 0; remotes[i]; i++) {
- struct strbuf **elems;
- const char *remote_name = NULL;
- const char *remote_url = NULL;
- char *decoded_name = NULL;
- char *decoded_url = NULL;
+ struct promisor_info *advertised;
strbuf_strip_suffix(remotes[i], ";");
- elems = strbuf_split(remotes[i], ',');
- for (size_t j = 0; elems[j]; j++) {
- strbuf_strip_suffix(elems[j], ",");
- if (!skip_prefix(elems[j]->buf, "name=", &remote_name))
- skip_prefix(elems[j]->buf, "url=", &remote_url);
- }
+ advertised = parse_one_advertised_remote(remotes[i]);
- if (remote_name)
- decoded_name = url_percent_decode(remote_name);
- if (remote_url)
- decoded_url = url_percent_decode(remote_url);
+ if (!advertised)
+ continue;
- if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &config_info))
- strvec_push(accepted, decoded_name);
+ if (should_accept_remote(accept, advertised, &config_info))
+ strvec_push(accepted, advertised->name);
- strbuf_list_free(elems);
- free(decoded_name);
- free(decoded_url);
+ promisor_info_free(advertised);
}
promisor_info_list_clear(&config_info);