Signed-off-by: Mike Hommey <m...@glandium.org>
---
 connect.c | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/connect.c b/connect.c
index 8813f90..e95e385 100644
--- a/connect.c
+++ b/connect.c
@@ -588,11 +588,13 @@ static char *get_port(char *host)
  * Extract protocol and relevant parts from the specified connection URL.
  * The caller must free() the returned strings.
  */
-static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
-                                      char **ret_port, char **ret_path)
+static enum protocol parse_connect_url(const char *url_orig, char **ret_user,
+                                      char **ret_host, char **ret_port,
+                                      char **ret_path)
 {
        char *url;
        char *host, *path;
+       const char *user = NULL;
        const char *port = NULL;
        char *end;
        int separator = '/';
@@ -650,13 +652,20 @@ static enum protocol parse_connect_url(const char 
*url_orig, char **ret_host,
 
        get_host_and_port(&host, &port);
 
-       if (*host && !port) {
+       if (*host) {
                /* The host might contain a user:password string, ignore it
                 * when searching for the port again */
                char *end_user = strrchr(host, '@');
-               port = get_port(end_user ? end_user : host);
+               if (end_user) {
+                       *end_user = '\0';
+                       user = host;
+                       host = end_user + 1;
+               }
        }
+       if (!port)
+               port = get_port(host);
 
+       *ret_user = user ? xstrdup(user) : NULL;
        *ret_host = xstrdup(host);
        *ret_port = port ? xstrdup(port) : NULL;
        *ret_path = path;
@@ -680,7 +689,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 *host, *port, *path;
+       char *user, *host, *port, *path;
        struct child_process *conn = &no_fork;
        enum protocol protocol;
        struct strbuf cmd = STRBUF_INIT;
@@ -690,11 +699,14 @@ struct child_process *git_connect(int fd[2], const char 
*url,
         */
        signal(SIGCHLD, SIG_DFL);
 
-       protocol = parse_connect_url(url, &host, &port, &path);
+       protocol = parse_connect_url(url, &user, &host, &port, &path);
        if (flags & CONNECT_DIAG_URL) {
                printf("Diag: url=%s\n", url ? url : "NULL");
                printf("Diag: protocol=%s\n", prot_name(protocol));
-               printf("Diag: userandhost=%s\n", host ? host : "NULL");
+               if (user)
+                       printf("Diag: userandhost=%s@%s\n", user, host);
+               else
+                       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;
@@ -801,7 +813,15 @@ struct child_process *git_connect(int fd[2], const char 
*url,
                                argv_array_push(&conn->args, putty ? "-P" : 
"-p");
                                argv_array_push(&conn->args, port);
                        }
-                       argv_array_push(&conn->args, host);
+                       if (user) {
+                               struct strbuf userandhost = STRBUF_INIT;
+                               strbuf_addstr(&userandhost, user);
+                               strbuf_addch(&userandhost, '@');
+                               strbuf_addstr(&userandhost, host);
+                               argv_array_push(&conn->args, userandhost.buf);
+                               strbuf_release(&userandhost);
+                       } else
+                               argv_array_push(&conn->args, host);
                } else {
                        transport_check_allowed("file");
                }
@@ -814,6 +834,7 @@ struct child_process *git_connect(int fd[2], const char 
*url,
                fd[1] = conn->in;  /* write to child's stdin */
                strbuf_release(&cmd);
        }
+       free(user);
        free(host);
        free(port);
        free(path);
-- 
2.8.1.16.gaa70619.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to