Web lists-archives.com

[RFC 1/4] upload-file: Add upload-file command




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