send-pack.con commit [PATCH] Remove unnecessary sort from t6001 testcase (9d89d19)
   1#include "cache.h"
   2#include "pkt-line.h"
   3
   4static const char send_pack_usage[] = "git-send-pack [--exec=other] destination [heads]*";
   5
   6static const char *exec = "git-receive-pack";
   7
   8static int send_pack(int in, int out)
   9{
  10        for (;;) {
  11                static char buffer[1000];
  12                int len;
  13
  14                len = packet_read_line(in, buffer, sizeof(buffer));
  15                if (len > 0) {
  16                        write(2, buffer, len);
  17                        continue;
  18                }
  19                break;
  20        }
  21        packet_flush(out);
  22        close(out);
  23        return 0;
  24}
  25
  26/*
  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.
  31 */
  32static char *shell_safe(char *url)
  33{
  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
  43        };
  44
  45        while ((c = *n++) != 0) {
  46                if (flags[c] != 1)
  47                        die("I don't like '%c'. Sue me.", c);
  48        }
  49        return url;
  50}
  51
  52/*
  53 * Yeah, yeah, fixme. Need to pass in the heads etc.
  54 */
  55static int setup_connection(int fd[2], char *url, char **heads)
  56{
  57        char command[1024];
  58        const char *host, *path;
  59        char *colon;
  60        int pipefd[2][2];
  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", 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");
  86        }               
  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;
  92}
  93
  94int main(int argc, char **argv)
  95{
  96        int i, nr_heads = 0;
  97        char *dest = NULL;
  98        char **heads = NULL;
  99        int fd[2];
 100
 101        argv++;
 102        for (i = 1; i < argc; i++) {
 103                char *arg = *argv++;
 104
 105                if (*arg == '-') {
 106                        if (!strncmp(arg, "--exec=", 7)) {
 107                                exec = arg + 7;
 108                                continue;
 109                        }
 110                        usage(send_pack_usage);
 111                }
 112                dest = arg;
 113                heads = argv;
 114                nr_heads = argc - i -1;
 115                break;
 116        }
 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]);
 122}