93a50b4444e3bba210f6879795979d0894ad5aaf
[git.git] / http-push.c
1 #include "cache.h"
2 #include "commit.h"
3 #include "pack.h"
4 #include "fetch.h"
5 #include "tag.h"
6 #include "blob.h"
7 #include "http.h"
8 #include "refs.h"
9 #include "revision.h"
10
11 #include <expat.h>
12
13 static const char http_push_usage[] =
14 "git-http-push [--complete] [--force] [--verbose] <url> <ref> [<ref>...]\n";
15
16 #ifndef XML_STATUS_OK
17 enum XML_Status {
18   XML_STATUS_OK = 1,
19   XML_STATUS_ERROR = 0
20 };
21 #define XML_STATUS_OK    1
22 #define XML_STATUS_ERROR 0
23 #endif
24
25 #define PREV_BUF_SIZE 4096
26 #define RANGE_HEADER_SIZE 30
27
28 /* DAV methods */
29 #define DAV_LOCK "LOCK"
30 #define DAV_MKCOL "MKCOL"
31 #define DAV_MOVE "MOVE"
32 #define DAV_PROPFIND "PROPFIND"
33 #define DAV_PUT "PUT"
34 #define DAV_UNLOCK "UNLOCK"
35
36 /* DAV lock flags */
37 #define DAV_PROP_LOCKWR (1u << 0)
38 #define DAV_PROP_LOCKEX (1u << 1)
39 #define DAV_LOCK_OK (1u << 2)
40
41 /* DAV XML properties */
42 #define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
43 #define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
44 #define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
45 #define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
46 #define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
47 #define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
48 #define DAV_PROPFIND_RESP ".multistatus.response"
49 #define DAV_PROPFIND_NAME ".multistatus.response.href"
50 #define DAV_PROPFIND_COLLECTION ".multistatus.response.propstat.prop.resourcetype.collection"
51
52 /* DAV request body templates */
53 #define PROPFIND_SUPPORTEDLOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock/>\n</D:prop>\n</D:propfind>"
54 #define PROPFIND_ALL_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:allprop/>\n</D:propfind>"
55 #define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>\n<D:owner>\n<D:href>mailto:%s</D:href>\n</D:owner>\n</D:lockinfo>"
56
57 #define LOCK_TIME 600
58 #define LOCK_REFRESH 30
59
60 /* bits #0-4 in revision.h */
61
62 #define LOCAL    (1u << 5)
63 #define REMOTE   (1u << 6)
64 #define FETCHING (1u << 7)
65 #define PUSHING  (1u << 8)
66
67 static int pushing = 0;
68 static int aborted = 0;
69 static char remote_dir_exists[256];
70
71 static struct curl_slist *no_pragma_header;
72 static struct curl_slist *default_headers;
73
74 static int push_verbosely = 0;
75 static int push_all = 0;
76 static int force_all = 0;
77
78 static struct object_list *objects = NULL;
79
80 struct repo
81 {
82         char *url;
83         int path_len;
84         int has_info_refs;
85         int can_update_info_refs;
86         int has_info_packs;
87         struct packed_git *packs;
88         struct remote_lock *locks;
89 };
90
91 static struct repo *remote = NULL;
92
93 enum transfer_state {
94         NEED_FETCH,
95         RUN_FETCH_LOOSE,
96         RUN_FETCH_PACKED,
97         NEED_PUSH,
98         RUN_MKCOL,
99         RUN_PUT,
100         RUN_MOVE,
101         ABORTED,
102         COMPLETE,
103 };
104
105 struct transfer_request
106 {
107         struct object *obj;
108         char *url;
109         char *dest;
110         struct remote_lock *lock;
111         struct curl_slist *headers;
112         struct buffer buffer;
113         char filename[PATH_MAX];
114         char tmpfile[PATH_MAX];
115         int local_fileno;
116         FILE *local_stream;
117         enum transfer_state state;
118         CURLcode curl_result;
119         char errorstr[CURL_ERROR_SIZE];
120         long http_code;
121         unsigned char real_sha1[20];
122         SHA_CTX c;
123         z_stream stream;
124         int zret;
125         int rename;
126         void *userData;
127         struct active_request_slot *slot;
128         struct transfer_request *next;
129 };
130
131 static struct transfer_request *request_queue_head = NULL;
132
133 struct xml_ctx
134 {
135         char *name;
136         int len;
137         char *cdata;
138         void (*userFunc)(struct xml_ctx *ctx, int tag_closed);
139         void *userData;
140 };
141
142 struct remote_lock
143 {
144         char *url;
145         char *owner;
146         char *token;
147         time_t start_time;
148         long timeout;
149         int refreshing;
150         struct remote_lock *next;
151 };
152
153 /* Flags that control remote_ls processing */
154 #define PROCESS_FILES (1u << 0)
155 #define PROCESS_DIRS  (1u << 1)
156 #define RECURSIVE     (1u << 2)
157
158 /* Flags that remote_ls passes to callback functions */
159 #define IS_DIR (1u << 0)
160
161 struct remote_ls_ctx
162 {
163         char *path;
164         void (*userFunc)(struct remote_ls_ctx *ls);
165         void *userData;
166         int flags;
167         char *dentry_name;
168         int dentry_flags;
169         struct remote_ls_ctx *parent;
170 };
171
172 static void finish_request(struct transfer_request *request);
173 static void release_request(struct transfer_request *request);
174
175 static void process_response(void *callback_data)
176 {
177         struct transfer_request *request =
178                 (struct transfer_request *)callback_data;
179
180         finish_request(request);
181 }
182
183 static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
184                                void *data)
185 {
186         unsigned char expn[4096];
187         size_t size = eltsize * nmemb;
188         int posn = 0;
189         struct transfer_request *request = (struct transfer_request *)data;
190         do {
191                 ssize_t retval = write(request->local_fileno,
192                                        ptr + posn, size - posn);
193                 if (retval < 0)
194                         return posn;
195                 posn += retval;
196         } while (posn < size);
197
198         request->stream.avail_in = size;
199         request->stream.next_in = ptr;
200         do {
201                 request->stream.next_out = expn;
202                 request->stream.avail_out = sizeof(expn);
203                 request->zret = inflate(&request->stream, Z_SYNC_FLUSH);
204                 SHA1_Update(&request->c, expn,
205                             sizeof(expn) - request->stream.avail_out);
206         } while (request->stream.avail_in && request->zret == Z_OK);
207         data_received++;
208         return size;
209 }
210
211 static void start_fetch_loose(struct transfer_request *request)
212 {
213         char *hex = sha1_to_hex(request->obj->sha1);
214         char *filename;
215         char prevfile[PATH_MAX];
216         char *url;
217         char *posn;
218         int prevlocal;
219         unsigned char prev_buf[PREV_BUF_SIZE];
220         ssize_t prev_read = 0;
221         long prev_posn = 0;
222         char range[RANGE_HEADER_SIZE];
223         struct curl_slist *range_header = NULL;
224         struct active_request_slot *slot;
225
226         filename = sha1_file_name(request->obj->sha1);
227         snprintf(request->filename, sizeof(request->filename), "%s", filename);
228         snprintf(request->tmpfile, sizeof(request->tmpfile),
229                  "%s.temp", filename);
230
231         snprintf(prevfile, sizeof(prevfile), "%s.prev", request->filename);
232         unlink(prevfile);
233         rename(request->tmpfile, prevfile);
234         unlink(request->tmpfile);
235
236         if (request->local_fileno != -1)
237                 error("fd leakage in start: %d", request->local_fileno);
238         request->local_fileno = open(request->tmpfile,
239                                      O_WRONLY | O_CREAT | O_EXCL, 0666);
240         /* This could have failed due to the "lazy directory creation";
241          * try to mkdir the last path component.
242          */
243         if (request->local_fileno < 0 && errno == ENOENT) {
244                 char *dir = strrchr(request->tmpfile, '/');
245                 if (dir) {
246                         *dir = 0;
247                         mkdir(request->tmpfile, 0777);
248                         *dir = '/';
249                 }
250                 request->local_fileno = open(request->tmpfile,
251                                              O_WRONLY | O_CREAT | O_EXCL, 0666);
252         }
253
254         if (request->local_fileno < 0) {
255                 request->state = ABORTED;
256                 error("Couldn't create temporary file %s for %s: %s",
257                       request->tmpfile, request->filename, strerror(errno));
258                 return;
259         }
260
261         memset(&request->stream, 0, sizeof(request->stream));
262
263         inflateInit(&request->stream);
264
265         SHA1_Init(&request->c);
266
267         url = xmalloc(strlen(remote->url) + 50);
268         request->url = xmalloc(strlen(remote->url) + 50);
269         strcpy(url, remote->url);
270         posn = url + strlen(remote->url);
271         strcpy(posn, "objects/");
272         posn += 8;
273         memcpy(posn, hex, 2);
274         posn += 2;
275         *(posn++) = '/';
276         strcpy(posn, hex + 2);
277         strcpy(request->url, url);
278
279         /* If a previous temp file is present, process what was already
280            fetched. */
281         prevlocal = open(prevfile, O_RDONLY);
282         if (prevlocal != -1) {
283                 do {
284                         prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE);
285                         if (prev_read>0) {
286                                 if (fwrite_sha1_file(prev_buf,
287                                                      1,
288                                                      prev_read,
289                                                      request) == prev_read) {
290                                         prev_posn += prev_read;
291                                 } else {
292                                         prev_read = -1;
293                                 }
294                         }
295                 } while (prev_read > 0);
296                 close(prevlocal);
297         }
298         unlink(prevfile);
299
300         /* Reset inflate/SHA1 if there was an error reading the previous temp
301            file; also rewind to the beginning of the local file. */
302         if (prev_read == -1) {
303                 memset(&request->stream, 0, sizeof(request->stream));
304                 inflateInit(&request->stream);
305                 SHA1_Init(&request->c);
306                 if (prev_posn>0) {
307                         prev_posn = 0;
308                         lseek(request->local_fileno, SEEK_SET, 0);
309                         ftruncate(request->local_fileno, 0);
310                 }
311         }
312
313         slot = get_active_slot();
314         slot->callback_func = process_response;
315         slot->callback_data = request;
316         request->slot = slot;
317
318         curl_easy_setopt(slot->curl, CURLOPT_FILE, request);
319         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
320         curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
321         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
322         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
323
324         /* If we have successfully processed data from a previous fetch
325            attempt, only fetch the data we don't already have. */
326         if (prev_posn>0) {
327                 if (push_verbosely)
328                         fprintf(stderr,
329                                 "Resuming fetch of object %s at byte %ld\n",
330                                 hex, prev_posn);
331                 sprintf(range, "Range: bytes=%ld-", prev_posn);
332                 range_header = curl_slist_append(range_header, range);
333                 curl_easy_setopt(slot->curl,
334                                  CURLOPT_HTTPHEADER, range_header);
335         }
336
337         /* Try to get the request started, abort the request on error */
338         request->state = RUN_FETCH_LOOSE;
339         if (!start_active_slot(slot)) {
340                 fprintf(stderr, "Unable to start GET request\n");
341                 remote->can_update_info_refs = 0;
342                 release_request(request);
343         }
344 }
345
346 static void start_fetch_packed(struct transfer_request *request)
347 {
348         char *url;
349         struct packed_git *target;
350         FILE *packfile;
351         char *filename;
352         long prev_posn = 0;
353         char range[RANGE_HEADER_SIZE];
354         struct curl_slist *range_header = NULL;
355
356         struct transfer_request *check_request = request_queue_head;
357         struct active_request_slot *slot;
358
359         target = find_sha1_pack(request->obj->sha1, remote->packs);
360         if (!target) {
361                 fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", sha1_to_hex(request->obj->sha1));
362                 remote->can_update_info_refs = 0;
363                 release_request(request);
364                 return;
365         }
366
367         fprintf(stderr, "Fetching pack %s\n", sha1_to_hex(target->sha1));
368         fprintf(stderr, " which contains %s\n", sha1_to_hex(request->obj->sha1));
369
370         filename = sha1_pack_name(target->sha1);
371         snprintf(request->filename, sizeof(request->filename), "%s", filename);
372         snprintf(request->tmpfile, sizeof(request->tmpfile),
373                  "%s.temp", filename);
374
375         url = xmalloc(strlen(remote->url) + 64);
376         sprintf(url, "%sobjects/pack/pack-%s.pack",
377                 remote->url, sha1_to_hex(target->sha1));
378
379         /* Make sure there isn't another open request for this pack */
380         while (check_request) {
381                 if (check_request->state == RUN_FETCH_PACKED &&
382                     !strcmp(check_request->url, url)) {
383                         free(url);
384                         release_request(request);
385                         return;
386                 }
387                 check_request = check_request->next;
388         }
389
390         packfile = fopen(request->tmpfile, "a");
391         if (!packfile) {
392                 fprintf(stderr, "Unable to open local file %s for pack",
393                         filename);
394                 remote->can_update_info_refs = 0;
395                 free(url);
396                 return;
397         }
398
399         slot = get_active_slot();
400         slot->callback_func = process_response;
401         slot->callback_data = request;
402         request->slot = slot;
403         request->local_stream = packfile;
404         request->userData = target;
405
406         request->url = url;
407         curl_easy_setopt(slot->curl, CURLOPT_FILE, packfile);
408         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
409         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
410         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
411         slot->local = packfile;
412
413         /* If there is data present from a previous transfer attempt,
414            resume where it left off */
415         prev_posn = ftell(packfile);
416         if (prev_posn>0) {
417                 if (push_verbosely)
418                         fprintf(stderr,
419                                 "Resuming fetch of pack %s at byte %ld\n",
420                                 sha1_to_hex(target->sha1), prev_posn);
421                 sprintf(range, "Range: bytes=%ld-", prev_posn);
422                 range_header = curl_slist_append(range_header, range);
423                 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
424         }
425
426         /* Try to get the request started, abort the request on error */
427         request->state = RUN_FETCH_PACKED;
428         if (!start_active_slot(slot)) {
429                 fprintf(stderr, "Unable to start GET request\n");
430                 remote->can_update_info_refs = 0;
431                 release_request(request);
432         }
433 }
434
435 static void start_mkcol(struct transfer_request *request)
436 {
437         char *hex = sha1_to_hex(request->obj->sha1);
438         struct active_request_slot *slot;
439         char *posn;
440
441         request->url = xmalloc(strlen(remote->url) + 13);
442         strcpy(request->url, remote->url);
443         posn = request->url + strlen(remote->url);
444         strcpy(posn, "objects/");
445         posn += 8;
446         memcpy(posn, hex, 2);
447         posn += 2;
448         strcpy(posn, "/");
449
450         slot = get_active_slot();
451         slot->callback_func = process_response;
452         slot->callback_data = request;
453         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
454         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
455         curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
456         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
457         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
458
459         if (start_active_slot(slot)) {
460                 request->slot = slot;
461                 request->state = RUN_MKCOL;
462         } else {
463                 request->state = ABORTED;
464                 free(request->url);
465                 request->url = NULL;
466         }
467 }
468
469 static void start_put(struct transfer_request *request)
470 {
471         char *hex = sha1_to_hex(request->obj->sha1);
472         struct active_request_slot *slot;
473         char *posn;
474         char type[20];
475         char hdr[50];
476         void *unpacked;
477         unsigned long len;
478         int hdrlen;
479         ssize_t size;
480         z_stream stream;
481
482         unpacked = read_sha1_file(request->obj->sha1, type, &len);
483         hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
484
485         /* Set it up */
486         memset(&stream, 0, sizeof(stream));
487         deflateInit(&stream, Z_BEST_COMPRESSION);
488         size = deflateBound(&stream, len + hdrlen);
489         request->buffer.buffer = xmalloc(size);
490
491         /* Compress it */
492         stream.next_out = request->buffer.buffer;
493         stream.avail_out = size;
494
495         /* First header.. */
496         stream.next_in = (void *)hdr;
497         stream.avail_in = hdrlen;
498         while (deflate(&stream, 0) == Z_OK)
499                 /* nothing */;
500
501         /* Then the data itself.. */
502         stream.next_in = unpacked;
503         stream.avail_in = len;
504         while (deflate(&stream, Z_FINISH) == Z_OK)
505                 /* nothing */;
506         deflateEnd(&stream);
507         free(unpacked);
508
509         request->buffer.size = stream.total_out;
510         request->buffer.posn = 0;
511
512         request->url = xmalloc(strlen(remote->url) + 
513                                strlen(request->lock->token) + 51);
514         strcpy(request->url, remote->url);
515         posn = request->url + strlen(remote->url);
516         strcpy(posn, "objects/");
517         posn += 8;
518         memcpy(posn, hex, 2);
519         posn += 2;
520         *(posn++) = '/';
521         strcpy(posn, hex + 2);
522         request->dest = xmalloc(strlen(request->url) + 14);
523         sprintf(request->dest, "Destination: %s", request->url);
524         posn += 38;
525         *(posn++) = '.';
526         strcpy(posn, request->lock->token);
527
528         slot = get_active_slot();
529         slot->callback_func = process_response;
530         slot->callback_data = request;
531         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);
532         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.size);
533         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
534         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
535         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
536         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
537         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
538         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
539         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
540
541         if (start_active_slot(slot)) {
542                 request->slot = slot;
543                 request->state = RUN_PUT;
544         } else {
545                 request->state = ABORTED;
546                 free(request->url);
547                 request->url = NULL;
548         }
549 }
550
551 static void start_move(struct transfer_request *request)
552 {
553         struct active_request_slot *slot;
554         struct curl_slist *dav_headers = NULL;
555
556         slot = get_active_slot();
557         slot->callback_func = process_response;
558         slot->callback_data = request;
559         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
560         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MOVE);
561         dav_headers = curl_slist_append(dav_headers, request->dest);
562         dav_headers = curl_slist_append(dav_headers, "Overwrite: T");
563         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
564         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
565         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
566
567         if (start_active_slot(slot)) {
568                 request->slot = slot;
569                 request->state = RUN_MOVE;
570         } else {
571                 request->state = ABORTED;
572                 free(request->url);
573                 request->url = NULL;
574         }
575 }
576
577 static int refresh_lock(struct remote_lock *lock)
578 {
579         struct active_request_slot *slot;
580         struct slot_results results;
581         char *if_header;
582         char timeout_header[25];
583         struct curl_slist *dav_headers = NULL;
584         int rc = 0;
585
586         lock->refreshing = 1;
587
588         if_header = xmalloc(strlen(lock->token) + 25);
589         sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
590         sprintf(timeout_header, "Timeout: Second-%ld", lock->timeout);
591         dav_headers = curl_slist_append(dav_headers, if_header);
592         dav_headers = curl_slist_append(dav_headers, timeout_header);
593
594         slot = get_active_slot();
595         slot->results = &results;
596         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
597         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
598         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
599         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
600         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
601
602         if (start_active_slot(slot)) {
603                 run_active_slot(slot);
604                 if (results.curl_result != CURLE_OK) {
605                         fprintf(stderr, "LOCK HTTP error %ld\n",
606                                 results.http_code);
607                 } else {
608                         lock->start_time = time(NULL);
609                         rc = 1;
610                 }
611         }
612
613         lock->refreshing = 0;
614         curl_slist_free_all(dav_headers);
615         free(if_header);
616
617         return rc;
618 }
619
620 static void check_locks()
621 {
622         struct remote_lock *lock = remote->locks;
623         time_t current_time = time(NULL);
624         int time_remaining;
625
626         while (lock) {
627                 time_remaining = lock->start_time + lock->timeout -
628                         current_time;
629                 if (!lock->refreshing && time_remaining < LOCK_REFRESH) {
630                         if (!refresh_lock(lock)) {
631                                 fprintf(stderr,
632                                         "Unable to refresh lock for %s\n",
633                                         lock->url);
634                                 aborted = 1;
635                                 return;
636                         }
637                 }
638                 lock = lock->next;
639         }
640 }
641
642 static void release_request(struct transfer_request *request)
643 {
644         struct transfer_request *entry = request_queue_head;
645
646         if (request == request_queue_head) {
647                 request_queue_head = request->next;
648         } else {
649                 while (entry->next != NULL && entry->next != request)
650                         entry = entry->next;
651                 if (entry->next == request)
652                         entry->next = entry->next->next;
653         }
654
655         if (request->local_fileno != -1)
656                 close(request->local_fileno);
657         if (request->local_stream)
658                 fclose(request->local_stream);
659         if (request->url != NULL)
660                 free(request->url);
661         free(request);
662 }
663
664 static void finish_request(struct transfer_request *request)
665 {
666         struct stat st;
667         struct packed_git *target;
668         struct packed_git **lst;
669
670         request->curl_result = request->slot->curl_result;
671         request->http_code = request->slot->http_code;
672         request->slot = NULL;
673
674         /* Keep locks active */
675         check_locks();
676
677         if (request->headers != NULL)
678                 curl_slist_free_all(request->headers);
679
680         /* URL is reused for MOVE after PUT */
681         if (request->state != RUN_PUT) {
682                 free(request->url);
683                 request->url = NULL;
684         }
685
686         if (request->state == RUN_MKCOL) {
687                 if (request->curl_result == CURLE_OK ||
688                     request->http_code == 405) {
689                         remote_dir_exists[request->obj->sha1[0]] = 1;
690                         start_put(request);
691                 } else {
692                         fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
693                                 sha1_to_hex(request->obj->sha1),
694                                 request->curl_result, request->http_code);
695                         request->state = ABORTED;
696                         aborted = 1;
697                 }
698         } else if (request->state == RUN_PUT) {
699                 if (request->curl_result == CURLE_OK) {
700                         start_move(request);
701                 } else {
702                         fprintf(stderr, "PUT %s failed, aborting (%d/%ld)\n",
703                                 sha1_to_hex(request->obj->sha1),
704                                 request->curl_result, request->http_code);
705                         request->state = ABORTED;
706                         aborted = 1;
707                 }
708         } else if (request->state == RUN_MOVE) {
709                 if (request->curl_result == CURLE_OK) {
710                         fprintf(stderr, "    sent %s\n",
711                                 sha1_to_hex(request->obj->sha1));
712                         request->obj->flags |= REMOTE;
713                         release_request(request);
714                 } else {
715                         fprintf(stderr, "MOVE %s failed, aborting (%d/%ld)\n",
716                                 sha1_to_hex(request->obj->sha1),
717                                 request->curl_result, request->http_code);
718                         request->state = ABORTED;
719                         aborted = 1;
720                 }
721         } else if (request->state == RUN_FETCH_LOOSE) {
722                 fchmod(request->local_fileno, 0444);
723                 close(request->local_fileno); request->local_fileno = -1;
724
725                 if (request->curl_result != CURLE_OK &&
726                     request->http_code != 416) {
727                         if (stat(request->tmpfile, &st) == 0) {
728                                 if (st.st_size == 0)
729                                         unlink(request->tmpfile);
730                         }
731                 } else {
732                         if (request->http_code == 416)
733                                 fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n");
734
735                         inflateEnd(&request->stream);
736                         SHA1_Final(request->real_sha1, &request->c);
737                         if (request->zret != Z_STREAM_END) {
738                                 unlink(request->tmpfile);
739                         } else if (memcmp(request->obj->sha1, request->real_sha1, 20)) {
740                                 unlink(request->tmpfile);
741                         } else {
742                                 request->rename =
743                                         move_temp_to_file(
744                                                 request->tmpfile,
745                                                 request->filename);
746                                 if (request->rename == 0) {
747                                         request->obj->flags |= (LOCAL | REMOTE);
748                                 }
749                         }
750                 }
751
752                 /* Try fetching packed if necessary */
753                 if (request->obj->flags & LOCAL)
754                         release_request(request);
755                 else
756                         start_fetch_packed(request);
757
758         } else if (request->state == RUN_FETCH_PACKED) {
759                 if (request->curl_result != CURLE_OK) {
760                         fprintf(stderr, "Unable to get pack file %s\n%s",
761                                 request->url, curl_errorstr);
762                         remote->can_update_info_refs = 0;
763                 } else {
764                         fclose(request->local_stream);
765                         request->local_stream = NULL;
766                         if (!move_temp_to_file(request->tmpfile,
767                                                request->filename)) {
768                                 target = (struct packed_git *)request->userData;
769                                 lst = &remote->packs;
770                                 while (*lst != target)
771                                         lst = &((*lst)->next);
772                                 *lst = (*lst)->next;
773
774                                 if (!verify_pack(target, 0))
775                                         install_packed_git(target);
776                                 else
777                                         remote->can_update_info_refs = 0;
778                         }
779                 }
780                 release_request(request);
781         }
782 }
783
784 void fill_active_slots(void)
785 {
786         struct transfer_request *request = request_queue_head;
787         struct transfer_request *next;
788         struct active_request_slot *slot = active_queue_head;
789         int num_transfers;
790
791         if (aborted)
792                 return;
793
794         while (active_requests < max_requests && request != NULL) {
795                 next = request->next;
796                 if (request->state == NEED_FETCH) {
797                         start_fetch_loose(request);
798                 } else if (pushing && request->state == NEED_PUSH) {
799                         if (remote_dir_exists[request->obj->sha1[0]] == 1) {
800                                 start_put(request);
801                         } else {
802                                 start_mkcol(request);
803                         }
804                         curl_multi_perform(curlm, &num_transfers);
805                 }
806                 request = next;
807         }
808
809         while (slot != NULL) {
810                 if (!slot->in_use && slot->curl != NULL) {
811                         curl_easy_cleanup(slot->curl);
812                         slot->curl = NULL;
813                 }
814                 slot = slot->next;
815         }
816 }
817
818 static void get_remote_object_list(unsigned char parent);
819
820 static void add_fetch_request(struct object *obj)
821 {
822         struct transfer_request *request;
823
824         check_locks();
825
826         /*
827          * Don't fetch the object if it's known to exist locally
828          * or is already in the request queue
829          */
830         if (remote_dir_exists[obj->sha1[0]] == -1)
831                 get_remote_object_list(obj->sha1[0]);
832         if (obj->flags & (LOCAL | FETCHING))
833                 return;
834
835         obj->flags |= FETCHING;
836         request = xmalloc(sizeof(*request));
837         request->obj = obj;
838         request->url = NULL;
839         request->lock = NULL;
840         request->headers = NULL;
841         request->local_fileno = -1;
842         request->local_stream = NULL;
843         request->state = NEED_FETCH;
844         request->next = request_queue_head;
845         request_queue_head = request;
846
847         fill_active_slots();
848         step_active_slots();
849 }
850
851 static void add_send_request(struct object *obj, struct remote_lock *lock)
852 {
853         struct transfer_request *request = request_queue_head;
854         struct packed_git *target;
855
856         /* Keep locks active */
857         check_locks();
858
859         /*
860          * Don't push the object if it's known to exist on the remote
861          * or is already in the request queue
862          */
863         if (remote_dir_exists[obj->sha1[0]] == -1)
864                 get_remote_object_list(obj->sha1[0]);
865         if (obj->flags & (REMOTE | PUSHING))
866                 return;
867         target = find_sha1_pack(obj->sha1, remote->packs);
868         if (target) {
869                 obj->flags |= REMOTE;
870                 return;
871         }
872
873         obj->flags |= PUSHING;
874         request = xmalloc(sizeof(*request));
875         request->obj = obj;
876         request->url = NULL;
877         request->lock = lock;
878         request->headers = NULL;
879         request->local_fileno = -1;
880         request->local_stream = NULL;
881         request->state = NEED_PUSH;
882         request->next = request_queue_head;
883         request_queue_head = request;
884
885         fill_active_slots();
886         step_active_slots();
887 }
888
889 static int fetch_index(unsigned char *sha1)
890 {
891         char *hex = sha1_to_hex(sha1);
892         char *filename;
893         char *url;
894         char tmpfile[PATH_MAX];
895         long prev_posn = 0;
896         char range[RANGE_HEADER_SIZE];
897         struct curl_slist *range_header = NULL;
898
899         FILE *indexfile;
900         struct active_request_slot *slot;
901         struct slot_results results;
902
903         /* Don't use the index if the pack isn't there */
904         url = xmalloc(strlen(remote->url) + 65);
905         sprintf(url, "%s/objects/pack/pack-%s.pack", remote->url, hex);
906         slot = get_active_slot();
907         slot->results = &results;
908         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
909         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
910         if (start_active_slot(slot)) {
911                 run_active_slot(slot);
912                 if (results.curl_result != CURLE_OK) {
913                         free(url);
914                         return error("Unable to verify pack %s is available",
915                                      hex);
916                 }
917         } else {
918                 return error("Unable to start request");
919         }
920
921         if (has_pack_index(sha1))
922                 return 0;
923
924         if (push_verbosely)
925                 fprintf(stderr, "Getting index for pack %s\n", hex);
926         
927         sprintf(url, "%s/objects/pack/pack-%s.idx", remote->url, hex);
928         
929         filename = sha1_pack_index_name(sha1);
930         snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
931         indexfile = fopen(tmpfile, "a");
932         if (!indexfile)
933                 return error("Unable to open local file %s for pack index",
934                              filename);
935
936         slot = get_active_slot();
937         slot->results = &results;
938         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
939         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
940         curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
941         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
942         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
943         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
944         slot->local = indexfile;
945
946         /* If there is data present from a previous transfer attempt,
947            resume where it left off */
948         prev_posn = ftell(indexfile);
949         if (prev_posn>0) {
950                 if (push_verbosely)
951                         fprintf(stderr,
952                                 "Resuming fetch of index for pack %s at byte %ld\n",
953                                 hex, prev_posn);
954                 sprintf(range, "Range: bytes=%ld-", prev_posn);
955                 range_header = curl_slist_append(range_header, range);
956                 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
957         }
958
959         if (start_active_slot(slot)) {
960                 run_active_slot(slot);
961                 if (results.curl_result != CURLE_OK) {
962                         free(url);
963                         fclose(indexfile);
964                         return error("Unable to get pack index %s\n%s", url,
965                                      curl_errorstr);
966                 }
967         } else {
968                 free(url);
969                 fclose(indexfile);
970                 return error("Unable to start request");
971         }
972
973         free(url);
974         fclose(indexfile);
975
976         return move_temp_to_file(tmpfile, filename);
977 }
978
979 static int setup_index(unsigned char *sha1)
980 {
981         struct packed_git *new_pack;
982
983         if (fetch_index(sha1))
984                 return -1;
985
986         new_pack = parse_pack_index(sha1);
987         new_pack->next = remote->packs;
988         remote->packs = new_pack;
989         return 0;
990 }
991
992 static int fetch_indices(void)
993 {
994         unsigned char sha1[20];
995         char *url;
996         struct buffer buffer;
997         char *data;
998         int i = 0;
999
1000         struct active_request_slot *slot;
1001         struct slot_results results;
1002
1003         data = xmalloc(4096);
1004         memset(data, 0, 4096);
1005         buffer.size = 4096;
1006         buffer.posn = 0;
1007         buffer.buffer = data;
1008
1009         if (push_verbosely)
1010                 fprintf(stderr, "Getting pack list\n");
1011         
1012         url = xmalloc(strlen(remote->url) + 21);
1013         sprintf(url, "%s/objects/info/packs", remote->url);
1014
1015         slot = get_active_slot();
1016         slot->results = &results;
1017         curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
1018         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1019         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1020         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
1021         if (start_active_slot(slot)) {
1022                 run_active_slot(slot);
1023                 if (results.curl_result != CURLE_OK) {
1024                         free(buffer.buffer);
1025                         free(url);
1026                         if (results.http_code == 404)
1027                                 return 0;
1028                         else
1029                                 return error("%s", curl_errorstr);
1030                 }
1031         } else {
1032                 free(buffer.buffer);
1033                 free(url);
1034                 return error("Unable to start request");
1035         }
1036         free(url);
1037
1038         data = buffer.buffer;
1039         while (i < buffer.posn) {
1040                 switch (data[i]) {
1041                 case 'P':
1042                         i++;
1043                         if (i + 52 < buffer.posn &&
1044                             !strncmp(data + i, " pack-", 6) &&
1045                             !strncmp(data + i + 46, ".pack\n", 6)) {
1046                                 get_sha1_hex(data + i + 6, sha1);
1047                                 setup_index(sha1);
1048                                 i += 51;
1049                                 break;
1050                         }
1051                 default:
1052                         while (data[i] != '\n')
1053                                 i++;
1054                 }
1055                 i++;
1056         }
1057
1058         free(buffer.buffer);
1059         return 0;
1060 }
1061
1062 static inline int needs_quote(int ch)
1063 {
1064         switch (ch) {
1065         case '/': case '-': case '.':
1066         case 'A'...'Z': case 'a'...'z': case '0'...'9':
1067                 return 0;
1068         default:
1069                 return 1;
1070         }
1071 }
1072
1073 static inline int hex(int v)
1074 {
1075         if (v < 10) return '0' + v;
1076         else return 'A' + v - 10;
1077 }
1078
1079 static char *quote_ref_url(const char *base, const char *ref)
1080 {
1081         const char *cp;
1082         char *dp, *qref;
1083         int len, baselen, ch;
1084
1085         baselen = strlen(base);
1086         len = baselen + 1;
1087         for (cp = ref; (ch = *cp) != 0; cp++, len++)
1088                 if (needs_quote(ch))
1089                         len += 2; /* extra two hex plus replacement % */
1090         qref = xmalloc(len);
1091         memcpy(qref, base, baselen);
1092         for (cp = ref, dp = qref + baselen; (ch = *cp) != 0; cp++) {
1093                 if (needs_quote(ch)) {
1094                         *dp++ = '%';
1095                         *dp++ = hex((ch >> 4) & 0xF);
1096                         *dp++ = hex(ch & 0xF);
1097                 }
1098                 else
1099                         *dp++ = ch;
1100         }
1101         *dp = 0;
1102
1103         return qref;
1104 }
1105
1106 int fetch_ref(char *ref, unsigned char *sha1)
1107 {
1108         char *url;
1109         char hex[42];
1110         struct buffer buffer;
1111         char *base = remote->url;
1112         struct active_request_slot *slot;
1113         struct slot_results results;
1114         buffer.size = 41;
1115         buffer.posn = 0;
1116         buffer.buffer = hex;
1117         hex[41] = '\0';
1118
1119         url = quote_ref_url(base, ref);
1120         slot = get_active_slot();
1121         slot->results = &results;
1122         curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
1123         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1124         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
1125         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1126         if (start_active_slot(slot)) {
1127                 run_active_slot(slot);
1128                 if (results.curl_result != CURLE_OK)
1129                         return error("Couldn't get %s for %s\n%s",
1130                                      url, ref, curl_errorstr);
1131         } else {
1132                 return error("Unable to start request");
1133         }
1134
1135         hex[40] = '\0';
1136         get_sha1_hex(hex, sha1);
1137         return 0;
1138 }
1139
1140 static void one_remote_object(const char *hex)
1141 {
1142         unsigned char sha1[20];
1143         struct object *obj;
1144
1145         if (get_sha1_hex(hex, sha1) != 0)
1146                 return;
1147
1148         obj = lookup_object(sha1);
1149         if (!obj)
1150                 obj = parse_object(sha1);
1151
1152         /* Ignore remote objects that don't exist locally */
1153         if (!obj)
1154                 return;
1155
1156         obj->flags |= REMOTE;
1157         if (!object_list_contains(objects, obj))
1158                 add_object(obj, &objects, NULL, "");
1159 }
1160
1161 static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed)
1162 {
1163         int *lock_flags = (int *)ctx->userData;
1164
1165         if (tag_closed) {
1166                 if (!strcmp(ctx->name, DAV_CTX_LOCKENTRY)) {
1167                         if ((*lock_flags & DAV_PROP_LOCKEX) &&
1168                             (*lock_flags & DAV_PROP_LOCKWR)) {
1169                                 *lock_flags |= DAV_LOCK_OK;
1170                         }
1171                         *lock_flags &= DAV_LOCK_OK;
1172                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_WRITE)) {
1173                         *lock_flags |= DAV_PROP_LOCKWR;
1174                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_EXCLUSIVE)) {
1175                         *lock_flags |= DAV_PROP_LOCKEX;
1176                 }
1177         }
1178 }
1179
1180 static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
1181 {
1182         struct remote_lock *lock = (struct remote_lock *)ctx->userData;
1183
1184         if (tag_closed && ctx->cdata) {
1185                 if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
1186                         lock->owner = xmalloc(strlen(ctx->cdata) + 1);
1187                         strcpy(lock->owner, ctx->cdata);
1188                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
1189                         if (!strncmp(ctx->cdata, "Second-", 7))
1190                                 lock->timeout =
1191                                         strtol(ctx->cdata + 7, NULL, 10);
1192                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
1193                         if (!strncmp(ctx->cdata, "opaquelocktoken:", 16)) {
1194                                 lock->token = xmalloc(strlen(ctx->cdata) - 15);
1195                                 strcpy(lock->token, ctx->cdata + 16);
1196                         }
1197                 }
1198         }
1199 }
1200
1201 static void one_remote_ref(char *refname);
1202
1203 static void
1204 xml_start_tag(void *userData, const char *name, const char **atts)
1205 {
1206         struct xml_ctx *ctx = (struct xml_ctx *)userData;
1207         const char *c = index(name, ':');
1208         int new_len;
1209
1210         if (c == NULL)
1211                 c = name;
1212         else
1213                 c++;
1214
1215         new_len = strlen(ctx->name) + strlen(c) + 2;
1216
1217         if (new_len > ctx->len) {
1218                 ctx->name = xrealloc(ctx->name, new_len);
1219                 ctx->len = new_len;
1220         }
1221         strcat(ctx->name, ".");
1222         strcat(ctx->name, c);
1223
1224         if (ctx->cdata) {
1225                 free(ctx->cdata);
1226                 ctx->cdata = NULL;
1227         }
1228
1229         ctx->userFunc(ctx, 0);
1230 }
1231
1232 static void
1233 xml_end_tag(void *userData, const char *name)
1234 {
1235         struct xml_ctx *ctx = (struct xml_ctx *)userData;
1236         const char *c = index(name, ':');
1237         char *ep;
1238
1239         ctx->userFunc(ctx, 1);
1240
1241         if (c == NULL)
1242                 c = name;
1243         else
1244                 c++;
1245
1246         ep = ctx->name + strlen(ctx->name) - strlen(c) - 1;
1247         *ep = 0;
1248 }
1249
1250 static void
1251 xml_cdata(void *userData, const XML_Char *s, int len)
1252 {
1253         struct xml_ctx *ctx = (struct xml_ctx *)userData;
1254         if (ctx->cdata)
1255                 free(ctx->cdata);
1256         ctx->cdata = xcalloc(len+1, 1);
1257         strncpy(ctx->cdata, s, len);
1258 }
1259
1260 static struct remote_lock *lock_remote(char *path, long timeout)
1261 {
1262         struct active_request_slot *slot;
1263         struct slot_results results;
1264         struct buffer out_buffer;
1265         struct buffer in_buffer;
1266         char *out_data;
1267         char *in_data;
1268         char *url;
1269         char *ep;
1270         char timeout_header[25];
1271         struct remote_lock *lock = NULL;
1272         XML_Parser parser = XML_ParserCreate(NULL);
1273         enum XML_Status result;
1274         struct curl_slist *dav_headers = NULL;
1275         struct xml_ctx ctx;
1276
1277         url = xmalloc(strlen(remote->url) + strlen(path) + 1);
1278         sprintf(url, "%s%s", remote->url, path);
1279
1280         /* Make sure leading directories exist for the remote ref */
1281         ep = strchr(url + strlen(remote->url) + 11, '/');
1282         while (ep) {
1283                 *ep = 0;
1284                 slot = get_active_slot();
1285                 slot->results = &results;
1286                 curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
1287                 curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1288                 curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
1289                 curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1290                 if (start_active_slot(slot)) {
1291                         run_active_slot(slot);
1292                         if (results.curl_result != CURLE_OK &&
1293                             results.http_code != 405) {
1294                                 fprintf(stderr,
1295                                         "Unable to create branch path %s\n",
1296                                         url);
1297                                 free(url);
1298                                 return NULL;
1299                         }
1300                 } else {
1301                         fprintf(stderr, "Unable to start request\n");
1302                         free(url);
1303                         return NULL;
1304                 }
1305                 *ep = '/';
1306                 ep = strchr(ep + 1, '/');
1307         }
1308
1309         out_buffer.size = strlen(LOCK_REQUEST) + strlen(git_default_email) - 2;
1310         out_data = xmalloc(out_buffer.size + 1);
1311         snprintf(out_data, out_buffer.size + 1, LOCK_REQUEST, git_default_email);
1312         out_buffer.posn = 0;
1313         out_buffer.buffer = out_data;
1314
1315         in_buffer.size = 4096;
1316         in_data = xmalloc(in_buffer.size);
1317         in_buffer.posn = 0;
1318         in_buffer.buffer = in_data;
1319
1320         sprintf(timeout_header, "Timeout: Second-%ld", timeout);
1321         dav_headers = curl_slist_append(dav_headers, timeout_header);
1322         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1323
1324         slot = get_active_slot();
1325         slot->results = &results;
1326         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1327         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1328         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1329         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1330         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1331         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1332         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1333         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
1334         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1335
1336         lock = xcalloc(1, sizeof(*lock));
1337         lock->timeout = -1;
1338
1339         if (start_active_slot(slot)) {
1340                 run_active_slot(slot);
1341                 if (results.curl_result == CURLE_OK) {
1342                         ctx.name = xcalloc(10, 1);
1343                         ctx.len = 0;
1344                         ctx.cdata = NULL;
1345                         ctx.userFunc = handle_new_lock_ctx;
1346                         ctx.userData = lock;
1347                         XML_SetUserData(parser, &ctx);
1348                         XML_SetElementHandler(parser, xml_start_tag,
1349                                               xml_end_tag);
1350                         XML_SetCharacterDataHandler(parser, xml_cdata);
1351                         result = XML_Parse(parser, in_buffer.buffer,
1352                                            in_buffer.posn, 1);
1353                         free(ctx.name);
1354                         if (result != XML_STATUS_OK) {
1355                                 fprintf(stderr, "XML error: %s\n",
1356                                         XML_ErrorString(
1357                                                 XML_GetErrorCode(parser)));
1358                                 lock->timeout = -1;
1359                         }
1360                 }
1361         } else {
1362                 fprintf(stderr, "Unable to start request\n");
1363         }
1364
1365         curl_slist_free_all(dav_headers);
1366         free(out_data);
1367         free(in_data);
1368
1369         if (lock->token == NULL || lock->timeout <= 0) {
1370                 if (lock->token != NULL)
1371                         free(lock->token);
1372                 if (lock->owner != NULL)
1373                         free(lock->owner);
1374                 free(url);
1375                 free(lock);
1376                 lock = NULL;
1377         } else {
1378                 lock->url = url;
1379                 lock->start_time = time(NULL);
1380                 lock->next = remote->locks;
1381                 remote->locks = lock;
1382         }
1383
1384         return lock;
1385 }
1386
1387 static int unlock_remote(struct remote_lock *lock)
1388 {
1389         struct active_request_slot *slot;
1390         struct slot_results results;
1391         struct remote_lock *prev = remote->locks;
1392         char *lock_token_header;
1393         struct curl_slist *dav_headers = NULL;
1394         int rc = 0;
1395
1396         lock_token_header = xmalloc(strlen(lock->token) + 31);
1397         sprintf(lock_token_header, "Lock-Token: <opaquelocktoken:%s>",
1398                 lock->token);
1399         dav_headers = curl_slist_append(dav_headers, lock_token_header);
1400
1401         slot = get_active_slot();
1402         slot->results = &results;
1403         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1404         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
1405         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_UNLOCK);
1406         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1407
1408         if (start_active_slot(slot)) {
1409                 run_active_slot(slot);
1410                 if (results.curl_result == CURLE_OK)
1411                         rc = 1;
1412                 else
1413                         fprintf(stderr, "UNLOCK HTTP error %ld\n",
1414                                 results.http_code);
1415         } else {
1416                 fprintf(stderr, "Unable to start UNLOCK request\n");
1417         }
1418
1419         curl_slist_free_all(dav_headers);
1420         free(lock_token_header);
1421
1422         if (remote->locks == lock) {
1423                 remote->locks = lock->next;
1424         } else {
1425                 while (prev && prev->next != lock)
1426                         prev = prev->next;
1427                 if (prev)
1428                         prev->next = prev->next->next;
1429         }
1430
1431         if (lock->owner != NULL)
1432                 free(lock->owner);
1433         free(lock->url);
1434         free(lock->token);
1435         free(lock);
1436
1437         return rc;
1438 }
1439
1440 static void remote_ls(const char *path, int flags,
1441                       void (*userFunc)(struct remote_ls_ctx *ls),
1442                       void *userData);
1443
1444 static void process_ls_object(struct remote_ls_ctx *ls)
1445 {
1446         unsigned int *parent = (unsigned int *)ls->userData;
1447         char *path = ls->dentry_name;
1448         char *obj_hex;
1449
1450         if (!strcmp(ls->path, ls->dentry_name) && (ls->flags & IS_DIR)) {
1451                 remote_dir_exists[*parent] = 1;
1452                 return;
1453         }
1454
1455         if (strlen(path) != 49)
1456                 return;
1457         path += 8;
1458         obj_hex = xmalloc(strlen(path));
1459         strncpy(obj_hex, path, 2);
1460         strcpy(obj_hex + 2, path + 3);
1461         one_remote_object(obj_hex);
1462         free(obj_hex);
1463 }
1464
1465 static void process_ls_ref(struct remote_ls_ctx *ls)
1466 {
1467         if (!strcmp(ls->path, ls->dentry_name) && (ls->dentry_flags & IS_DIR)) {
1468                 fprintf(stderr, "  %s\n", ls->dentry_name);
1469                 return;
1470         }
1471
1472         if (!(ls->dentry_flags & IS_DIR))
1473                 one_remote_ref(ls->dentry_name);
1474 }
1475
1476 static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
1477 {
1478         struct remote_ls_ctx *ls = (struct remote_ls_ctx *)ctx->userData;
1479
1480         if (tag_closed) {
1481                 if (!strcmp(ctx->name, DAV_PROPFIND_RESP) && ls->dentry_name) {
1482                         if (ls->dentry_flags & IS_DIR) {
1483                                 if (ls->flags & PROCESS_DIRS) {
1484                                         ls->userFunc(ls);
1485                                 }
1486                                 if (strcmp(ls->dentry_name, ls->path) &&
1487                                     ls->flags & RECURSIVE) {
1488                                         remote_ls(ls->dentry_name,
1489                                                   ls->flags,
1490                                                   ls->userFunc,
1491                                                   ls->userData);
1492                                 }
1493                         } else if (ls->flags & PROCESS_FILES) {
1494                                 ls->userFunc(ls);
1495                         }
1496                 } else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
1497                         ls->dentry_name = xmalloc(strlen(ctx->cdata) -
1498                                                   remote->path_len + 1);
1499                         strcpy(ls->dentry_name, ctx->cdata + remote->path_len);
1500                 } else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
1501                         ls->dentry_flags |= IS_DIR;
1502                 }
1503         } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) {
1504                 if (ls->dentry_name) {
1505                         free(ls->dentry_name);
1506                 }
1507                 ls->dentry_name = NULL;
1508                 ls->dentry_flags = 0;
1509         }
1510 }
1511
1512 static void remote_ls(const char *path, int flags,
1513                       void (*userFunc)(struct remote_ls_ctx *ls),
1514                       void *userData)
1515 {
1516         char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
1517         struct active_request_slot *slot;
1518         struct slot_results results;
1519         struct buffer in_buffer;
1520         struct buffer out_buffer;
1521         char *in_data;
1522         char *out_data;
1523         XML_Parser parser = XML_ParserCreate(NULL);
1524         enum XML_Status result;
1525         struct curl_slist *dav_headers = NULL;
1526         struct xml_ctx ctx;
1527         struct remote_ls_ctx ls;
1528
1529         ls.flags = flags;
1530         ls.path = strdup(path);
1531         ls.dentry_name = NULL;
1532         ls.dentry_flags = 0;
1533         ls.userData = userData;
1534         ls.userFunc = userFunc;
1535
1536         sprintf(url, "%s%s", remote->url, path);
1537
1538         out_buffer.size = strlen(PROPFIND_ALL_REQUEST);
1539         out_data = xmalloc(out_buffer.size + 1);
1540         snprintf(out_data, out_buffer.size + 1, PROPFIND_ALL_REQUEST);
1541         out_buffer.posn = 0;
1542         out_buffer.buffer = out_data;
1543
1544         in_buffer.size = 4096;
1545         in_data = xmalloc(in_buffer.size);
1546         in_buffer.posn = 0;
1547         in_buffer.buffer = in_data;
1548
1549         dav_headers = curl_slist_append(dav_headers, "Depth: 1");
1550         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1551
1552         slot = get_active_slot();
1553         slot->results = &results;
1554         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1555         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1556         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1557         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1558         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1559         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1560         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1561         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
1562         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1563
1564         if (start_active_slot(slot)) {
1565                 run_active_slot(slot);
1566                 if (results.curl_result == CURLE_OK) {
1567                         ctx.name = xcalloc(10, 1);
1568                         ctx.len = 0;
1569                         ctx.cdata = NULL;
1570                         ctx.userFunc = handle_remote_ls_ctx;
1571                         ctx.userData = &ls;
1572                         XML_SetUserData(parser, &ctx);
1573                         XML_SetElementHandler(parser, xml_start_tag,
1574                                               xml_end_tag);
1575                         XML_SetCharacterDataHandler(parser, xml_cdata);
1576                         result = XML_Parse(parser, in_buffer.buffer,
1577                                            in_buffer.posn, 1);
1578                         free(ctx.name);
1579
1580                         if (result != XML_STATUS_OK) {
1581                                 fprintf(stderr, "XML error: %s\n",
1582                                         XML_ErrorString(
1583                                                 XML_GetErrorCode(parser)));
1584                         }
1585                 }
1586         } else {
1587                 fprintf(stderr, "Unable to start PROPFIND request\n");
1588         }
1589
1590         free(ls.path);
1591         free(url);
1592         free(out_data);
1593         free(in_buffer.buffer);
1594         curl_slist_free_all(dav_headers);
1595 }
1596
1597 static void get_remote_object_list(unsigned char parent)
1598 {
1599         char path[] = "objects/XX/";
1600         static const char hex[] = "0123456789abcdef";
1601         unsigned int val = parent;
1602
1603         path[8] = hex[val >> 4];
1604         path[9] = hex[val & 0xf];
1605         remote_dir_exists[val] = 0;
1606         remote_ls(path, (PROCESS_FILES | PROCESS_DIRS),
1607                   process_ls_object, &val);
1608 }
1609
1610 static int locking_available(void)
1611 {
1612         struct active_request_slot *slot;
1613         struct slot_results results;
1614         struct buffer in_buffer;
1615         struct buffer out_buffer;
1616         char *in_data;
1617         char *out_data;
1618         XML_Parser parser = XML_ParserCreate(NULL);
1619         enum XML_Status result;
1620         struct curl_slist *dav_headers = NULL;
1621         struct xml_ctx ctx;
1622         int lock_flags = 0;
1623
1624         out_buffer.size =
1625                 strlen(PROPFIND_SUPPORTEDLOCK_REQUEST) +
1626                 strlen(remote->url) - 2;
1627         out_data = xmalloc(out_buffer.size + 1);
1628         snprintf(out_data, out_buffer.size + 1,
1629                  PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);
1630         out_buffer.posn = 0;
1631         out_buffer.buffer = out_data;
1632
1633         in_buffer.size = 4096;
1634         in_data = xmalloc(in_buffer.size);
1635         in_buffer.posn = 0;
1636         in_buffer.buffer = in_data;
1637
1638         dav_headers = curl_slist_append(dav_headers, "Depth: 0");
1639         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1640
1641         slot = get_active_slot();
1642         slot->results = &results;
1643         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1644         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1645         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1646         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1647         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1648         curl_easy_setopt(slot->curl, CURLOPT_URL, remote->url);
1649         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1650         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
1651         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1652
1653         if (start_active_slot(slot)) {
1654                 run_active_slot(slot);
1655                 if (results.curl_result == CURLE_OK) {
1656                         ctx.name = xcalloc(10, 1);
1657                         ctx.len = 0;
1658                         ctx.cdata = NULL;
1659                         ctx.userFunc = handle_lockprop_ctx;
1660                         ctx.userData = &lock_flags;
1661                         XML_SetUserData(parser, &ctx);
1662                         XML_SetElementHandler(parser, xml_start_tag,
1663                                               xml_end_tag);
1664                         result = XML_Parse(parser, in_buffer.buffer,
1665                                            in_buffer.posn, 1);
1666                         free(ctx.name);
1667
1668                         if (result != XML_STATUS_OK) {
1669                                 fprintf(stderr, "XML error: %s\n",
1670                                         XML_ErrorString(
1671                                                 XML_GetErrorCode(parser)));
1672                                 lock_flags = 0;
1673                         }
1674                 }
1675         } else {
1676                 fprintf(stderr, "Unable to start request\n");
1677         }
1678
1679         free(out_data);
1680         free(in_buffer.buffer);
1681         curl_slist_free_all(dav_headers);
1682
1683         return lock_flags;
1684 }
1685
1686 static struct object_list **process_blob(struct blob *blob,
1687                                          struct object_list **p,
1688                                          struct name_path *path,
1689                                          const char *name)
1690 {
1691         struct object *obj = &blob->object;
1692
1693         obj->flags |= LOCAL;
1694
1695         if (obj->flags & (UNINTERESTING | SEEN))
1696                 return p;
1697
1698         obj->flags |= SEEN;
1699         return add_object(obj, p, path, name);
1700 }
1701
1702 static struct object_list **process_tree(struct tree *tree,
1703                                          struct object_list **p,
1704                                          struct name_path *path,
1705                                          const char *name)
1706 {
1707         struct object *obj = &tree->object;
1708         struct tree_entry_list *entry;
1709         struct name_path me;
1710
1711         obj->flags |= LOCAL;
1712
1713         if (obj->flags & (UNINTERESTING | SEEN))
1714                 return p;
1715         if (parse_tree(tree) < 0)
1716                 die("bad tree object %s", sha1_to_hex(obj->sha1));
1717
1718         obj->flags |= SEEN;
1719         p = add_object(obj, p, NULL, name);
1720         me.up = path;
1721         me.elem = name;
1722         me.elem_len = strlen(name);
1723         entry = tree->entries;
1724         tree->entries = NULL;
1725         while (entry) {
1726                 struct tree_entry_list *next = entry->next;
1727                 if (entry->directory)
1728                         p = process_tree(entry->item.tree, p, &me, entry->name);
1729                 else
1730                         p = process_blob(entry->item.blob, p, &me, entry->name);
1731                 free(entry);
1732                 entry = next;
1733         }
1734         return p;
1735 }
1736
1737 static void get_delta(struct rev_info *revs, struct remote_lock *lock)
1738 {
1739         struct commit *commit;
1740         struct object_list **p = &objects, *pending;
1741
1742         while ((commit = get_revision(revs)) != NULL) {
1743                 p = process_tree(commit->tree, p, NULL, "");
1744                 commit->object.flags |= LOCAL;
1745                 if (!(commit->object.flags & UNINTERESTING))
1746                         add_send_request(&commit->object, lock);
1747         }
1748
1749         for (pending = revs->pending_objects; pending; pending = pending->next) {
1750                 struct object *obj = pending->item;
1751                 const char *name = pending->name;
1752
1753                 if (obj->flags & (UNINTERESTING | SEEN))
1754                         continue;
1755                 if (obj->type == tag_type) {
1756                         obj->flags |= SEEN;
1757                         p = add_object(obj, p, NULL, name);
1758                         continue;
1759                 }
1760                 if (obj->type == tree_type) {
1761                         p = process_tree((struct tree *)obj, p, NULL, name);
1762                         continue;
1763                 }
1764                 if (obj->type == blob_type) {
1765                         p = process_blob((struct blob *)obj, p, NULL, name);
1766                         continue;
1767                 }
1768                 die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
1769         }
1770
1771         while (objects) {
1772                 if (!(objects->item->flags & UNINTERESTING))
1773                         add_send_request(objects->item, lock);
1774                 objects = objects->next;
1775         }
1776 }
1777
1778 static int update_remote(unsigned char *sha1, struct remote_lock *lock)
1779 {
1780         struct active_request_slot *slot;
1781         struct slot_results results;
1782         char *out_data;
1783         char *if_header;
1784         struct buffer out_buffer;
1785         struct curl_slist *dav_headers = NULL;
1786         int i;
1787
1788         if_header = xmalloc(strlen(lock->token) + 25);
1789         sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
1790         dav_headers = curl_slist_append(dav_headers, if_header);
1791
1792         out_buffer.size = 41;
1793         out_data = xmalloc(out_buffer.size + 1);
1794         i = snprintf(out_data, out_buffer.size + 1, "%s\n", sha1_to_hex(sha1));
1795         if (i != out_buffer.size) {
1796                 fprintf(stderr, "Unable to initialize PUT request body\n");
1797                 return 0;
1798         }
1799         out_buffer.posn = 0;
1800         out_buffer.buffer = out_data;
1801
1802         slot = get_active_slot();
1803         slot->results = &results;
1804         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1805         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);
1806         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1807         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1808         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
1809         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1810         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1811         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
1812         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
1813
1814         if (start_active_slot(slot)) {
1815                 run_active_slot(slot);
1816                 free(out_data);
1817                 free(if_header);
1818                 if (results.curl_result != CURLE_OK) {
1819                         fprintf(stderr,
1820                                 "PUT error: curl result=%d, HTTP code=%ld\n",
1821                                 results.curl_result, results.http_code);
1822                         /* We should attempt recovery? */
1823                         return 0;
1824                 }
1825         } else {
1826                 free(out_data);
1827                 free(if_header);
1828                 fprintf(stderr, "Unable to start PUT request\n");
1829                 return 0;
1830         }
1831
1832         return 1;
1833 }
1834
1835 static struct ref *local_refs, **local_tail;
1836 static struct ref *remote_refs, **remote_tail;
1837
1838 static int one_local_ref(const char *refname, const unsigned char *sha1)
1839 {
1840         struct ref *ref;
1841         int len = strlen(refname) + 1;
1842         ref = xcalloc(1, sizeof(*ref) + len);
1843         memcpy(ref->new_sha1, sha1, 20);
1844         memcpy(ref->name, refname, len);
1845         *local_tail = ref;
1846         local_tail = &ref->next;
1847         return 0;
1848 }
1849
1850 static void one_remote_ref(char *refname)
1851 {
1852         struct ref *ref;
1853         unsigned char remote_sha1[20];
1854         struct object *obj;
1855
1856         if (fetch_ref(refname, remote_sha1) != 0) {
1857                 fprintf(stderr,
1858                         "Unable to fetch ref %s from %s\n",
1859                         refname, remote->url);
1860                 return;
1861         }
1862
1863         /*
1864          * Fetch a copy of the object if it doesn't exist locally - it
1865          * may be required for updating server info later.
1866          */
1867         if (remote->can_update_info_refs && !has_sha1_file(remote_sha1)) {
1868                 obj = lookup_unknown_object(remote_sha1);
1869                 if (obj) {
1870                         fprintf(stderr, "  fetch %s for %s\n",
1871                                 sha1_to_hex(remote_sha1), refname);
1872                         add_fetch_request(obj);
1873                 }
1874         }
1875
1876         int len = strlen(refname) + 1;
1877         ref = xcalloc(1, sizeof(*ref) + len);
1878         memcpy(ref->old_sha1, remote_sha1, 20);
1879         memcpy(ref->name, refname, len);
1880         *remote_tail = ref;
1881         remote_tail = &ref->next;
1882 }
1883
1884 static void get_local_heads(void)
1885 {
1886         local_tail = &local_refs;
1887         for_each_ref(one_local_ref);
1888 }
1889
1890 static void get_dav_remote_heads(void)
1891 {
1892         remote_tail = &remote_refs;
1893         remote_ls("refs/", (PROCESS_FILES | PROCESS_DIRS | RECURSIVE), process_ls_ref, NULL);
1894 }
1895
1896 static int is_zero_sha1(const unsigned char *sha1)
1897 {
1898         int i;
1899
1900         for (i = 0; i < 20; i++) {
1901                 if (*sha1++)
1902                         return 0;
1903         }
1904         return 1;
1905 }
1906
1907 static void unmark_and_free(struct commit_list *list, unsigned int mark)
1908 {
1909         while (list) {
1910                 struct commit_list *temp = list;
1911                 temp->item->object.flags &= ~mark;
1912                 list = temp->next;
1913                 free(temp);
1914         }
1915 }
1916
1917 static int ref_newer(const unsigned char *new_sha1,
1918                      const unsigned char *old_sha1)
1919 {
1920         struct object *o;
1921         struct commit *old, *new;
1922         struct commit_list *list, *used;
1923         int found = 0;
1924
1925         /* Both new and old must be commit-ish and new is descendant of
1926          * old.  Otherwise we require --force.
1927          */
1928         o = deref_tag(parse_object(old_sha1), NULL, 0);
1929         if (!o || o->type != commit_type)
1930                 return 0;
1931         old = (struct commit *) o;
1932
1933         o = deref_tag(parse_object(new_sha1), NULL, 0);
1934         if (!o || o->type != commit_type)
1935                 return 0;
1936         new = (struct commit *) o;
1937
1938         if (parse_commit(new) < 0)
1939                 return 0;
1940
1941         used = list = NULL;
1942         commit_list_insert(new, &list);
1943         while (list) {
1944                 new = pop_most_recent_commit(&list, TMP_MARK);
1945                 commit_list_insert(new, &used);
1946                 if (new == old) {
1947                         found = 1;
1948                         break;
1949                 }
1950         }
1951         unmark_and_free(list, TMP_MARK);
1952         unmark_and_free(used, TMP_MARK);
1953         return found;
1954 }
1955
1956 static void mark_edge_parents_uninteresting(struct commit *commit)
1957 {
1958         struct commit_list *parents;
1959
1960         for (parents = commit->parents; parents; parents = parents->next) {
1961                 struct commit *parent = parents->item;
1962                 if (!(parent->object.flags & UNINTERESTING))
1963                         continue;
1964                 mark_tree_uninteresting(parent->tree);
1965         }
1966 }
1967
1968 static void mark_edges_uninteresting(struct commit_list *list)
1969 {
1970         for ( ; list; list = list->next) {
1971                 struct commit *commit = list->item;
1972
1973                 if (commit->object.flags & UNINTERESTING) {
1974                         mark_tree_uninteresting(commit->tree);
1975                         continue;
1976                 }
1977                 mark_edge_parents_uninteresting(commit);
1978         }
1979 }
1980
1981 static void add_remote_info_ref(struct remote_ls_ctx *ls)
1982 {
1983         struct buffer *buf = (struct buffer *)ls->userData;
1984         unsigned char remote_sha1[20];
1985         struct object *o;
1986         int len;
1987         char *ref_info;
1988
1989         if (fetch_ref(ls->dentry_name, remote_sha1) != 0) {
1990                 fprintf(stderr,
1991                         "Unable to fetch ref %s from %s\n",
1992                         ls->dentry_name, remote->url);
1993                 aborted = 1;
1994                 return;
1995         }
1996
1997         o = parse_object(remote_sha1);
1998         if (!o) {
1999                 fprintf(stderr,
2000                         "Unable to parse object %s for remote ref %s\n",
2001                         sha1_to_hex(remote_sha1), ls->dentry_name);
2002                 aborted = 1;
2003                 return;
2004         }
2005
2006         len = strlen(ls->dentry_name) + 42;
2007         ref_info = xcalloc(len + 1, 1);
2008         sprintf(ref_info, "%s   %s\n",
2009                 sha1_to_hex(remote_sha1), ls->dentry_name);
2010         fwrite_buffer(ref_info, 1, len, buf);
2011         free(ref_info);
2012
2013         if (o->type == tag_type) {
2014                 o = deref_tag(o, ls->dentry_name, 0);
2015                 if (o) {
2016                         len = strlen(ls->dentry_name) + 45;
2017                         ref_info = xcalloc(len + 1, 1);
2018                         sprintf(ref_info, "%s   %s^{}\n",
2019                                 sha1_to_hex(o->sha1), ls->dentry_name);
2020                         fwrite_buffer(ref_info, 1, len, buf);
2021                         free(ref_info);
2022                 }
2023         }
2024 }
2025
2026 static void update_remote_info_refs(struct remote_lock *lock)
2027 {
2028         struct buffer buffer;
2029         struct active_request_slot *slot;
2030         struct slot_results results;
2031         char *if_header;
2032         struct curl_slist *dav_headers = NULL;
2033
2034         buffer.buffer = xmalloc(4096);
2035         memset(buffer.buffer, 0, 4096);
2036         buffer.size = 4096;
2037         buffer.posn = 0;
2038         remote_ls("refs/", (PROCESS_FILES | RECURSIVE),
2039                   add_remote_info_ref, &buffer);
2040         if (!aborted) {
2041                 if_header = xmalloc(strlen(lock->token) + 25);
2042                 sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
2043                 dav_headers = curl_slist_append(dav_headers, if_header);
2044
2045                 slot = get_active_slot();
2046                 slot->results = &results;
2047                 curl_easy_setopt(slot->curl, CURLOPT_INFILE, &buffer);
2048                 curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.posn);
2049                 curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
2050                 curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
2051                 curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
2052                 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
2053                 curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
2054                 curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
2055                 curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
2056
2057                 buffer.posn = 0;
2058
2059                 if (start_active_slot(slot)) {
2060                         run_active_slot(slot);
2061                         if (results.curl_result != CURLE_OK) {
2062                                 fprintf(stderr,
2063                                         "PUT error: curl result=%d, HTTP code=%ld\n",
2064                                         results.curl_result, results.http_code);
2065                         }
2066                 }
2067                 free(if_header);
2068         }
2069         free(buffer.buffer);
2070 }
2071
2072 static int remote_exists(const char *path)
2073 {
2074         char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
2075         struct active_request_slot *slot;
2076         struct slot_results results;
2077
2078         sprintf(url, "%s%s", remote->url, path);
2079
2080         slot = get_active_slot();
2081         slot->results = &results;
2082         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
2083         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
2084
2085         if (start_active_slot(slot)) {
2086                 run_active_slot(slot);
2087                 if (results.http_code == 404)
2088                         return 0;
2089                 else if (results.curl_result == CURLE_OK)
2090                         return 1;
2091                 else
2092                         fprintf(stderr, "HEAD HTTP error %ld\n", results.http_code);
2093         } else {
2094                 fprintf(stderr, "Unable to start HEAD request\n");
2095         }
2096
2097         return -1;
2098 }
2099
2100 int main(int argc, char **argv)
2101 {
2102         struct transfer_request *request;
2103         struct transfer_request *next_request;
2104         int nr_refspec = 0;
2105         char **refspec = NULL;
2106         struct remote_lock *ref_lock = NULL;
2107         struct remote_lock *info_ref_lock = NULL;
2108         struct rev_info revs;
2109         int rc = 0;
2110         int i;
2111
2112         setup_git_directory();
2113         setup_ident();
2114
2115         remote = xcalloc(sizeof(*remote), 1);
2116
2117         argv++;
2118         for (i = 1; i < argc; i++, argv++) {
2119                 char *arg = *argv;
2120
2121                 if (*arg == '-') {
2122                         if (!strcmp(arg, "--all")) {
2123                                 push_all = 1;
2124                                 continue;
2125                         }
2126                         if (!strcmp(arg, "--force")) {
2127                                 force_all = 1;
2128                                 continue;
2129                         }
2130                         if (!strcmp(arg, "--verbose")) {
2131                                 push_verbosely = 1;
2132                                 continue;
2133                         }
2134                         usage(http_push_usage);
2135                 }
2136                 if (!remote->url) {
2137                         remote->url = arg;
2138                         char *path = strstr(arg, "//");
2139                         if (path) {
2140                                 path = index(path+2, '/');
2141                                 if (path)
2142                                         remote->path_len = strlen(path);
2143                         }
2144                         continue;
2145                 }
2146                 refspec = argv;
2147                 nr_refspec = argc - i;
2148                 break;
2149         }
2150
2151         if (!remote->url)
2152                 usage(http_push_usage);
2153
2154         memset(remote_dir_exists, -1, 256);
2155
2156         http_init();
2157
2158         no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
2159         default_headers = curl_slist_append(default_headers, "Range:");
2160         default_headers = curl_slist_append(default_headers, "Destination:");
2161         default_headers = curl_slist_append(default_headers, "If:");
2162         default_headers = curl_slist_append(default_headers,
2163                                             "Pragma: no-cache");
2164
2165         /* Verify DAV compliance/lock support */
2166         if (!locking_available()) {
2167                 fprintf(stderr, "Error: no DAV locking support on remote repo %s\n", remote->url);
2168                 rc = 1;
2169                 goto cleanup;
2170         }
2171
2172         /* Check whether the remote has server info files */
2173         remote->can_update_info_refs = 0;
2174         remote->has_info_refs = remote_exists("info/refs");
2175         remote->has_info_packs = remote_exists("objects/info/packs");
2176         if (remote->has_info_refs) {
2177                 info_ref_lock = lock_remote("info/refs", LOCK_TIME);
2178                 if (info_ref_lock)
2179                         remote->can_update_info_refs = 1;
2180         }
2181         if (remote->has_info_packs)
2182                 fetch_indices();
2183
2184         /* Get a list of all local and remote heads to validate refspecs */
2185         get_local_heads();
2186         fprintf(stderr, "Fetching remote heads...\n");
2187         get_dav_remote_heads();
2188
2189         /* match them up */
2190         if (!remote_tail)
2191                 remote_tail = &remote_refs;
2192         if (match_refs(local_refs, remote_refs, &remote_tail,
2193                        nr_refspec, refspec, push_all))
2194                 return -1;
2195         if (!remote_refs) {
2196                 fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
2197                 return 0;
2198         }
2199
2200         int ret = 0;
2201         int new_refs = 0;
2202         struct ref *ref;
2203         for (ref = remote_refs; ref; ref = ref->next) {
2204                 char old_hex[60], *new_hex;
2205                 if (!ref->peer_ref)
2206                         continue;
2207                 if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) {
2208                         if (push_verbosely || 1)
2209                                 fprintf(stderr, "'%s': up-to-date\n", ref->name);
2210                         continue;
2211                 }
2212
2213                 if (!force_all &&
2214                     !is_zero_sha1(ref->old_sha1) &&
2215                     !ref->force) {
2216                         if (!has_sha1_file(ref->old_sha1) ||
2217                             !ref_newer(ref->peer_ref->new_sha1,
2218                                        ref->old_sha1)) {
2219                                 /* We do not have the remote ref, or
2220                                  * we know that the remote ref is not
2221                                  * an ancestor of what we are trying to
2222                                  * push.  Either way this can be losing
2223                                  * commits at the remote end and likely
2224                                  * we were not up to date to begin with.
2225                                  */
2226                                 error("remote '%s' is not a strict "
2227                                       "subset of local ref '%s'. "
2228                                       "maybe you are not up-to-date and "
2229                                       "need to pull first?",
2230                                       ref->name,
2231                                       ref->peer_ref->name);
2232                                 ret = -2;
2233                                 continue;
2234                         }
2235                 }
2236                 memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
2237                 if (is_zero_sha1(ref->new_sha1)) {
2238                         error("cannot happen anymore");
2239                         ret = -3;
2240                         continue;
2241                 }
2242                 new_refs++;
2243                 strcpy(old_hex, sha1_to_hex(ref->old_sha1));
2244                 new_hex = sha1_to_hex(ref->new_sha1);
2245
2246                 fprintf(stderr, "updating '%s'", ref->name);
2247                 if (strcmp(ref->name, ref->peer_ref->name))
2248                         fprintf(stderr, " using '%s'", ref->peer_ref->name);
2249                 fprintf(stderr, "\n  from %s\n  to   %s\n", old_hex, new_hex);
2250
2251
2252                 /* Lock remote branch ref */
2253                 ref_lock = lock_remote(ref->name, LOCK_TIME);
2254                 if (ref_lock == NULL) {
2255                         fprintf(stderr, "Unable to lock remote branch %s\n",
2256                                 ref->name);
2257                         rc = 1;
2258                         continue;
2259                 }
2260
2261                 /* Set up revision info for this refspec */
2262                 const char *commit_argv[4];
2263                 int commit_argc = 3;
2264                 char *new_sha1_hex = strdup(sha1_to_hex(ref->new_sha1));
2265                 char *old_sha1_hex = NULL;
2266                 commit_argv[1] = "--objects";
2267                 commit_argv[2] = new_sha1_hex;
2268                 if (!push_all && !is_zero_sha1(ref->old_sha1)) {
2269                         old_sha1_hex = xmalloc(42);
2270                         sprintf(old_sha1_hex, "^%s",
2271                                 sha1_to_hex(ref->old_sha1));
2272                         commit_argv[3] = old_sha1_hex;
2273                         commit_argc++;
2274                 }
2275                 setup_revisions(commit_argc, commit_argv, &revs, NULL);
2276                 free(new_sha1_hex);
2277                 if (old_sha1_hex) {
2278                         free(old_sha1_hex);
2279                         commit_argv[1] = NULL;
2280                 }
2281
2282                 /* Generate a list of objects that need to be pushed */
2283                 pushing = 0;
2284                 prepare_revision_walk(&revs);
2285                 mark_edges_uninteresting(revs.commits);
2286                 get_delta(&revs, ref_lock);
2287                 finish_all_active_slots();
2288
2289                 /* Push missing objects to remote, this would be a
2290                    convenient time to pack them first if appropriate. */
2291                 pushing = 1;
2292                 fill_active_slots();
2293                 finish_all_active_slots();
2294
2295                 /* Update the remote branch if all went well */
2296                 if (aborted || !update_remote(ref->new_sha1, ref_lock)) {
2297                         rc = 1;
2298                         goto unlock;
2299                 }
2300
2301         unlock:
2302                 if (!rc)
2303                         fprintf(stderr, "    done\n");
2304                 unlock_remote(ref_lock);
2305                 check_locks();
2306         }
2307
2308         /* Update remote server info if appropriate */
2309         if (remote->has_info_refs && new_refs) {
2310                 if (info_ref_lock && remote->can_update_info_refs) {
2311                         fprintf(stderr, "Updating remote server info\n");
2312                         update_remote_info_refs(info_ref_lock);
2313                 } else {
2314                         fprintf(stderr, "Unable to update server info\n");
2315                 }
2316         }
2317         if (info_ref_lock)
2318                 unlock_remote(info_ref_lock);
2319
2320  cleanup:
2321         free(remote);
2322
2323         curl_slist_free_all(no_pragma_header);
2324         curl_slist_free_all(default_headers);
2325
2326         http_cleanup();
2327
2328         request = request_queue_head;
2329         while (request != NULL) {
2330                 next_request = request->next;
2331                 release_request(request);
2332                 request = next_request;
2333         }
2334
2335         return rc;
2336 }