summaryrefslogtreecommitdiff
path: root/connect.c
diff options
context:
space:
mode:
authorMike Hommey <mh@glandium.org>2016-05-27 11:27:51 +0900
committerJunio C Hamano <gitster@pobox.com>2016-06-01 12:53:12 -0700
commitb945533ba9cbb6b56190ebd004d353db4e24acdb (patch)
treebb717061292339c3f826f4661afb41eb3729afbd /connect.c
parenta724c2dfeb374815eaa004b75f01455422580c40 (diff)
downloadgit-b945533ba9cbb6b56190ebd004d353db4e24acdb.tar.gz
connect: make parse_connect_url() return separated host and port
Now that nothing besides CONNECT_DIAG_URL is using hostandport, we can have parse_connect_url() itself do the host and port splitting. This still leaves "user@" part of the host, if there is one, which will be addressed in a subsequent change. This however does add /some/ handling of the "user@" part of the host, in order to pick the port properly. Signed-off-by: Mike Hommey <mh@glandium.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'connect.c')
-rw-r--r--connect.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/connect.c b/connect.c
index 3d7bd8eb7f..de7419e9ca 100644
--- a/connect.c
+++ b/connect.c
@@ -589,10 +589,11 @@ static char *get_port(char *host)
* The caller must free() the returned strings.
*/
static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
- char **ret_path)
+ char **ret_port, char **ret_path)
{
char *url;
char *host, *path;
+ const char *port = NULL;
char *end;
int separator = '/';
enum protocol protocol = PROTO_LOCAL;
@@ -647,7 +648,27 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
path = xstrdup(path);
*end = '\0';
+ get_host_and_port(&host, &port);
+
+ if (*host && !port) {
+ /*
+ * get_host_and_port does not return a port in the
+ * [host:port]:path case. In that case, it is called with
+ * "[host:port]" and returns "host:port" and NULL.
+ * To support this undocumented legacy we still need to split
+ * the port.
+ * "host:port" may also look like "user@host:port". As the
+ * `user` portion tends to be less strict than `host:port`,
+ * we first put it out of the equation: since a hostname
+ * cannot contain a '@', we start from the last '@' in the
+ * string.
+ */
+ char *end_user = strrchr(host, '@');
+ port = get_port(end_user ? end_user : host);
+ }
+
*ret_host = xstrdup(host);
+ *ret_port = port ? xstrdup(port) : NULL;
*ret_path = path;
free(url);
return protocol;
@@ -669,8 +690,7 @@ static struct child_process no_fork = CHILD_PROCESS_INIT;
struct child_process *git_connect(int fd[2], const char *url,
const char *prog, int flags)
{
- char *hostandport, *path, *host;
- const char *port = NULL;
+ char *host, *port, *path;
struct child_process *conn = &no_fork;
enum protocol protocol;
struct strbuf cmd = STRBUF_INIT;
@@ -680,13 +700,12 @@ struct child_process *git_connect(int fd[2], const char *url,
*/
signal(SIGCHLD, SIG_DFL);
- protocol = parse_connect_url(url, &hostandport, &path);
- host = xstrdup(hostandport);
- get_host_and_port(&host, &port);
+ protocol = parse_connect_url(url, &host, &port, &path);
if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) {
printf("Diag: url=%s\n", url ? url : "NULL");
printf("Diag: protocol=%s\n", prot_name(protocol));
- printf("Diag: hostandport=%s\n", hostandport ? hostandport : "NULL");
+ printf("Diag: userandhost=%s\n", host ? host : "NULL");
+ printf("Diag: port=%s\n", port ? port : "NONE");
printf("Diag: path=%s\n", path ? path : "NULL");
conn = NULL;
} else if (protocol == PROTO_GIT) {
@@ -754,16 +773,6 @@ struct child_process *git_connect(int fd[2], const char *url,
int putty = 0, tortoiseplink = 0;
transport_check_allowed("ssh");
- /*
- * get_host_and_port does not return a port in the
- * [host:port]:path case. In that case, it is called
- * with "[host:port]" and returns "host:port" and NULL.
- * To support this undocumented legacy we still need
- * to split the port.
- */
- if (!port)
- port = get_port(host);
-
if (flags & CONNECT_DIAG_URL) {
printf("Diag: url=%s\n", url ? url : "NULL");
printf("Diag: protocol=%s\n", prot_name(protocol));
@@ -771,8 +780,8 @@ struct child_process *git_connect(int fd[2], const char *url,
printf("Diag: port=%s\n", port ? port : "NONE");
printf("Diag: path=%s\n", path ? path : "NULL");
- free(hostandport);
free(host);
+ free(port);
free(path);
free(conn);
return NULL;
@@ -831,8 +840,8 @@ struct child_process *git_connect(int fd[2], const char *url,
fd[1] = conn->in; /* write to child's stdin */
strbuf_release(&cmd);
}
- free(hostandport);
free(host);
+ free(port);
free(path);
return conn;
}