Refactor git_tcp_connect() functions a little.

Add client side sending of "\0host=%s\0" extended
arg for git native protocol, backwards compatibly.

Signed-off-by: Jon Loeliger <jdl@jdl.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
diff --git a/connect.c b/connect.c
index 54f7bf7..eca94f7 100644
--- a/connect.c
+++ b/connect.c
@@ -322,7 +322,10 @@
 
 #ifndef NO_IPV6
 
-static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
+/*
+ * Returns a connected socket() fd, or else die()s.
+ */
+static int git_tcp_connect_sock(char *host)
 {
 	int sockfd = -1;
 	char *colon, *end;
@@ -356,7 +359,8 @@
 		die("Unable to look up %s (%s)", host, gai_strerror(gai));
 
 	for (ai0 = ai; ai; ai = ai->ai_next) {
-		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+		sockfd = socket(ai->ai_family,
+				ai->ai_socktype, ai->ai_protocol);
 		if (sockfd < 0)
 			continue;
 		if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
@@ -372,15 +376,15 @@
 	if (sockfd < 0)
 		die("unable to connect a socket (%s)", strerror(errno));
 
-	fd[0] = sockfd;
-	fd[1] = sockfd;
-	packet_write(sockfd, "%s %s\n", prog, path);
-	return 0;
+	return sockfd;
 }
 
 #else /* NO_IPV6 */
 
-static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
+/*
+ * Returns a connected socket() fd, or else die()s.
+ */
+static int git_tcp_connect_sock(char *host)
 {
 	int sockfd = -1;
 	char *colon, *end;
@@ -407,7 +411,6 @@
 		port = colon + 1;
 	}
 
-
 	he = gethostbyname(host);
 	if (!he)
 		die("Unable to look up %s (%s)", host, hstrerror(h_errno));
@@ -441,14 +444,22 @@
 	if (sockfd < 0)
 		die("unable to connect a socket (%s)", strerror(errno));
 
-	fd[0] = sockfd;
-	fd[1] = sockfd;
-	packet_write(sockfd, "%s %s\n", prog, path);
-	return 0;
+	return sockfd;
 }
 
 #endif /* NO_IPV6 */
 
+
+static void git_tcp_connect(int fd[2],
+			    const char *prog, char *host, char *path)
+{
+	int sockfd = git_tcp_connect_sock(host);
+
+	fd[0] = sockfd;
+	fd[1] = sockfd;
+}
+
+
 static char *git_proxy_command = NULL;
 static const char *rhost_name = NULL;
 static int rhost_len;
@@ -510,7 +521,8 @@
 	return (git_proxy_command && *git_proxy_command);
 }
 
-static int git_proxy_connect(int fd[2], const char *prog, char *host, char *path)
+static void git_proxy_connect(int fd[2],
+			      const char *prog, char *host, char *path)
 {
 	char *port = STR(DEFAULT_GIT_PORT);
 	char *colon, *end;
@@ -547,12 +559,12 @@
 		execlp(git_proxy_command, git_proxy_command, host, port, NULL);
 		die("exec failed");
 	}
+	if (pid < 0)
+		die("fork failed");
 	fd[0] = pipefd[0][0];
 	fd[1] = pipefd[1][1];
 	close(pipefd[0][1]);
 	close(pipefd[1][0]);
-	packet_write(fd[1], "%s %s\n", prog, path);
-	return pid;
 }
 
 /*
@@ -620,14 +632,26 @@
 	}
 
 	if (protocol == PROTO_GIT) {
-		int ret;
+		/* These underlying connection commands die() if they
+		 * cannot connect.
+		 */
+		char *target_host = strdup(host);
 		if (git_use_proxy(host))
-			ret = git_proxy_connect(fd, prog, host, path);
+			git_proxy_connect(fd, prog, host, path);
 		else
-			ret = git_tcp_connect(fd, prog, host, path);
+			git_tcp_connect(fd, prog, host, path);
+		/*
+		 * Separate original protocol components prog and path
+		 * from extended components with a NUL byte.
+		 */
+		packet_write(fd[1],
+			     "%s %s%chost=%s%c",
+			     prog, path, 0,
+			     target_host, 0);
+		free(target_host);
 		if (free_path)
 			free(path);
-		return ret;
+		return 0;
 	}
 
 	if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
diff --git a/daemon.c b/daemon.c
index 776749e..2f03f99 100644
--- a/daemon.c
+++ b/daemon.c
@@ -267,12 +267,17 @@
 static int execute(void)
 {
 	static char line[1000];
-	int len;
+	int pktlen, len;
 
 	alarm(init_timeout ? init_timeout : timeout);
-	len = packet_read_line(0, line, sizeof(line));
+	pktlen = packet_read_line(0, line, sizeof(line));
 	alarm(0);
 
+	len = strlen(line);
+	if (pktlen != len)
+		loginfo("Extended attributes (%d bytes) exist <%.*s>",
+			(int) pktlen - len,
+			(int) pktlen - len, line + len + 1);
 	if (len && line[len-1] == '\n')
 		line[--len] = 0;