connect.con commit git-rev-list: make sure the output is sorted by recency (7a662e8)
   1#include "cache.h"
   2#include <sys/wait.h>
   3
   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
  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}