summaryrefslogtreecommitdiff
path: root/connect.c
diff options
context:
space:
mode:
authorPaul Collins <paul@briny.ondioline.org>2005-11-04 14:57:16 +0000
committerJunio C Hamano <junkio@cox.net>2005-11-21 13:48:58 -0800
commitf801477645146fd7eff018b4997b86dfa1a0767d (patch)
tree463a215c061858a9a1637e00f383998fb1809cd4 /connect.c
parentce335fe04f32261e0204280281989ffbb5d990c6 (diff)
downloadgit-f801477645146fd7eff018b4997b86dfa1a0767d.tar.gz
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.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/connect.c b/connect.c
index 73187a1e93..be88ef0388 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");