The upload-file command allows a remote to request specific files by sha1. Signed-off-by: Mark Thomas <markbt@xxxxxxxxxx> --- .gitignore | 1 + Makefile | 2 ++ daemon.c | 6 +++++ upload-file.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 upload-file.c diff --git a/.gitignore b/.gitignore index 833ef3b..c2db9c2 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,7 @@ /git-update-ref /git-update-server-info /git-upload-archive +/git-upload-file /git-upload-pack /git-var /git-verify-commit diff --git a/Makefile b/Makefile index 9ec6065..1b84322 100644 --- a/Makefile +++ b/Makefile @@ -597,6 +597,7 @@ PROGRAM_OBJS += sh-i18n--envsubst.o PROGRAM_OBJS += shell.o PROGRAM_OBJS += show-index.o PROGRAM_OBJS += upload-pack.o +PROGRAM_OBJS += upload-file.o PROGRAM_OBJS += remote-testsvn.o # Binary suffix, set to .exe for Windows builds @@ -668,6 +669,7 @@ BINDIR_PROGRAMS_NEED_X += git-upload-pack BINDIR_PROGRAMS_NEED_X += git-receive-pack BINDIR_PROGRAMS_NEED_X += git-upload-archive BINDIR_PROGRAMS_NEED_X += git-shell +BINDIR_PROGRAMS_NEED_X += git-upload-file BINDIR_PROGRAMS_NO_X += git-cvsserver diff --git a/daemon.c b/daemon.c index 473e6b6..8b5b026 100644 --- a/daemon.c +++ b/daemon.c @@ -479,6 +479,11 @@ static int upload_pack(void) return run_service_command(argv); } +static int upload_file(void) +{ + const char *argv[] = { "upload-file", ".", NULL }; + return run_service_command(argv); +} static int upload_archive(void) { static const char *argv[] = { "upload-archive", ".", NULL }; @@ -494,6 +499,7 @@ static int receive_pack(void) static struct daemon_service daemon_service[] = { { "upload-archive", "uploadarch", upload_archive, 0, 1 }, { "upload-pack", "uploadpack", upload_pack, 1, 1 }, + { "upload-file", "uploadfile", upload_file, 1, 1 }, { "receive-pack", "receivepack", receive_pack, 0, 1 }, }; diff --git a/upload-file.c b/upload-file.c new file mode 100644 index 0000000..cb2bfe8 --- /dev/null +++ b/upload-file.c @@ -0,0 +1,87 @@ + +#include "cache.h" +#include "exec_cmd.h" +#include "parse-options.h" +#include "pkt-line.h" + +static const char * const upload_file_usage[] = { + N_("git upload-file [<options>] <dir>"), + NULL +}; + + +static void upload_file(void) +{ + for (;;) { + char *line = packet_read_line(0, NULL); + const char *arg; + if (!line) + break; + + if (skip_prefix(line, "info ", &arg)) { + unsigned char sha1[20]; + void *buffer; + enum object_type type; + unsigned long size; + + if (get_sha1_hex(arg, sha1)) + die("invalid sha: %s", arg); + + buffer = read_sha1_file(sha1, &type, &size); + if (buffer) { + packet_write_fmt(1, "found %s %d %ld\n", sha1_to_hex(sha1), type, size); + free(buffer); + } else { + packet_write_fmt(1, "missing %s\n", sha1_to_hex(sha1)); + } + } + + if (skip_prefix(line, "get ", &arg)) { + unsigned char sha1[20]; + void *buffer; + enum object_type type; + unsigned long size; + + if (get_sha1_hex(arg, sha1)) + die("invalid sha: %s", arg); + + buffer = read_sha1_file(sha1, &type, &size); + if (buffer) { + packet_write_fmt(1, "found %s %d %ld\n", sha1_to_hex(sha1), type, size); + write_or_die(1, buffer, size); + free(buffer); + } else { + packet_write_fmt(1, "missing %s\n", sha1_to_hex(sha1)); + } + + } + + if (!strcmp(line, "end")) + break; + } +} + +int cmd_main(int argc, const char **argv) +{ + const char *dir; + struct option options[] = { + OPT_END() + }; + + packet_trace_identity("upload-file"); + + argc = parse_options(argc, argv, NULL, options, upload_file_usage, 0); + + if (argc != 1) + usage_with_options(upload_file_usage, options); + + setup_path(); + + dir = argv[0]; + + if (!enter_repo(dir, 0)) + die("'%s' does not appear to be a git repository", dir); + + upload_file(); + return 0; +} -- 2.7.4