--- http-push.c.orig	2009-02-08 03:46:30.000000000 +0800
+++ http-push.c	2009-04-10 20:05:26.000000000 +0800
@@ -12,6 +12,7 @@
 #include "list-objects.h"
 
 #include <expat.h>
+#include <termios.h>
 
 static const char http_push_usage[] =
 "git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n";
@@ -94,6 +95,8 @@
 	int has_info_packs;
 	struct packed_git *packs;
 	struct remote_lock *locks;
+	char *http_auth_user;
+	char *http_auth_pass;
 };
 
 static struct repo *remote;
@@ -329,6 +332,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	/* If we have successfully processed data from a previous fetch
 	   attempt, only fetch the data we don't already have. */
@@ -375,6 +382,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		request->slot = slot;
@@ -452,6 +463,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 	slot->local = packfile;
 
 	/* If there is data present from a previous transfer attempt,
@@ -547,6 +562,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		request->slot = slot;
@@ -573,6 +592,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		request->slot = slot;
@@ -608,6 +631,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -917,6 +944,10 @@
 	slot->results = &results;
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
 		if (results.curl_result != CURLE_OK) {
@@ -956,6 +987,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 	slot->local = indexfile;
 
 	/* If there is data present from a previous transfer attempt,
@@ -1027,6 +1062,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
 		if (results.curl_result != CURLE_OK) {
@@ -1188,12 +1227,14 @@
 	struct slot_results results;
 	struct buffer out_buffer = { STRBUF_INIT, 0 };
 	struct strbuf in_buffer = STRBUF_INIT;
+	struct strbuf sb = STRBUF_INIT;
 	char *url;
 	char *ep;
 	char timeout_header[25];
 	struct remote_lock *lock = NULL;
 	struct curl_slist *dav_headers = NULL;
 	struct xml_ctx ctx;
+	int has_tried = 0;
 
 	url = xmalloc(strlen(remote->url) + strlen(path) + 1);
 	sprintf(url, "%s%s", remote->url, path);
@@ -1209,10 +1250,61 @@
 		curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 		curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
 		curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
+		if (remote->http_auth_user)
+			curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+		if (remote->http_auth_pass)
+			curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
+
 		if (start_active_slot(slot)) {
 			run_active_slot(slot);
 			if (results.curl_result != CURLE_OK &&
 			    results.http_code != 405) {
+			    	if (results.http_code == 401 && !has_tried) {
+			    		struct termios old, new;
+
+			    		has_tried++;
+					printf("HTTP Authorization Required.\nUsername: ");
+					if (strbuf_getline(&sb, stdin, '\n') == EOF)
+					{
+						free(url);
+						return NULL;
+					}
+					remote->http_auth_user = xstrdup(sb.buf);
+
+					printf("Password: ");
+
+					/* Turn echoing off and fail if we can't. */
+					if (tcgetattr(fileno (stdin), &old) != 0)
+					{
+						free(url);
+						return NULL;
+					}
+
+					new = old;
+					new.c_lflag &= ~ECHO || ECHOCTL;
+
+					if (tcsetattr (fileno (stdin), TCSAFLUSH, &new) != 0)
+					{
+						free(url);
+						return NULL;
+					}
+
+					if (strbuf_getline(&sb, stdin, '\n') == EOF)
+					{
+						(void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);
+						free(url);
+						return NULL;
+					}
+
+					(void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);
+					printf("\n");
+
+					remote->http_auth_pass = xstrdup(sb.buf);
+					strbuf_release(&sb);
+					ep = strchr(url + strlen(remote->url) + 1, '/');
+					continue;
+				}
+
 				fprintf(stderr,
 					"Unable to create branch path %s\n",
 					url);
@@ -1245,6 +1337,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	lock = xcalloc(1, sizeof(*lock));
 	lock->timeout = -1;
@@ -1318,6 +1414,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_UNLOCK);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -1491,6 +1591,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -1547,15 +1651,17 @@
 	struct slot_results results;
 	struct strbuf in_buffer = STRBUF_INIT;
 	struct buffer out_buffer = { STRBUF_INIT, 0 };
+	struct strbuf sb = STRBUF_INIT;
 	struct curl_slist *dav_headers = NULL;
 	struct xml_ctx ctx;
 	int lock_flags = 0;
+	int has_tried = 0;
 
 	strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);
 
 	dav_headers = curl_slist_append(dav_headers, "Depth: 0");
 	dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
-
+LK_RETRY:
 	slot = get_active_slot();
 	slot->results = &results;
 	curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
@@ -1567,6 +1673,11 @@
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -1597,6 +1708,47 @@
 				      remote->url);
 
 		} else {
+			if (results.http_code == 401 && !has_tried) {
+			 	struct termios old, new;
+
+			    	has_tried++;
+				printf("HTTP Authorization Required.\nUsername: ");
+				if (strbuf_getline(&sb, stdin, '\n') == EOF)
+				{
+					goto LK_END;
+				}
+				remote->http_auth_user = xstrdup(sb.buf);
+
+				printf("Password: ");
+
+				/* Turn echoing off and fail if we can't. */
+				if (tcgetattr(fileno (stdin), &old) != 0)
+				{
+					goto LK_END;
+				}
+
+				new = old;
+				new.c_lflag &= ~ECHO || ECHOCTL;
+
+				if (tcsetattr (fileno (stdin), TCSAFLUSH, &new) != 0)
+				{
+					goto LK_END;
+				}
+
+				if (strbuf_getline(&sb, stdin, '\n') == EOF)
+				{
+					(void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);
+					goto LK_END;
+				}
+
+				(void) tcsetattr (fileno (stdin), TCSAFLUSH, &old);
+				printf("\n");
+
+				remote->http_auth_pass = xstrdup(sb.buf);
+				strbuf_release(&sb);
+				goto LK_RETRY;
+			}
+LK_END:
 			error("Cannot access URL %s, return code %d",
 			      remote->url, results.curl_result);
 			lock_flags = 0;
@@ -1752,6 +1904,10 @@
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -1969,6 +2125,10 @@
 		curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
 		curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
 		curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
+		if (remote->http_auth_user)
+			curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+		if (remote->http_auth_pass)
+			curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 		if (start_active_slot(slot)) {
 			run_active_slot(slot);
@@ -1996,6 +2156,10 @@
 	slot->results = &results;
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
 
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
@@ -2029,6 +2193,11 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
+
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
 		if (results.curl_result != CURLE_OK) {
@@ -2152,6 +2321,11 @@
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
 	curl_easy_setopt(slot->curl, CURLOPT_URL, url);
 	curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_DELETE);
+	if (remote->http_auth_user)
+		curl_easy_setopt(slot->curl, CURLOPT_USERNAME, remote->http_auth_user);
+	if (remote->http_auth_pass)
+		curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, remote->http_auth_pass);
+
 	if (start_active_slot(slot)) {
 		run_active_slot(slot);
 		free(url);
@@ -2457,6 +2631,13 @@
 	free(rewritten_url);
 	if (info_ref_lock)
 		unlock_remote(info_ref_lock);
+
+	if (remote->http_auth_user)
+		free(remote->http_auth_user);
+
+	if (remote->http_auth_pass)
+		free(remote->http_auth_pass);
+
 	free(remote);
 
 	curl_slist_free_all(no_pragma_header);
