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>

Johannes Sixt committed Nov 28, 2013 at 20:49 UTC cabc3c12e40f5556bb4de934ab783d53e908e401
1 file changed +53 -27
connect.c
+53 -27
@@ -543,37 +543,20 @@ static char *get_port(char *host)
543 return NULL;
544 }
545
546 -static struct child_process no_fork;
547 -
546 /*
549 - * This returns a dummy child_process if the transport protocol does not
550 - * need fork(2), or a struct child_process object if it does. Once done,
551 - * finish the connection with finish_connect() with the value returned from
552 - * this function (it is safe to call finish_connect() with NULL to support
553 - * the former case).
554 - *
555 - * If it returns, the connect is successful; it just dies on errors (this
556 - * will hopefully be changed in a libification effort, to return NULL when
557 - * the connection failed).
547 + * Extract protocol and relevant parts from the specified connection URL.
548 + * The caller must free() the returned strings.
549 */
559 -struct child_process *git_connect(int fd[2], const char *url_orig,
560 - const char *prog, int flags)
550 +static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
551 + char **ret_port, char **ret_path)
552 {
553 char *url;
554 char *host, *path;
555 char *end;
556 int c;
566 - struct child_process *conn = &no_fork;
557 enum protocol protocol = PROTO_LOCAL;
558 int free_path = 0;
559 char *port = NULL;
570 - const char **arg;
571 - struct strbuf cmd = STRBUF_INIT;
572 -
573 - /* Without this we cannot rely on waitpid() to tell
574 - * what happened to our children.
575 - */
576 - signal(SIGCHLD, SIG_DFL);
560
561 if (is_url(url_orig))
562 url = url_decode(url_orig);
@@ -645,6 +628,49 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
628 if (protocol == PROTO_SSH && host != url)
629 port = get_port(end);
630
631 + *ret_host = xstrdup(host);
632 + if (port)
633 + *ret_port = xstrdup(port);
634 + else
635 + *ret_port = NULL;
636 + if (free_path)
637 + *ret_path = path;
638 + else
639 + *ret_path = xstrdup(path);
640 + free(url);
641 + return protocol;
642 +}
643 +
644 +static struct child_process no_fork;
645 +
646 +/*
647 + * This returns a dummy child_process if the transport protocol does not
648 + * need fork(2), or a struct child_process object if it does. Once done,
649 + * finish the connection with finish_connect() with the value returned from
650 + * this function (it is safe to call finish_connect() with NULL to support
651 + * the former case).
652 + *
653 + * If it returns, the connect is successful; it just dies on errors (this
654 + * will hopefully be changed in a libification effort, to return NULL when
655 + * the connection failed).
656 + */
657 +struct child_process *git_connect(int fd[2], const char *url,
658 + const char *prog, int flags)
659 +{
660 + char *host, *path;
661 + struct child_process *conn = &no_fork;
662 + enum protocol protocol;
663 + char *port;
664 + const char **arg;
665 + struct strbuf cmd = STRBUF_INIT;
666 +
667 + /* Without this we cannot rely on waitpid() to tell
668 + * what happened to our children.
669 + */
670 + signal(SIGCHLD, SIG_DFL);
671 +
672 + protocol = parse_connect_url(url, &host, &port, &path);
673 +
674 if (protocol == PROTO_GIT) {
675 /* These underlying connection commands die() if they
676 * cannot connect.
@@ -666,9 +692,9 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
692 prog, path, 0,
693 target_host, 0);
694 free(target_host);
669 - free(url);
670 - if (free_path)
671 - free(path);
695 + free(host);
696 + free(port);
697 + free(path);
698 return conn;
699 }
700
@@ -709,9 +735,9 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
735 fd[0] = conn->out; /* read from child's stdout */
736 fd[1] = conn->in; /* write to child's stdin */
737 strbuf_release(&cmd);
712 - free(url);
713 - if (free_path)
714 - free(path);
738 + free(host);
739 + free(port);
740 + free(path);
741 return conn;
742 }
743