5 #include <sys/socket.h>
6 #include <netinet/in.h>
11 * Read all the refs from the other end
13 struct ref
**get_remote_heads(int in
, struct ref
**list
, int nr_match
, char **match
)
18 unsigned char old_sha1
[20];
19 static char buffer
[1000];
23 len
= packet_read_line(in
, buffer
, sizeof(buffer
));
26 if (buffer
[len
-1] == '\n')
29 if (len
< 42 || get_sha1_hex(buffer
, old_sha1
) || buffer
[40] != ' ')
30 die("protocol error: expected sha/ref, got '%s'", buffer
);
32 if (nr_match
&& !path_match(name
, nr_match
, match
))
34 ref
= xmalloc(sizeof(*ref
) + len
- 40);
35 memcpy(ref
->old_sha1
, old_sha1
, 20);
36 memset(ref
->new_sha1
, 0, 20);
37 memcpy(ref
->name
, buffer
+ 41, len
- 40);
45 int get_ack(int fd
, unsigned char *result_sha1
)
47 static char line
[1000];
48 int len
= packet_read_line(fd
, line
, sizeof(line
));
51 die("git-fetch-pack: expected ACK/NAK, got EOF");
52 if (line
[len
-1] == '\n')
54 if (!strcmp(line
, "NAK"))
56 if (!strncmp(line
, "ACK ", 3)) {
57 if (!get_sha1_hex(line
+4, result_sha1
))
60 die("git-fetch_pack: expected ACK/NAK, got '%s'", line
);
63 int path_match(const char *path
, int nr
, char **match
)
66 int pathlen
= strlen(path
);
68 for (i
= 0; i
< nr
; i
++) {
72 if (!len
|| len
> pathlen
)
74 if (memcmp(path
+ pathlen
- len
, s
, len
))
76 if (pathlen
> len
&& path
[pathlen
- len
- 1] != '/')
90 static enum protocol
get_protocol(const char *name
)
92 if (!strcmp(name
, "ssh"))
94 if (!strcmp(name
, "git"))
96 die("I don't handle protocol '%s'", name
);
100 #define STR(s) STR_(s)
102 static int git_tcp_connect(int fd
[2], const char *prog
, char *host
, char *path
)
106 char *port
= STR(DEFAULT_GIT_PORT
);
107 struct addrinfo hints
, *ai0
, *ai
;
110 if (host
[0] == '[') {
111 end
= strchr(host
+ 1, ']');
120 colon
= strchr(end
, ':');
127 memset(&hints
, 0, sizeof(hints
));
128 hints
.ai_socktype
= SOCK_STREAM
;
129 hints
.ai_protocol
= IPPROTO_TCP
;
131 gai
= getaddrinfo(host
, port
, &hints
, &ai
);
133 die("Unable to look up %s (%s)", host
, gai_strerror(gai
));
135 for (ai0
= ai
; ai
; ai
= ai
->ai_next
) {
136 sockfd
= socket(ai
->ai_family
, ai
->ai_socktype
, ai
->ai_protocol
);
139 if (connect(sockfd
, ai
->ai_addr
, ai
->ai_addrlen
) < 0) {
150 die("unable to connect a socket (%s)", strerror(errno
));
154 packet_write(sockfd
, "%s %s\n", prog
, path
);
159 * Yeah, yeah, fixme. Need to pass in the heads etc.
161 int git_connect(int fd
[2], char *url
, const char *prog
)
168 enum protocol protocol
;
172 colon
= strchr(url
, ':');
173 protocol
= PROTO_LOCAL
;
178 protocol
= PROTO_SSH
;
179 if (!memcmp(path
, "//", 2)) {
180 char *slash
= strchr(path
+ 2, '/');
182 int nr
= slash
- path
- 2;
183 memmove(path
, path
+2, nr
);
185 protocol
= get_protocol(url
);
192 if (protocol
== PROTO_GIT
)
193 return git_tcp_connect(fd
, prog
, host
, path
);
195 if (pipe(pipefd
[0]) < 0 || pipe(pipefd
[1]) < 0)
196 die("unable to create pipe pair for communication");
199 snprintf(command
, sizeof(command
), "%s %s", prog
,
201 dup2(pipefd
[1][0], 0);
202 dup2(pipefd
[0][1], 1);
207 if (protocol
== PROTO_SSH
)
208 execlp("ssh", "ssh", host
, command
, NULL
);
210 execlp("sh", "sh", "-c", command
, NULL
);
213 fd
[0] = pipefd
[0][0];
214 fd
[1] = pipefd
[1][1];
220 int finish_connect(pid_t pid
)
225 ret
= waitpid(pid
, NULL
, 0);