From: Daniel Barkalow <barkalow@iabervon.org>
Date: Fri, 3 Jun 2005 21:43:52 +0000 (-0400)
Subject: [PATCH] ssh-protocol version, command types, response code
X-Git-Tag: v0.99~371
X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=dba385bb3ed541c4d18e2b8080960eee358394fa;p=git.git

[PATCH] ssh-protocol version, command types, response code

This patch makes an incompatible change to the protocol used by
rpull/rpush which will let it be extended in the future without
incompatible changes.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

diff --git a/rpull.c b/rpull.c
index 8b3322fe0..f4ab89836 100644
--- a/rpull.c
+++ b/rpull.c
@@ -6,16 +6,39 @@
 static int fd_in;
 static int fd_out;
 
+static unsigned char remote_version = 0;
+static unsigned char local_version = 1;
+
 int fetch(unsigned char *sha1)
 {
 	int ret;
+	signed char remote;
+	char type = 'o';
+	if (has_sha1_file(sha1))
+		return 0;
+	write(fd_out, &type, 1);
 	write(fd_out, sha1, 20);
+	if (read(fd_in, &remote, 1) < 1)
+		return -1;
+	if (remote < 0)
+		return remote;
 	ret = write_sha1_from_fd(sha1, fd_in);
 	if (!ret)
 		pull_say("got %s\n", sha1_to_hex(sha1));
 	return ret;
 }
 
+int get_version(void)
+{
+	char type = 'v';
+	write(fd_out, &type, 1);
+	write(fd_out, &local_version, 1);
+	if (read(fd_in, &remote_version, 1) < 1) {
+		return error("Couldn't read version from remote end");
+	}
+	return 0;
+}
+
 int main(int argc, char **argv)
 {
 	char *commit_id;
@@ -48,6 +71,9 @@ int main(int argc, char **argv)
 	if (setup_connection(&fd_in, &fd_out, "git-rpush", url, arg, argv + 1))
 		return 1;
 
+	if (get_version())
+		return 1;
+
 	if (pull(commit_id))
 		return 1;
 
diff --git a/rpush.c b/rpush.c
index 17d5ab8a6..bd381ac9d 100644
--- a/rpush.c
+++ b/rpush.c
@@ -3,46 +3,81 @@
 #include <sys/socket.h>
 #include <errno.h>
 
-static void service(int fd_in, int fd_out) {
+unsigned char local_version = 1;
+unsigned char remote_version = 0;
+
+int serve_object(int fd_in, int fd_out) {
 	ssize_t size;
-	int posn;
-	char unsigned sha1[20];
+	int posn = 0;
+	char sha1[20];
 	unsigned long objsize;
 	void *buf;
+	signed char remote;
+	do {
+		size = read(fd_in, sha1 + posn, 20 - posn);
+		if (size < 0) {
+			perror("git-rpush: read ");
+			return -1;
+		}
+		if (!size)
+			return -1;
+		posn += size;
+	} while (posn < 20);
+	
+	/* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
+	remote = 0;
+	
+	buf = map_sha1_file(sha1, &objsize);
+	
+	if (!buf) {
+		fprintf(stderr, "git-rpush: could not find %s\n", 
+			sha1_to_hex(sha1));
+		remote = -1;
+	}
+	
+	write(fd_out, &remote, 1);
+	
+	if (remote < 0)
+		return 0;
+	
+	posn = 0;
 	do {
-		posn = 0;
-		do {
-			size = read(fd_in, sha1 + posn, 20 - posn);
-			if (size < 0) {
-				perror("git-rpush: read ");
-				return;
+		size = write(fd_out, buf + posn, objsize - posn);
+		if (size <= 0) {
+			if (!size) {
+				fprintf(stderr, "git-rpush: write closed");
+			} else {
+				perror("git-rpush: write ");
 			}
-			if (!size)
-				return;
-			posn += size;
-		} while (posn < 20);
+			return -1;
+		}
+		posn += size;
+	} while (posn < objsize);
+	return 0;
+}
 
-		/* fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); */
+int serve_version(int fd_in, int fd_out)
+{
+	if (read(fd_in, &remote_version, 1) < 1)
+		return -1;
+	write(fd_out, &local_version, 1);
+	return 0;
+}
 
-		buf = map_sha1_file(sha1, &objsize);
-		if (!buf) {
-			fprintf(stderr, "git-rpush: could not find %s\n", 
-				sha1_to_hex(sha1));
+void service(int fd_in, int fd_out) {
+	char type;
+	int retval;
+	do {
+		retval = read(fd_in, &type, 1);
+		if (retval < 1) {
+			if (retval < 0)
+				perror("rpush: read ");
 			return;
 		}
-		posn = 0;
-		do {
-			size = write(fd_out, buf + posn, objsize - posn);
-			if (size <= 0) {
-				if (!size) {
-					fprintf(stderr, "git-rpush: write closed");
-				} else {
-					perror("git-rpush: write ");
-				}
-				return;
-			}
-			posn += size;
-		} while (posn < objsize);
+		if (type == 'v' && serve_version(fd_in, fd_out))
+			return;
+		if (type == 'o' && serve_object(fd_in, fd_out))
+			return;
 	} while (1);
 }
 
@@ -56,7 +91,7 @@ int main(int argc, char **argv)
                 arg++;
         }
         if (argc < arg + 2) {
-                usage("git-rpush [-c] [-t] [-a] commit-id url");
+		usage("git-rpush [-c] [-t] [-a] commit-id url");
                 return 1;
         }
 	commit_id = argv[arg];