1#include "cache.h"
2#include "pkt-line.h"
3#include "quote.h"
4#include <sys/wait.h>
5
6int get_ack(int fd, unsigned char *result_sha1)
7{
8 static char line[1000];
9 int len = packet_read_line(fd, line, sizeof(line));
10
11 if (!len)
12 die("git-fetch-pack: expected ACK/NAK, got EOF");
13 if (line[len-1] == '\n')
14 line[--len] = 0;
15 if (!strcmp(line, "NAK"))
16 return 0;
17 if (!strncmp(line, "ACK ", 3)) {
18 if (!get_sha1_hex(line+4, result_sha1))
19 return 1;
20 }
21 die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
22}
23
24int path_match(const char *path, int nr, char **match)
25{
26 int i;
27 int pathlen = strlen(path);
28
29 for (i = 0; i < nr; i++) {
30 char *s = match[i];
31 int len = strlen(s);
32
33 if (!len || len > pathlen)
34 continue;
35 if (memcmp(path + pathlen - len, s, len))
36 continue;
37 if (pathlen > len && path[pathlen - len - 1] != '/')
38 continue;
39 *s = 0;
40 return 1;
41 }
42 return 0;
43}
44
45/*
46 * Yeah, yeah, fixme. Need to pass in the heads etc.
47 */
48int git_connect(int fd[2], char *url, const char *prog)
49{
50 char command[1024];
51 const char *host, *path;
52 char *colon;
53 int pipefd[2][2];
54 pid_t pid;
55
56 host = NULL;
57 path = url;
58 colon = strchr(url, ':');
59 if (colon) {
60 *colon = 0;
61 host = url;
62 path = colon+1;
63 }
64 if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
65 die("unable to create pipe pair for communication");
66 pid = fork();
67 if (!pid) {
68 snprintf(command, sizeof(command), "%s %s", prog,
69 sq_quote(path));
70 dup2(pipefd[1][0], 0);
71 dup2(pipefd[0][1], 1);
72 close(pipefd[0][0]);
73 close(pipefd[0][1]);
74 close(pipefd[1][0]);
75 close(pipefd[1][1]);
76 if (host)
77 execlp("ssh", "ssh", host, command, NULL);
78 else
79 execlp("sh", "sh", "-c", command, NULL);
80 die("exec failed");
81 }
82 fd[0] = pipefd[0][0];
83 fd[1] = pipefd[1][1];
84 close(pipefd[0][1]);
85 close(pipefd[1][0]);
86 return pid;
87}
88
89int finish_connect(pid_t pid)
90{
91 int ret;
92
93 for (;;) {
94 ret = waitpid(pid, NULL, 0);
95 if (!ret)
96 break;
97 if (errno != EINTR)
98 break;
99 }
100 return ret;
101}