git-remote-fd
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@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ilari Liusvaara committed
Oct 12, 2010 at 19:39 UTC
3a9ed4bdee5032ecb9328aea51a752d69a2d966e
6 files changed
+142
.gitignore
+1
@@ -112,6 +112,7 @@
112
/git-remote-https
113
/git-remote-ftp
114
/git-remote-ftps
115
+/git-remote-fd
116
/git-remote-testgit
117
/git-repack
118
/git-replace
Documentation/git-remote-fd.txt
new
+59
@@ -0,0 +1,59 @@
1
+git-remote-fd(1)
2
+=================
3
+
4
+NAME
5
+----
6
+git-remote-fd - Reflect smart transport stream back to caller
7
+
8
+SYNOPSIS
9
+--------
10
+"fd::<infd>[,<outfd>][/<anything>]" (as URL)
11
+
12
+DESCRIPTION
13
+-----------
14
+This helper uses specified file descriptors to connect to remote git server.
15
+This is not meant for end users but for programs and scripts calling git
16
+fetch, push or archive.
17
+
18
+If only <infd> is given, it is assumed to be bidirectional socket connected
19
+to remote git server (git-upload-pack, git-receive-pack or
20
+git-upload-achive). If both <infd> and <outfd> are given, they are assumed
21
+to be pipes connected to remote git server (<infd> being the inbound pipe
22
+and <outfd> being the outbound pipe.
23
+
24
+It is assumed that any handshaking procedures have already been completed
25
+(such as sending service request for git://) before this helper is started.
26
+
27
+<anything> can be any string. It is ignored. It is meant for provoding
28
+information to user in the URL in case that URL is displayed in some
29
+context.
30
+
31
+ENVIRONMENT VARIABLES:
32
+----------------------
33
+GIT_TRANSLOOP_DEBUG::
34
+ If set, prints debugging information about various reads/writes.
35
+
36
+EXAMPLES:
37
+---------
38
+git fetch fd::17 master::
39
+ Fetch master, using file descriptor #17 to communicate with
40
+ git-upload-pack.
41
+
42
+git fetch fd::17/foo master::
43
+ Same as above.
44
+
45
+git push fd::7,8 master (as URL)::
46
+ Push master, using file descriptor #7 to read data from
47
+ git-receive-pack and file descriptor #8 to write data to
48
+ same service.
49
+
50
+git push fd::7,8/bar master::
51
+ Same as above.
52
+
53
+Documentation
54
+--------------
55
+Documentation by Ilari Liusvaara and the git list <git@vger.kernel.org>
56
+
57
+GIT
58
+---
59
+Part of the linkgit:git[1] suite
Makefile
+1
@@ -723,6 +723,7 @@ BUILTIN_OBJS += builtin/read-tree.o
723
BUILTIN_OBJS += builtin/receive-pack.o
724
BUILTIN_OBJS += builtin/reflog.o
725
BUILTIN_OBJS += builtin/remote.o
726
+BUILTIN_OBJS += builtin/remote-fd.o
727
BUILTIN_OBJS += builtin/replace.o
728
BUILTIN_OBJS += builtin/rerere.o
729
BUILTIN_OBJS += builtin/reset.o
builtin.h
+1
@@ -107,6 +107,7 @@ extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
107
extern int cmd_receive_pack(int argc, const char **argv, const char *prefix);
108
extern int cmd_reflog(int argc, const char **argv, const char *prefix);
109
extern int cmd_remote(int argc, const char **argv, const char *prefix);
110
+extern int cmd_remote_fd(int argc, const char **argv, const char *prefix);
111
extern int cmd_config(int argc, const char **argv, const char *prefix);
112
extern int cmd_rerere(int argc, const char **argv, const char *prefix);
113
extern int cmd_reset(int argc, const char **argv, const char *prefix);
builtin/remote-fd.c
new
+79
@@ -0,0 +1,79 @@
1
+#include "git-compat-util.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
+
21
+static 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 (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
+
53
+int 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("URL missing");
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
+}
git.c
+1
@@ -374,6 +374,7 @@ static void handle_internal_command(int argc, const char **argv)
374
{ "receive-pack", cmd_receive_pack },
375
{ "reflog", cmd_reflog, RUN_SETUP },
376
{ "remote", cmd_remote, RUN_SETUP },
377
+ { "remote-fd", cmd_remote_fd },
378
{ "replace", cmd_replace, RUN_SETUP },
379
{ "repo-config", cmd_config, RUN_SETUP_GENTLY },
380
{ "rerere", cmd_rerere, RUN_SETUP },