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