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);