diff options
author | Johannes Sixt <j6t@kdbg.org> | 2013-11-28 20:49:01 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-12-09 14:54:47 -0800 |
commit | cabc3c12e40f5556bb4de934ab783d53e908e401 (patch) | |
tree | d46836cc6fccf1a6fbd669344d0519cbc3360c1e /connect.c | |
parent | d98d109979760bed1909fbf5e56cbb6239980095 (diff) | |
download | git-cabc3c12e40f5556bb4de934ab783d53e908e401.tar.gz |
git_connect: factor out discovery of the protocol and its parts
git_connect has grown large due to the many different protocols syntaxes
that are supported. Move the part of the function that parses the URL to
connect to into a separate function for readability.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'connect.c')
-rw-r--r-- | connect.c | 80 |
1 files changed, 53 insertions, 27 deletions
@@ -543,37 +543,20 @@ static char *get_port(char *host) return NULL; } -static struct child_process no_fork; - /* - * This returns a dummy child_process if the transport protocol does not - * need fork(2), or a struct child_process object if it does. Once done, - * finish the connection with finish_connect() with the value returned from - * this function (it is safe to call finish_connect() with NULL to support - * the former case). - * - * If it returns, the connect is successful; it just dies on errors (this - * will hopefully be changed in a libification effort, to return NULL when - * the connection failed). + * Extract protocol and relevant parts from the specified connection URL. + * The caller must free() the returned strings. */ -struct child_process *git_connect(int fd[2], const char *url_orig, - const char *prog, int flags) +static enum protocol parse_connect_url(const char *url_orig, char **ret_host, + char **ret_port, char **ret_path) { char *url; char *host, *path; char *end; int c; - struct child_process *conn = &no_fork; enum protocol protocol = PROTO_LOCAL; int free_path = 0; char *port = NULL; - const char **arg; - struct strbuf cmd = STRBUF_INIT; - - /* Without this we cannot rely on waitpid() to tell - * what happened to our children. - */ - signal(SIGCHLD, SIG_DFL); if (is_url(url_orig)) url = url_decode(url_orig); @@ -645,6 +628,49 @@ struct child_process *git_connect(int fd[2], const char *url_orig, if (protocol == PROTO_SSH && host != url) port = get_port(end); + *ret_host = xstrdup(host); + if (port) + *ret_port = xstrdup(port); + else + *ret_port = NULL; + if (free_path) + *ret_path = path; + else + *ret_path = xstrdup(path); + free(url); + return protocol; +} + +static struct child_process no_fork; + +/* + * This returns a dummy child_process if the transport protocol does not + * need fork(2), or a struct child_process object if it does. Once done, + * finish the connection with finish_connect() with the value returned from + * this function (it is safe to call finish_connect() with NULL to support + * the former case). + * + * If it returns, the connect is successful; it just dies on errors (this + * will hopefully be changed in a libification effort, to return NULL when + * the connection failed). + */ +struct child_process *git_connect(int fd[2], const char *url, + const char *prog, int flags) +{ + char *host, *path; + struct child_process *conn = &no_fork; + enum protocol protocol; + char *port; + const char **arg; + struct strbuf cmd = STRBUF_INIT; + + /* Without this we cannot rely on waitpid() to tell + * what happened to our children. + */ + signal(SIGCHLD, SIG_DFL); + + protocol = parse_connect_url(url, &host, &port, &path); + if (protocol == PROTO_GIT) { /* These underlying connection commands die() if they * cannot connect. @@ -666,9 +692,9 @@ struct child_process *git_connect(int fd[2], const char *url_orig, prog, path, 0, target_host, 0); free(target_host); - free(url); - if (free_path) - free(path); + free(host); + free(port); + free(path); return conn; } @@ -709,9 +735,9 @@ struct child_process *git_connect(int fd[2], const char *url_orig, fd[0] = conn->out; /* read from child's stdout */ fd[1] = conn->in; /* write to child's stdin */ strbuf_release(&cmd); - free(url); - if (free_path) - free(path); + free(host); + free(port); + free(path); return conn; } |