URL: allow port specification in ssh:// URLs
authorLuben Tuikov <ltuikov@yahoo.com>
Sat, 1 Sep 2007 09:36:31 +0000 (02:36 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 1 Sep 2007 10:35:29 +0000 (03:35 -0700)
Allow port specification in ssh:// URLs in the
usual notation:

ssh://[user@]host.domain[:<port>]/<path>

This allows git to be used over ssh-tunneling
networks.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/urls.txt
connect.c
index b38145faff384344fde354152db186275ebeb5ca..e67f9140ab6be15499b60a8a87ec524a5357a284 100644 (file)
@@ -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:
 
 ===============================================================
index ae49c5a367f9f5b77b07228fcd241fd73a5711b0..8b1e9935a85b639f6c48298d07299f72bceaad29 100644 (file)
--- 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:<port>/...
+        */
+       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);