[PATCH] Fix broken t6001 test case
[git/dscho.git] / send-pack.c
blob99cb84b2c4820878839b18557c2c51e07390f099
1 #include "cache.h"
2 #include "pkt-line.h"
4 static const char send_pack_usage[] = "git-send-pack [--exec=other] destination [heads]*";
6 static const char *exec = "git-receive-pack";
8 static int send_pack(int in, int out)
10 for (;;) {
11 static char buffer[1000];
12 int len;
14 len = packet_read_line(in, buffer, sizeof(buffer));
15 if (len > 0) {
16 write(2, buffer, len);
17 continue;
19 break;
21 packet_flush(out);
22 close(out);
23 return 0;
27 * First, make it shell-safe. We do this by just disallowing any
28 * special characters. Somebody who cares can do escaping and let
29 * through the rest. But since we're doing to feed this to ssh as
30 * a command line, we're going to be pretty damn anal for now.
32 static char *shell_safe(char *url)
34 char *n = url;
35 unsigned char c;
36 static const char flags[256] = {
37 ['0'...'9'] = 1,
38 ['a'...'z'] = 1,
39 ['A'...'Z'] = 1,
40 ['.'] = 1, ['/'] = 1,
41 ['-'] = 1, ['+'] = 1,
42 [':'] = 1
45 while ((c = *n++) != 0) {
46 if (flags[c] != 1)
47 die("I don't like '%c'. Sue me.", c);
49 return url;
53 * Yeah, yeah, fixme. Need to pass in the heads etc.
55 static int setup_connection(int fd[2], char *url, char **heads)
57 char command[1024];
58 const char *host, *path;
59 char *colon;
60 int pipefd[2][2];
62 url = shell_safe(url);
63 host = NULL;
64 path = url;
65 colon = strchr(url, ':');
66 if (colon) {
67 *colon = 0;
68 host = url;
69 path = colon+1;
71 snprintf(command, sizeof(command), "%s %s", exec, path);
72 if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
73 die("unable to create pipe pair for communication");
74 if (!fork()) {
75 dup2(pipefd[1][0], 0);
76 dup2(pipefd[0][1], 1);
77 close(pipefd[0][0]);
78 close(pipefd[0][1]);
79 close(pipefd[1][0]);
80 close(pipefd[1][1]);
81 if (host)
82 execlp("ssh", "ssh", host, command, NULL);
83 else
84 execlp("sh", "sh", "-c", command, NULL);
85 die("exec failed");
87 fd[0] = pipefd[0][0];
88 fd[1] = pipefd[1][1];
89 close(pipefd[0][1]);
90 close(pipefd[1][0]);
91 return 0;
94 int main(int argc, char **argv)
96 int i, nr_heads = 0;
97 char *dest = NULL;
98 char **heads = NULL;
99 int fd[2];
101 argv++;
102 for (i = 1; i < argc; i++) {
103 char *arg = *argv++;
105 if (*arg == '-') {
106 if (!strncmp(arg, "--exec=", 7)) {
107 exec = arg + 7;
108 continue;
110 usage(send_pack_usage);
112 dest = arg;
113 heads = argv;
114 nr_heads = argc - i -1;
115 break;
117 if (!dest)
118 usage(send_pack_usage);
119 if (setup_connection(fd, dest, heads))
120 return 1;
121 return send_pack(fd[0], fd[1]);