This remote helper reflects raw smart remote transport stream back to the calling program. This is useful for example if some UI wants to handle ssh itself and not use hacks via GIT_SSH. Signed-off-by: Ilari Liusvaara <ilari.liusvaara@xxxxxxxxxxx> --- Documentation/git-remote-fd.txt | 57 +++++++++++++++++++++++++ Makefile | 1 + builtin.h | 1 + builtin/remote-fd.c | 88 +++++++++++++++++++++++++++++++++++++++ git.c | 1 + 5 files changed, 148 insertions(+), 0 deletions(-) create mode 100644 Documentation/git-remote-fd.txt create mode 100644 builtin/remote-fd.c diff --git a/Documentation/git-remote-fd.txt b/Documentation/git-remote-fd.txt new file mode 100644 index 0000000..12e588a --- /dev/null +++ b/Documentation/git-remote-fd.txt @@ -0,0 +1,57 @@ +git-remote-fd(1) +================= + +NAME +---- +git-remote-fd - Reflect smart transport back to caller. + + +SYNOPSIS +-------- +"fd::<fd>[/<anything>]" or "fd::<infd>,<outfd>[/<anything>]" (as URL) + +DESCRIPTION +----------- +This command uses specified file descriptors to connect to remote git server. + +If just <fd> is specified, <fd> is assumed to be socket that is +transparently connected to git server program. + +If <infd> and <outfd> are specified, <infd> is assumed to be pipe from +git server program and <outfd> is assumed to be pipe to git server program. + +It is assumed that any handshaking procedures have already been completed +(such as sending service request for git://). + +<anything> can be any string. It is ignored. It is meant for provoding +information to user in form of "URL". + +ENVIRONMENT VARIABLES: +---------------------- + +$GIT_TRANSLOOP_DEBUG (passed to git):: + If set, prints debugging information about various reads/writes. + + +EXAMPLES: +--------- +"fd::17":: + Connect using socket in file descriptor #17. + +"fd::17/foo":: + Same as above. + +"fd::7,8":: + Connect using pipes in file descriptors #7 and #8. The incoming + pipe is at fd #7 and the outgoing pipe at fd #8. + +"fd::7,8/bar":: + Same as above. + +Documentation +-------------- +Documentation by Ilari Liusvaara. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Makefile b/Makefile index 8a56b9a..7da54d7 100644 --- a/Makefile +++ b/Makefile @@ -728,6 +728,7 @@ BUILTIN_OBJS += builtin/read-tree.o BUILTIN_OBJS += builtin/receive-pack.o BUILTIN_OBJS += builtin/reflog.o BUILTIN_OBJS += builtin/remote.o +BUILTIN_OBJS += builtin/remote-fd.o BUILTIN_OBJS += builtin/replace.o BUILTIN_OBJS += builtin/rerere.o BUILTIN_OBJS += builtin/reset.o diff --git a/builtin.h b/builtin.h index f2a25a0..748cc13 100644 --- a/builtin.h +++ b/builtin.h @@ -140,5 +140,6 @@ extern int cmd_verify_pack(int argc, const char **argv, const char *prefix); extern int cmd_show_ref(int argc, const char **argv, const char *prefix); extern int cmd_pack_refs(int argc, const char **argv, const char *prefix); extern int cmd_replace(int argc, const char **argv, const char *prefix); +extern int cmd_remote_fd(int argc, const char **argv, const char *prefix); #endif diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c new file mode 100644 index 0000000..08ff522 --- /dev/null +++ b/builtin/remote-fd.c @@ -0,0 +1,88 @@ +#include "git-compat-util.h" +#include "transport.h" +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> + + +/* + * URL syntax: + * 'fd::<inoutfd>[/<anything>]' Read/write socket pair + * <inoutfd>. + * 'fd::<infd>,<outfd>[/<anything>]' Read pipe <infd> and write + * pipe <outfd>. + * [foo] indicates 'foo' is optional. <anything> is any string. + * + * The data output to <outfd>/<inoutfd> should be passed unmolested to + * git-receive-pack/git-upload-pack/git-upload-archive and output of + * git-receive-pack/git-upload-pack/git-upload-archive should be passed + * unmolested to <infd>/<inoutfd>. + * + */ + +int input_fd = -1; +int output_fd = -1; + +#define MAXCOMMAND 4096 + +static int command_loop() +{ + char buffer[MAXCOMMAND]; + + while (1) { + if (!fgets(buffer, MAXCOMMAND - 1, stdin)) + exit(0); + //Strip end of line characters. + while (isspace((unsigned char)buffer[strlen(buffer) - 1])) + buffer[strlen(buffer) - 1] = 0; + + if (!strcmp(buffer, "capabilities")) { + printf("*connect\n\n"); + fflush(stdout); + } else if (!strncmp(buffer, "connect ", 8)) { + printf("\n"); + fflush(stdout); + return bidirectional_transfer_loop(input_fd, + output_fd); + } else { + fprintf(stderr, "Bad command"); + return 1; + } + } +} + +int cmd_remote_fd(int argc, const char **argv, const char *prefix) +{ + char* end; + unsigned long r; + + if (argc < 3) { + fprintf(stderr, "Error: URL missing"); + exit(1); + } + + r = strtoul(argv[2], &end, 10); + input_fd = (int)r; + + if ((*end != ',' && *end !='/' && *end) || end == argv[2]) { + fprintf(stderr, "Error: Bad URL syntax"); + exit(1); + } + + if (*end == '/' || !*end) { + output_fd = input_fd; + } else { + char* end2; + r = strtoul(end + 1, &end2, 10); + output_fd = (int)r; + + if ((*end2 !='/' && *end2) || end2 == end + 1) { + fprintf(stderr, "Error: Bad URL syntax"); + exit(1); + } + } + + return command_loop(); +} diff --git a/git.c b/git.c index 50a1401..250ecc5 100644 --- a/git.c +++ b/git.c @@ -374,6 +374,7 @@ static void handle_internal_command(int argc, const char **argv) { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, + { "remote-fd", cmd_remote_fd, 0 }, { "replace", cmd_replace, RUN_SETUP }, { "repo-config", cmd_config, RUN_SETUP_GENTLY }, { "rerere", cmd_rerere, RUN_SETUP }, -- 1.7.2.3.401.g919b6e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html