diff options
Diffstat (limited to 'third_party/git/builtin/remote-ext.c')
-rw-r--r-- | third_party/git/builtin/remote-ext.c | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/third_party/git/builtin/remote-ext.c b/third_party/git/builtin/remote-ext.c deleted file mode 100644 index fd3538d4f0e6..000000000000 --- a/third_party/git/builtin/remote-ext.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "builtin.h" -#include "transport.h" -#include "run-command.h" -#include "pkt-line.h" - -static const char usage_msg[] = - "git remote-ext <remote> <url>"; - -/* - * URL syntax: - * 'command [arg1 [arg2 [...]]]' Invoke command with given arguments. - * Special characters: - * '% ': Literal space in argument. - * '%%': Literal percent sign. - * '%S': Name of service (git-upload-pack/git-upload-archive/ - * git-receive-pack. - * '%s': Same as \s, but with possible git- prefix stripped. - * '%G': Only allowed as first 'character' of argument. Do not pass this - * Argument to command, instead send this as name of repository - * in in-line git://-style request (also activates sending this - * style of request). - * '%V': Only allowed as first 'character' of argument. Used in - * conjunction with '%G': Do not pass this argument to command, - * instead send this as vhost in git://-style request (note: does - * not activate sending git:// style request). - */ - -static char *git_req; -static char *git_req_vhost; - -static char *strip_escapes(const char *str, const char *service, - const char **next) -{ - size_t rpos = 0; - int escape = 0; - char special = 0; - const char *service_noprefix = service; - struct strbuf ret = STRBUF_INIT; - - skip_prefix(service_noprefix, "git-", &service_noprefix); - - /* Pass the service to command. */ - setenv("GIT_EXT_SERVICE", service, 1); - setenv("GIT_EXT_SERVICE_NOPREFIX", service_noprefix, 1); - - /* Scan the length of argument. */ - while (str[rpos] && (escape || str[rpos] != ' ')) { - if (escape) { - switch (str[rpos]) { - case ' ': - case '%': - case 's': - case 'S': - break; - case 'G': - case 'V': - special = str[rpos]; - if (rpos == 1) - break; - /* fallthrough */ - default: - die("Bad remote-ext placeholder '%%%c'.", - str[rpos]); - } - escape = 0; - } else - escape = (str[rpos] == '%'); - rpos++; - } - if (escape && !str[rpos]) - die("remote-ext command has incomplete placeholder"); - *next = str + rpos; - if (**next == ' ') - ++*next; /* Skip over space */ - - /* - * Do the actual placeholder substitution. The string will be short - * enough not to overflow integers. - */ - rpos = special ? 2 : 0; /* Skip first 2 bytes in specials. */ - escape = 0; - while (str[rpos] && (escape || str[rpos] != ' ')) { - if (escape) { - switch (str[rpos]) { - case ' ': - case '%': - strbuf_addch(&ret, str[rpos]); - break; - case 's': - strbuf_addstr(&ret, service_noprefix); - break; - case 'S': - strbuf_addstr(&ret, service); - break; - } - escape = 0; - } else - switch (str[rpos]) { - case '%': - escape = 1; - break; - default: - strbuf_addch(&ret, str[rpos]); - break; - } - rpos++; - } - switch (special) { - case 'G': - git_req = strbuf_detach(&ret, NULL); - return NULL; - case 'V': - git_req_vhost = strbuf_detach(&ret, NULL); - return NULL; - default: - return strbuf_detach(&ret, NULL); - } -} - -static void parse_argv(struct strvec *out, const char *arg, const char *service) -{ - while (*arg) { - char *expanded = strip_escapes(arg, service, &arg); - if (expanded) - strvec_push(out, expanded); - free(expanded); - } -} - -static void send_git_request(int stdin_fd, const char *serv, const char *repo, - const char *vhost) -{ - if (!vhost) - packet_write_fmt(stdin_fd, "%s %s%c", serv, repo, 0); - else - packet_write_fmt(stdin_fd, "%s %s%chost=%s%c", serv, repo, 0, - vhost, 0); -} - -static int run_child(const char *arg, const char *service) -{ - int r; - struct child_process child = CHILD_PROCESS_INIT; - - child.in = -1; - child.out = -1; - child.err = 0; - parse_argv(&child.args, arg, service); - - if (start_command(&child) < 0) - die("Can't run specified command"); - - if (git_req) - send_git_request(child.in, service, git_req, git_req_vhost); - - r = bidirectional_transfer_loop(child.out, child.in); - if (!r) - r = finish_command(&child); - else - finish_command(&child); - return r; -} - -#define MAXCOMMAND 4096 - -static int command_loop(const char *child) -{ - char buffer[MAXCOMMAND]; - - while (1) { - size_t i; - if (!fgets(buffer, MAXCOMMAND - 1, stdin)) { - if (ferror(stdin)) - die("Command input error"); - exit(0); - } - /* Strip end of line characters. */ - i = strlen(buffer); - while (i > 0 && isspace(buffer[i - 1])) - buffer[--i] = 0; - - if (!strcmp(buffer, "capabilities")) { - printf("*connect\n\n"); - fflush(stdout); - } else if (!strncmp(buffer, "connect ", 8)) { - printf("\n"); - fflush(stdout); - return run_child(child, buffer + 8); - } else { - fprintf(stderr, "Bad command"); - return 1; - } - } -} - -int cmd_remote_ext(int argc, const char **argv, const char *prefix) -{ - if (argc != 3) - usage(usage_msg); - - return command_loop(argv[2]); -} |