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