connect.con commit Clean up commit insertion in git-rev-list (7e21c29)
   1#include "cache.h"
   2#include "pkt-line.h"
   3#include <sys/wait.h>
   4
   5int get_ack(int fd, unsigned char *result_sha1)
   6{
   7        static char line[1000];
   8        int len = packet_read_line(fd, line, sizeof(line));
   9
  10        if (!len)
  11                die("git-fetch-pack: expected ACK/NAK, got EOF");
  12        if (line[len-1] == '\n')
  13                line[--len] = 0;
  14        if (!strcmp(line, "NAK"))
  15                return 0;
  16        if (!strncmp(line, "ACK ", 3)) {
  17                if (!get_sha1_hex(line+4, result_sha1))
  18                        return 1;
  19        }
  20        die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
  21}
  22
  23int path_match(const char *path, int nr, char **match)
  24{
  25        int i;
  26        int pathlen = strlen(path);
  27
  28        for (i = 0; i < nr; i++) {
  29                char *s = match[i];
  30                int len = strlen(s);
  31
  32                if (!len || len > pathlen)
  33                        continue;
  34                if (memcmp(path + pathlen - len, s, len))
  35                        continue;
  36                if (pathlen > len && path[pathlen - len - 1] != '/')
  37                        continue;
  38                *s = 0;
  39                return 1;
  40        }
  41        return 0;
  42}
  43
  44/*
  45 * First, make it shell-safe.  We do this by just disallowing any
  46 * special characters. Somebody who cares can do escaping and let
  47 * through the rest. But since we're doing to feed this to ssh as
  48 * a command line, we're going to be pretty damn anal for now.
  49 */
  50static char *shell_safe(char *url)
  51{
  52        char *n = url;
  53        unsigned char c;
  54        static const char flags[256] = {
  55                ['0'...'9'] = 1,
  56                ['a'...'z'] = 1,
  57                ['A'...'Z'] = 1,
  58                ['.'] = 1, ['/'] = 1,
  59                ['-'] = 1, ['+'] = 1,
  60                [':'] = 1
  61        };
  62
  63        while ((c = *n++) != 0) {
  64                if (flags[c] != 1)
  65                        die("I don't like '%c'. Sue me.", c);
  66        }
  67        return url;
  68}
  69
  70/*
  71 * Yeah, yeah, fixme. Need to pass in the heads etc.
  72 */
  73int git_connect(int fd[2], char *url, const char *prog)
  74{
  75        char command[1024];
  76        const char *host, *path;
  77        char *colon;
  78        int pipefd[2][2];
  79        pid_t pid;
  80
  81        url = shell_safe(url);
  82        host = NULL;
  83        path = url;
  84        colon = strchr(url, ':');
  85        if (colon) {
  86                *colon = 0;
  87                host = url;
  88                path = colon+1;
  89        }
  90        snprintf(command, sizeof(command), "%s %s", prog, path);
  91        if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
  92                die("unable to create pipe pair for communication");
  93        pid = fork();
  94        if (!pid) {
  95                dup2(pipefd[1][0], 0);
  96                dup2(pipefd[0][1], 1);
  97                close(pipefd[0][0]);
  98                close(pipefd[0][1]);
  99                close(pipefd[1][0]);
 100                close(pipefd[1][1]);
 101                if (host)
 102                        execlp("ssh", "ssh", host, command, NULL);
 103                else
 104                        execlp("sh", "sh", "-c", command, NULL);
 105                die("exec failed");
 106        }               
 107        fd[0] = pipefd[0][0];
 108        fd[1] = pipefd[1][1];
 109        close(pipefd[0][1]);
 110        close(pipefd[1][0]);
 111        return pid;
 112}
 113
 114int finish_connect(pid_t pid)
 115{
 116        int ret;
 117
 118        for (;;) {
 119                ret = waitpid(pid, NULL, 0);
 120                if (!ret)
 121                        break;
 122                if (errno != EINTR)
 123                        break;
 124        }
 125        return ret;
 126}