diff options
author | Daniel Barkalow <barkalow@iabervon.org> | 2005-04-23 18:47:23 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-23 18:47:23 -0700 |
commit | 6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c (patch) | |
tree | 3b4a5bb703599458ce8fe504f37f8e28b77bd6ca /rsh.c | |
parent | b6b15db3f464b18180eee79927cb324fd63e15ff (diff) | |
download | git-6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c.tar.gz git-6eb7ed5403b7d57d5ed7e30d0cd0b312888ee95c.tar.xz |
[PATCH] Various transport programs
This patch adds three similar and related programs. http-pull downloads
objects from an HTTP server; rpull downloads objects by using ssh and
rpush on the other side; and rpush uploads objects by using ssh and rpull
on the other side.
The algorithm should be sufficient to make the network throughput required
depend only on how much content is new, not at all on how much content the
repository contains.
The combination should enable people to have remote repositories by way of
ssh login for authenticated users and HTTP for anonymous access.
Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'rsh.c')
-rw-r--r-- | rsh.c | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -0,0 +1,63 @@ +#include "rsh.h" + +#include <string.h> +#include <sys/socket.h> + +#include "cache.h" + +#define COMMAND_SIZE 4096 + +int setup_connection(int *fd_in, int *fd_out, char *remote_prog, + char *url, int rmt_argc, char **rmt_argv) +{ + char *host; + char *path; + int sv[2]; + char command[COMMAND_SIZE]; + char *posn; + int i; + + if (!strcmp(url, "-")) { + *fd_in = 0; + *fd_out = 1; + return 0; + } + + host = strstr(url, "//"); + if (!host) { + return error("Bad URL: %s", url); + } + host += 2; + path = strchr(host, '/'); + if (!path) { + return error("Bad URL: %s", url); + } + *(path++) = '\0'; + /* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */ + snprintf(command, COMMAND_SIZE, + "cd /%s; SHA1_FILE_DIRECTORY=objects %s", + path, remote_prog); + posn = command + strlen(command); + for (i = 0; i < rmt_argc; i++) { + *(posn++) = ' '; + strncpy(posn, rmt_argv[i], COMMAND_SIZE - (posn - command)); + posn += strlen(rmt_argv[i]); + if (posn - command + 4 >= COMMAND_SIZE) { + return error("Command line too long"); + } + } + strcpy(posn, " -"); + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { + return error("Couldn't create socket"); + } + if (!fork()) { + close(sv[1]); + dup2(sv[0], 0); + dup2(sv[0], 1); + execlp("ssh", "ssh", host, command, NULL); + } + close(sv[0]); + *fd_in = sv[1]; + *fd_out = sv[1]; + return 0; +} |