continue;
if (nr_match && !path_match(name, nr_match, match))
continue;
- ref = xcalloc(1, sizeof(*ref) + len - 40);
+ ref = alloc_ref(len - 40);
hashcpy(ref->old_sha1, old_sha1);
memcpy(ref->name, buffer + 41, len - 40);
*list = ref;
return PROTO_SSH;
if (!strcmp(name, "ssh+git"))
return PROTO_SSH;
+ if (!strcmp(name, "file"))
+ return PROTO_LOCAL;
die("I don't handle protocol '%s'", name);
}
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;
+ git_proxy_command = xmemdupz(value, matchlen);
}
return 0;
}
#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
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.
end = host;
path = strchr(end, c);
- if (c == ':') {
- if (path) {
+ if (path) {
+ if (c == ':') {
protocol = PROTO_SSH;
*path++ = '\0';
- } else
- path = host;
- }
+ }
+ } else
+ path = end;
if (!path || !*path)
die("No path specified. See 'man git-pull' for valid url syntax");
*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.
if (pid < 0)
die("unable to fork");
if (!pid) {
- char command[MAX_CMD_LEN];
- char *posn = command;
- int size = MAX_CMD_LEN;
- int of = 0;
-
- of |= add_to_string(&posn, &size, prog, 0);
- of |= add_to_string(&posn, &size, " ", 0);
- of |= add_to_string(&posn, &size, path, 1);
+ struct strbuf cmd;
- if (of)
+ strbuf_init(&cmd, MAX_CMD_LEN);
+ strbuf_addstr(&cmd, prog);
+ strbuf_addch(&cmd, ' ');
+ sq_quote_buf(&cmd, path);
+ if (cmd.len >= MAX_CMD_LEN)
die("command line too long");
dup2(pipefd[1][0], 0);
ssh_basename = ssh;
else
ssh_basename++;
- execlp(ssh, ssh_basename, host, command, NULL);
+
+ if (!port)
+ execlp(ssh, ssh_basename, host, cmd.buf, NULL);
+ else
+ execlp(ssh, ssh_basename, "-p", port, host,
+ cmd.buf, NULL);
}
else {
unsetenv(ALTERNATE_DB_ENVIRONMENT);
unsetenv(GIT_WORK_TREE_ENVIRONMENT);
unsetenv(GRAFT_ENVIRONMENT);
unsetenv(INDEX_ENVIRONMENT);
- execlp("sh", "sh", "-c", command, NULL);
+ execlp("sh", "sh", "-c", cmd.buf, NULL);
}
die("exec failed");
}