From faea9ccbadf75128a9e394dca80ed9454e19c7a9 Mon Sep 17 00:00:00 2001 From: Andreas Ericsson Date: Thu, 17 Nov 2005 20:37:14 +0100 Subject: Client side support for user-relative paths. With this patch, the client side passes identical paths for these two: ssh://host.xz/~junio/repo host.xz:~junio/repo Signed-off-by: Andreas Ericsson Signed-off-by: Junio C Hamano --- connect.c | 55 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'connect.c') diff --git a/connect.c b/connect.c index c2badc71a..73187a1e9 100644 --- a/connect.c +++ b/connect.c @@ -454,34 +454,45 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) int git_connect(int fd[2], char *url, const char *prog) { char command[1024]; - char *host, *path; - char *colon; + char *host, *path = url; + char *colon = NULL; int pipefd[2][2]; pid_t pid; - enum protocol protocol; - - host = NULL; - path = url; - colon = strchr(url, ':'); - protocol = PROTO_LOCAL; - if (colon) { - *colon = 0; + enum protocol protocol = PROTO_LOCAL; + + host = strstr(url, "://"); + if(host) { + *host = '\0'; + protocol = get_protocol(url); + host += 3; + path = strchr(host, '/'); + } + else { host = url; - path = colon+1; - protocol = PROTO_SSH; - if (!memcmp(path, "//", 2)) { - char *slash = strchr(path + 2, '/'); - if (slash) { - int nr = slash - path - 2; - memmove(path, path+2, nr); - path[nr] = 0; - protocol = get_protocol(url); - host = path; - path = slash; - } + if ((colon = strchr(host, ':'))) { + protocol = PROTO_SSH; + *colon = '\0'; + path = colon + 1; } } + if (!path || !*path) + die("No path specified. See 'man git-pull' for valid url syntax"); + + /* + * null-terminate hostname and point path to ~ for URL's like this: + * ssh://host.xz/~user/repo + */ + if (protocol != PROTO_LOCAL && host != url) { + char *ptr = path; + if (path[1] == '~') + path++; + else + path = strdup(ptr); + + *ptr = '\0'; + } + if (protocol == PROTO_GIT) return git_tcp_connect(fd, prog, host, path); -- cgit v1.2.1 From f801477645146fd7eff018b4997b86dfa1a0767d Mon Sep 17 00:00:00 2001 From: Paul Collins Date: Fri, 4 Nov 2005 14:57:16 +0000 Subject: proxy-command support for git:// Here is an updated patch that first looks for GIT_PROXY_COMMAND in the environment and then git.proxycommand in the repository's configuration file. I have left the calling convention the same argv[1] is the host and argv[2] is the port. I've taken the hostname parsing verbatim from git_tcp_connect(), so it should now support an explicit port number and whatever that business with the square brackets is. (Should I move this to a helper function?) Regarding internal vs. external hosts, the proxy command can simply run netcat locally to internal hosts, so perhaps that is sufficient. Signed-off-by: Junio C Hamano --- connect.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'connect.c') diff --git a/connect.c b/connect.c index 73187a1e9..be88ef038 100644 --- a/connect.c +++ b/connect.c @@ -448,6 +448,73 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) #endif /* NO_IPV6 */ +static char *git_proxy_command = NULL; + +static int git_proxy_command_options(const char *var, const char *value) +{ + if (git_proxy_command == NULL) { + if (!strcmp(var, "git.proxycommand")) { + git_proxy_command = xmalloc(strlen(value) + 1); + strcpy(git_proxy_command, value); + return 0; + } + } + + return git_default_config(var, value); +} + +static int git_use_proxy(void) +{ + git_proxy_command = getenv("GIT_PROXY_COMMAND"); + git_config(git_proxy_command_options); + return git_proxy_command != NULL; +} + +static int git_proxy_connect(int fd[2], const char *prog, char *host, char *path) +{ + char *port = STR(DEFAULT_GIT_PORT); + char *colon, *end; + int pipefd[2][2]; + pid_t pid; + + if (host[0] == '[') { + end = strchr(host + 1, ']'); + if (end) { + *end = 0; + end++; + host++; + } else + end = host; + } else + end = host; + colon = strchr(end, ':'); + + if (colon) { + *colon = 0; + port = colon + 1; + } + + if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0) + die("unable to create pipe pair for communication"); + pid = fork(); + if (!pid) { + dup2(pipefd[1][0], 0); + dup2(pipefd[0][1], 1); + close(pipefd[0][0]); + close(pipefd[0][1]); + close(pipefd[1][0]); + close(pipefd[1][1]); + execlp(git_proxy_command, git_proxy_command, host, port, NULL); + die("exec failed"); + } + fd[0] = pipefd[0][0]; + fd[1] = pipefd[1][1]; + close(pipefd[0][1]); + close(pipefd[1][0]); + packet_write(fd[1], "%s %s\n", prog, path); + return pid; +} + /* * Yeah, yeah, fixme. Need to pass in the heads etc. */ @@ -493,8 +560,11 @@ int git_connect(int fd[2], char *url, const char *prog) *ptr = '\0'; } - if (protocol == PROTO_GIT) + if (protocol == PROTO_GIT) { + if (git_use_proxy()) + return git_proxy_connect(fd, prog, host, path); return git_tcp_connect(fd, prog, host, path); + } if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0) die("unable to create pipe pair for communication"); -- cgit v1.2.1 From e814bc4d159f62941fafe135c3008b3ff103444d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 19 Nov 2005 03:48:56 -0800 Subject: git-proxy updates. This builds on top of the git-proxy mechanism Paul Collins did, and updates its configuration mechanism. * GIT_PROXY_COMMAND environment variable is used as the catch-all fallback, as in the original. This has not changed. * Renames proxy configuration variables to core.gitproxy; this has become a multi-value variable per list discussion, most notably from suggestion by Linus. [core] ;# matches www.kernel.org as well gitproxy = netcatter for kernel.org gitproxy = netscatter for sample.xz gitproxy = none for mydomain.xz gitproxy = netcatter-default The values are command names, followed by an optional " for " and domainname; the first tail-match of the domainname determines which proxy command is used. An entry without " for " matches any domain and can be used as the default. The command name "none" is special -- it tells the mechanism not to use any proxy command and use the native git:// connection. Signed-off-by: Junio C Hamano --- connect.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'connect.c') diff --git a/connect.c b/connect.c index be88ef038..a4d6d356f 100644 --- a/connect.c +++ b/connect.c @@ -449,25 +449,63 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) #endif /* NO_IPV6 */ static char *git_proxy_command = NULL; +static const char *rhost_name = NULL; +static int rhost_len; static int git_proxy_command_options(const char *var, const char *value) { - if (git_proxy_command == NULL) { - if (!strcmp(var, "git.proxycommand")) { - git_proxy_command = xmalloc(strlen(value) + 1); - strcpy(git_proxy_command, value); + if (!strcmp(var, "core.gitproxy")) { + if (git_proxy_command) return 0; + /* [core] + * ;# matches www.kernel.org as well + * gitproxy = netcatter-1 for kernel.org + * gitproxy = netcatter-2 for sample.xz + * gitproxy = netcatter-default + */ + const char *for_pos = strstr(value, " for "); + int matchlen = -1; + int hostlen; + + if (!for_pos) + /* matches everybody */ + matchlen = strlen(value); + else { + hostlen = strlen(for_pos + 5); + if (rhost_len < hostlen) + matchlen = -1; + else if (!strncmp(for_pos + 5, + rhost_name + rhost_len - hostlen, + hostlen) && + ((rhost_len == hostlen) || + rhost_name[rhost_len - hostlen -1] == '.')) + matchlen = for_pos - value; + else + matchlen = -1; } + if (0 <= matchlen) { + /* core.gitproxy = none for kernel.org */ + if (matchlen == 4 && + !memcmp(value, "none", 4)) + matchlen = 0; + git_proxy_command = xmalloc(matchlen + 1); + memcpy(git_proxy_command, value, matchlen); + git_proxy_command[matchlen] = 0; + } + return 0; } return git_default_config(var, value); } -static int git_use_proxy(void) +static int git_use_proxy(const char *host) { + rhost_name = host; + rhost_len = strlen(host); git_proxy_command = getenv("GIT_PROXY_COMMAND"); git_config(git_proxy_command_options); - return git_proxy_command != NULL; + rhost_name = NULL; + return (git_proxy_command && *git_proxy_command); } static int git_proxy_connect(int fd[2], const char *prog, char *host, char *path) @@ -561,7 +599,7 @@ int git_connect(int fd[2], char *url, const char *prog) } if (protocol == PROTO_GIT) { - if (git_use_proxy()) + if (git_use_proxy(host)) return git_proxy_connect(fd, prog, host, path); return git_tcp_connect(fd, prog, host, path); } -- cgit v1.2.1 From c3df8568424684bbcc7df7722eb3ec34bdae8b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Tue, 22 Nov 2005 12:18:23 +0900 Subject: GIT: Fix compilation error in connect.c Fix compilation error for gcc-2.95. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Junio C Hamano --- connect.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'connect.c') diff --git a/connect.c b/connect.c index a4d6d356f..7a417e5a7 100644 --- a/connect.c +++ b/connect.c @@ -455,6 +455,10 @@ static int rhost_len; static int git_proxy_command_options(const char *var, const char *value) { if (!strcmp(var, "core.gitproxy")) { + const char *for_pos; + int matchlen = -1; + int hostlen; + if (git_proxy_command) return 0; /* [core] @@ -463,10 +467,7 @@ static int git_proxy_command_options(const char *var, const char *value) * gitproxy = netcatter-2 for sample.xz * gitproxy = netcatter-default */ - const char *for_pos = strstr(value, " for "); - int matchlen = -1; - int hostlen; - + for_pos = strstr(value, " for "); if (!for_pos) /* matches everybody */ matchlen = strlen(value); -- cgit v1.2.1 From c61642185d411e5e3350566a68483e358ca392b9 Mon Sep 17 00:00:00 2001 From: Paul Serice Date: Tue, 22 Nov 2005 07:54:23 -0600 Subject: Fixed git:// IPv4 address problem when compiled with -DNO_IPV6. Failure to dereference a pointer caused incorrect initialization of the IPv4 address when calling connect() when compiled with -DNO_IPV6. With this patch and yesterday's patch for git-daemon, it should now be possible to use the native git protocol for both the client and server on Cygwin. Signed-off-by: Paul Serice Signed-off-by: Junio C Hamano --- connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'connect.c') diff --git a/connect.c b/connect.c index 7a417e5a7..93f6f80d3 100644 --- a/connect.c +++ b/connect.c @@ -427,7 +427,7 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path) memset(&sa, 0, sizeof sa); sa.sin_family = he->h_addrtype; sa.sin_port = htons(nport); - memcpy(&sa.sin_addr, ap, he->h_length); + memcpy(&sa.sin_addr, *ap, he->h_length); if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { close(sockfd); -- cgit v1.2.1