builtin / remote-fd.con commit Merge branch 'mm/branch-doc-updates' into maint (315b3ba)
   1#include "builtin.h"
   2#include "transport.h"
   3
   4/*
   5 * URL syntax:
   6 *      'fd::<inoutfd>[/<anything>]'            Read/write socket pair
   7 *                                              <inoutfd>.
   8 *      'fd::<infd>,<outfd>[/<anything>]'       Read pipe <infd> and write
   9 *                                              pipe <outfd>.
  10 *      [foo] indicates 'foo' is optional. <anything> is any string.
  11 *
  12 * The data output to <outfd>/<inoutfd> should be passed unmolested to
  13 * git-receive-pack/git-upload-pack/git-upload-archive and output of
  14 * git-receive-pack/git-upload-pack/git-upload-archive should be passed
  15 * unmolested to <infd>/<inoutfd>.
  16 *
  17 */
  18
  19#define MAXCOMMAND 4096
  20
  21static void command_loop(int input_fd, int output_fd)
  22{
  23        char buffer[MAXCOMMAND];
  24
  25        while (1) {
  26                size_t i;
  27                if (!fgets(buffer, MAXCOMMAND - 1, stdin)) {
  28                        if (ferror(stdin))
  29                                die("Input error");
  30                        return;
  31                }
  32                /* Strip end of line characters. */
  33                i = strlen(buffer);
  34                while (i > 0 && isspace(buffer[i - 1]))
  35                        buffer[--i] = 0;
  36
  37                if (!strcmp(buffer, "capabilities")) {
  38                        printf("*connect\n\n");
  39                        fflush(stdout);
  40                } else if (!strncmp(buffer, "connect ", 8)) {
  41                        printf("\n");
  42                        fflush(stdout);
  43                        if (bidirectional_transfer_loop(input_fd,
  44                                output_fd))
  45                                die("Copying data between file descriptors failed");
  46                        return;
  47                } else {
  48                        die("Bad command: %s", buffer);
  49                }
  50        }
  51}
  52
  53int cmd_remote_fd(int argc, const char **argv, const char *prefix)
  54{
  55        int input_fd = -1;
  56        int output_fd = -1;
  57        char *end;
  58
  59        if (argc != 3)
  60                die("Expected two arguments");
  61
  62        input_fd = (int)strtoul(argv[2], &end, 10);
  63
  64        if ((end == argv[2]) || (*end != ',' && *end != '/' && *end))
  65                die("Bad URL syntax");
  66
  67        if (*end == '/' || !*end) {
  68                output_fd = input_fd;
  69        } else {
  70                char *end2;
  71                output_fd = (int)strtoul(end + 1, &end2, 10);
  72
  73                if ((end2 == end + 1) || (*end2 != '/' && *end2))
  74                        die("Bad URL syntax");
  75        }
  76
  77        command_loop(input_fd, output_fd);
  78        return 0;
  79}