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