]> git.ipfire.org Git - thirdparty/git.git/blame - connect.c
Remove multi-head support from fetch-pack
[thirdparty/git.git] / connect.c
CommitLineData
f7192598
LT
1#include "cache.h"
2#include <sys/wait.h>
3
013e7c7f
LT
4int path_match(const char *path, int nr, char **match)
5{
6 int i;
7 int pathlen = strlen(path);
8
9 for (i = 0; i < nr; i++) {
10 char *s = match[i];
11 int len = strlen(s);
12
13 if (!len || len > pathlen)
14 continue;
15 if (memcmp(path + pathlen - len, s, len))
16 continue;
17 if (pathlen > len && path[pathlen - len - 1] != '/')
18 continue;
19 *s = 0;
20 return 1;
21 }
22 return 0;
23}
24
f7192598
LT
25/*
26 * First, make it shell-safe. We do this by just disallowing any
27 * special characters. Somebody who cares can do escaping and let
28 * through the rest. But since we're doing to feed this to ssh as
29 * a command line, we're going to be pretty damn anal for now.
30 */
31static char *shell_safe(char *url)
32{
33 char *n = url;
34 unsigned char c;
35 static const char flags[256] = {
36 ['0'...'9'] = 1,
37 ['a'...'z'] = 1,
38 ['A'...'Z'] = 1,
39 ['.'] = 1, ['/'] = 1,
40 ['-'] = 1, ['+'] = 1,
41 [':'] = 1
42 };
43
44 while ((c = *n++) != 0) {
45 if (flags[c] != 1)
46 die("I don't like '%c'. Sue me.", c);
47 }
48 return url;
49}
50
51/*
52 * Yeah, yeah, fixme. Need to pass in the heads etc.
53 */
54int git_connect(int fd[2], char *url, const char *prog)
55{
56 char command[1024];
57 const char *host, *path;
58 char *colon;
59 int pipefd[2][2];
60 pid_t pid;
61
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;
70 }
71 snprintf(command, sizeof(command), "%s %s", prog, path);
72 if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
73 die("unable to create pipe pair for communication");
74 pid = fork();
75 if (!pid) {
76 dup2(pipefd[1][0], 0);
77 dup2(pipefd[0][1], 1);
78 close(pipefd[0][0]);
79 close(pipefd[0][1]);
80 close(pipefd[1][0]);
81 close(pipefd[1][1]);
82 if (host)
83 execlp("ssh", "ssh", host, command, NULL);
84 else
85 execlp("sh", "sh", "-c", command, NULL);
86 die("exec failed");
87 }
88 fd[0] = pipefd[0][0];
89 fd[1] = pipefd[1][1];
90 close(pipefd[0][1]);
91 close(pipefd[1][0]);
92 return pid;
93}
94
95int finish_connect(pid_t pid)
96{
97 int ret;
98
99 for (;;) {
100 ret = waitpid(pid, NULL, 0);
101 if (!ret)
102 break;
103 if (errno != EINTR)
104 break;
105 }
106 return ret;
107}