On Tue, May 26, 2015 at 6:01 PM, Stefan Beller <sbeller@xxxxxxxxxx> wrote: > Instead of calling get_remote_heads as a first command during the > protocol exchange, we need to have fine grained control over the > capability negotiation in version 2 of the protocol. > > Introduce get_remote_capabilities, which will just listen to > capabilities of the remote and request_capabilities which will > tell the selection of capabilities to the remote. > > Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> > --- > diff --git a/connect.c b/connect.c > index c0144d8..bb17618 100644 > --- a/connect.c > +++ b/connect.c > @@ -105,8 +105,54 @@ static void annotate_refs_with_symref_info(struct ref *ref) > string_list_clear(&symref, 0); > } > > +void get_remote_capabilities(int in, char *src_buf, size_t src_len) > +{ > + struct strbuf capabilities_string = STRBUF_INIT; > + for (;;) { > + int len; > + char *line = packet_buffer; > + const char *arg; > + > + len = packet_read(in, &src_buf, &src_len, > + packet_buffer, sizeof(packet_buffer), > + PACKET_READ_GENTLE_ON_EOF | > + PACKET_READ_CHOMP_NEWLINE); > + if (len < 0) > + die_initial_contact(0); > + > + if (!len) > + break; > + > + if (len > 4 && skip_prefix(line, "ERR ", &arg)) The 'len > 4' check is needed because there's no guarantee that 'line' is NUL-terminated. Correct? > + die("remote error: %s", arg); > + > + if (starts_with(line, "capability:")) { > + strbuf_addstr(&capabilities_string, line + strlen("capability:")); skip_prefix() maybe? > + strbuf_addch(&capabilities_string, ' '); > + } > + } > + free(server_capabilities); > + server_capabilities = xmalloc(capabilities_string.len + 1); > + server_capabilities = strbuf_detach(&capabilities_string, NULL); So, you're allocating a buffer for server_capabilities and then immediately throwing away (leaking) that buffer. Seems fishy. > + strbuf_release(&capabilities_string); Not outright incorrect, but you've just detached capabilities_string's buffer, so releasing it doesn't buy anything. > +} > + > +int request_capabilities(int out) > +{ > + fprintf(stderr, "request_capabilities\n"); > + // todo: send our capabilities > + packet_write(out, "capability:foo"); > + packet_flush(out); > +} > + > /* > - * Read all the refs from the other end > + * Read all the refs from the other end, > + * in is a file descriptor input stream > + * src_buf and src_len may be an alternative way to specify the input. The bit about src_buf and src_len conveys little or nothing. After reading it, I'm as clueless to their purpose as I would be if they were undocumented. > + * list is the output of refs > + * extra_have is a list to store information learned about sha1 the other side has. > + * shallow_points 'shallow_points' what? > */ > struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, > struct ref **list, unsigned int flags, > diff --git a/remote.h b/remote.h > index 04e2310..7381ddf 100644 > --- a/remote.h > +++ b/remote.h > @@ -146,6 +146,9 @@ int check_ref_type(const struct ref *ref, int flags); > void free_refs(struct ref *ref); > > struct sha1_array; > + > +extern void get_remote_capabilities(int in, char *src_buf, size_t src_len); > +extern int request_capabilities(int out); > extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, > struct ref **list, unsigned int flags, > struct sha1_array *extra_have, > -- > 2.4.1.345.gab207b6.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html