From 2e7766655abd0312a6bf4db6a6ff141e7e4ac8b6 Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Sat, 1 Sep 2007 02:36:31 -0700 Subject: URL: allow port specification in ssh:// URLs Allow port specification in ssh:// URLs in the usual notation: ssh://[user@]host.domain[:]/ This allows git to be used over ssh-tunneling networks. Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano diff --git a/Documentation/urls.txt b/Documentation/urls.txt index b38145f..e67f914 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -10,6 +10,7 @@ to name the remote repository: - https://host.xz/path/to/repo.git/ - git://host.xz/path/to/repo.git/ - git://host.xz/~user/path/to/repo.git/ +- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git @@ -18,7 +19,8 @@ to name the remote repository: SSH is the default transport protocol over the network. You can optionally specify which user to log-in as, and an alternate, scp-like syntax is also supported. Both syntaxes support -username expansion, as does the native git protocol. The following +username expansion, as does the native git protocol, but +only the former supports port specification. The following three are identical to the last three above, respectively: =============================================================== diff --git a/connect.c b/connect.c index ae49c5a..8b1e993 100644 --- a/connect.c +++ b/connect.c @@ -453,6 +453,22 @@ static void git_proxy_connect(int fd[2], char *host) #define MAX_CMD_LEN 1024 +char *get_port(char *host) +{ + char *end; + char *p = strchr(host, ':'); + + if (p) { + strtol(p+1, &end, 10); + if (*end == '\0') { + *p = '\0'; + return p+1; + } + } + + return NULL; +} + /* * This returns 0 if the transport protocol does not need fork(2), * or a process id if it does. Once done, finish the connection @@ -471,6 +487,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags) pid_t pid; enum protocol protocol = PROTO_LOCAL; int free_path = 0; + char *port = NULL; /* Without this we cannot rely on waitpid() to tell * what happened to our children. @@ -527,6 +544,12 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags) *ptr = '\0'; } + /* + * Add support for ssh port: ssh://host.xy:/... + */ + if (protocol == PROTO_SSH && host != url) + port = get_port(host); + if (protocol == PROTO_GIT) { /* These underlying connection commands die() if they * cannot connect. @@ -583,7 +606,12 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags) ssh_basename = ssh; else ssh_basename++; - execlp(ssh, ssh_basename, host, command, NULL); + + if (!port) + execlp(ssh, ssh_basename, host, command, NULL); + else + execlp(ssh, ssh_basename, "-p", port, host, + command, NULL); } else { unsetenv(ALTERNATE_DB_ENVIRONMENT); -- cgit v0.10.2-6-g49f6