diff options
author | Paul Collins <paul@briny.ondioline.org> | 2005-11-04 17:57:16 +0300 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-11-22 00:48:58 +0300 |
commit | f801477645146fd7eff018b4997b86dfa1a0767d (patch) | |
tree | 463a215c061858a9a1637e00f383998fb1809cd4 /connect.c | |
parent | ce335fe04f32261e0204280281989ffbb5d990c6 (diff) |
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 <junkio@cox.net>
Diffstat (limited to 'connect.c')
-rw-r--r-- | connect.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/connect.c b/connect.c index 73187a1e932..be88ef03882 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"); |