5 #include <sys/socket.h>
6 #include <netinet/in.h>
10 int get_ack(int fd, unsigned char *result_sha1)
12 static char line[1000];
13 int len = packet_read_line(fd, line, sizeof(line));
16 die("git-fetch-pack: expected ACK/NAK, got EOF");
17 if (line[len-1] == '\n')
19 if (!strcmp(line, "NAK"))
21 if (!strncmp(line, "ACK ", 3)) {
22 if (!get_sha1_hex(line+4, result_sha1))
25 die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
28 int path_match(const char *path, int nr, char **match)
31 int pathlen = strlen(path);
33 for (i = 0; i < nr; i++) {
37 if (!len || len > pathlen)
39 if (memcmp(path + pathlen - len, s, len))
41 if (pathlen > len && path[pathlen - len - 1] != '/')
55 static enum protocol get_protocol(const char *name)
57 if (!strcmp(name, "ssh"))
59 if (!strcmp(name, "git"))
61 die("I don't handle protocol '%s'", name);
64 static void lookup_host(const char *host, struct sockaddr *in)
69 ret = getaddrinfo(host, NULL, NULL, &res);
71 die("Unable to look up %s (%s)", host, gai_strerror(ret));
76 static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
79 int port = DEFAULT_GIT_PORT, sockfd;
82 colon = strchr(host, ':');
85 unsigned long n = strtoul(colon+1, &end, 0);
86 if (colon[1] && !*end) {
92 lookup_host(host, &addr);
93 ((struct sockaddr_in *)&addr)->sin_port = htons(port);
95 sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
97 die("unable to create socket (%s)", strerror(errno));
98 if (connect(sockfd, (void *)&addr, sizeof(addr)) < 0)
99 die("unable to connect (%s)", strerror(errno));
102 packet_write(sockfd, "%s %s\n", prog, path);
107 * Yeah, yeah, fixme. Need to pass in the heads etc.
109 int git_connect(int fd[2], char *url, const char *prog)
116 enum protocol protocol;
120 colon = strchr(url, ':');
121 protocol = PROTO_LOCAL;
126 protocol = PROTO_SSH;
127 if (!memcmp(path, "//", 2)) {
128 char *slash = strchr(path + 2, '/');
130 int nr = slash - path - 2;
131 memmove(path, path+2, nr);
133 protocol = get_protocol(url);
140 if (protocol == PROTO_GIT)
141 return git_tcp_connect(fd, prog, host, path);
143 if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
144 die("unable to create pipe pair for communication");
147 snprintf(command, sizeof(command), "%s %s", prog,
149 dup2(pipefd[1][0], 0);
150 dup2(pipefd[0][1], 1);
155 if (protocol == PROTO_SSH)
156 execlp("ssh", "ssh", host, command, NULL);
158 execlp("sh", "sh", "-c", command, NULL);
161 fd[0] = pipefd[0][0];
162 fd[1] = pipefd[1][1];
168 int finish_connect(pid_t pid)
173 ret = waitpid(pid, NULL, 0);