Merge branch 'mg/http-auth'
authorJunio C Hamano <gitster@pobox.com>
Thu, 26 Mar 2009 07:27:59 +0000 (00:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 26 Mar 2009 07:27:59 +0000 (00:27 -0700)
* mg/http-auth:
http-push.c: use a faux remote to pass to http_init
Do not name "repo" struct "remote" in push_http.c
http.c: CURLOPT_NETRC_OPTIONAL is not available in ancient versions of cURL
http authentication via prompts
http_init(): Fix config file parsing
http.c: style cleanups

Conflicts:
http-push.c

1  2 
http-push.c
diff --combined http-push.c
index e6bd01a516082985637eba3eaaab629e5ab5fef8,962934858e93422f102ff869dd40730709d5824a..6ce5a1d550d4cf781673c62599bd681fc5e318b5
@@@ -97,7 -97,7 +97,7 @@@ struct rep
        struct remote_lock *locks;
  };
  
- static struct repo *remote;
+ static struct repo *repo;
  
  enum transfer_state {
        NEED_FETCH,
@@@ -324,7 -324,7 +324,7 @@@ static void start_fetch_loose(struct tr
  
        git_SHA1_Init(&request->c);
  
-       url = get_remote_object_url(remote->url, hex, 0);
+       url = get_remote_object_url(repo->url, hex, 0);
        request->url = xstrdup(url);
  
        /* If a previous temp file is present, process what was already
        request->state = RUN_FETCH_LOOSE;
        if (!start_active_slot(slot)) {
                fprintf(stderr, "Unable to start GET request\n");
-               remote->can_update_info_refs = 0;
+               repo->can_update_info_refs = 0;
                release_request(request);
        }
  }
@@@ -399,7 -399,7 +399,7 @@@ static void start_mkcol(struct transfer
        char *hex = sha1_to_hex(request->obj->sha1);
        struct active_request_slot *slot;
  
-       request->url = get_remote_object_url(remote->url, hex, 1);
+       request->url = get_remote_object_url(repo->url, hex, 1);
  
        slot = get_active_slot();
        slot->callback_func = process_response;
@@@ -434,10 -434,10 +434,10 @@@ static void start_fetch_packed(struct t
        struct transfer_request *check_request = request_queue_head;
        struct active_request_slot *slot;
  
-       target = find_sha1_pack(request->obj->sha1, remote->packs);
+       target = find_sha1_pack(request->obj->sha1, repo->packs);
        if (!target) {
                fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", sha1_to_hex(request->obj->sha1));
-               remote->can_update_info_refs = 0;
+               repo->can_update_info_refs = 0;
                release_request(request);
                return;
        }
        snprintf(request->tmpfile, sizeof(request->tmpfile),
                 "%s.temp", filename);
  
-       url = xmalloc(strlen(remote->url) + 64);
+       url = xmalloc(strlen(repo->url) + 64);
        sprintf(url, "%sobjects/pack/pack-%s.pack",
-               remote->url, sha1_to_hex(target->sha1));
+               repo->url, sha1_to_hex(target->sha1));
  
        /* Make sure there isn't another open request for this pack */
        while (check_request) {
        if (!packfile) {
                fprintf(stderr, "Unable to open local file %s for pack",
                        request->tmpfile);
-               remote->can_update_info_refs = 0;
+               repo->can_update_info_refs = 0;
                free(url);
                return;
        }
        request->state = RUN_FETCH_PACKED;
        if (!start_active_slot(slot)) {
                fprintf(stderr, "Unable to start GET request\n");
-               remote->can_update_info_refs = 0;
+               repo->can_update_info_refs = 0;
                release_request(request);
        }
  }
@@@ -554,10 -554,10 +554,10 @@@ static void start_put(struct transfer_r
        request->buffer.buf.len = stream.total_out;
  
        strbuf_addstr(&buf, "Destination: ");
-       append_remote_object_url(&buf, remote->url, hex, 0);
+       append_remote_object_url(&buf, repo->url, hex, 0);
        request->dest = strbuf_detach(&buf, NULL);
  
-       append_remote_object_url(&buf, remote->url, hex, 0);
+       append_remote_object_url(&buf, repo->url, hex, 0);
        strbuf_add(&buf, request->lock->tmpfile_suffix, 41);
        request->url = strbuf_detach(&buf, NULL);
  
@@@ -648,7 -648,7 +648,7 @@@ static int refresh_lock(struct remote_l
  
  static void check_locks(void)
  {
-       struct remote_lock *lock = remote->locks;
+       struct remote_lock *lock = repo->locks;
        time_t current_time = time(NULL);
        int time_remaining;
  
@@@ -759,7 -759,7 +759,7 @@@ static void finish_request(struct trans
                        }
                } else {
                        if (request->http_code == 416)
 -                              fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n");
 +                              warning("requested range invalid; we may already have all the data.");
  
                        git_inflate_end(&request->stream);
                        git_SHA1_Final(request->real_sha1, &request->c);
                if (request->curl_result != CURLE_OK) {
                        fprintf(stderr, "Unable to get pack file %s\n%s",
                                request->url, curl_errorstr);
-                       remote->can_update_info_refs = 0;
+                       repo->can_update_info_refs = 0;
                } else {
                        off_t pack_size = ftell(request->local_stream);
  
                                               request->filename)) {
                                target = (struct packed_git *)request->userData;
                                target->pack_size = pack_size;
-                               lst = &remote->packs;
+                               lst = &repo->packs;
                                while (*lst != target)
                                        lst = &((*lst)->next);
                                *lst = (*lst)->next;
                                if (!verify_pack(target))
                                        install_packed_git(target);
                                else
-                                       remote->can_update_info_refs = 0;
+                                       repo->can_update_info_refs = 0;
                        }
                }
                release_request(request);
  #ifdef USE_CURL_MULTI
  static int fill_active_slot(void *unused)
  {
 -      struct transfer_request *request = request_queue_head;
 +      struct transfer_request *request;
  
        if (aborted)
                return 0;
@@@ -889,7 -889,7 +889,7 @@@ static int add_send_request(struct obje
                get_remote_object_list(obj->sha1[0]);
        if (obj->flags & (REMOTE | PUSHING))
                return 0;
-       target = find_sha1_pack(obj->sha1, remote->packs);
+       target = find_sha1_pack(obj->sha1, repo->packs);
        if (target) {
                obj->flags |= REMOTE;
                return 0;
@@@ -930,8 -930,8 +930,8 @@@ static int fetch_index(unsigned char *s
        struct slot_results results;
  
        /* Don't use the index if the pack isn't there */
-       url = xmalloc(strlen(remote->url) + 64);
-       sprintf(url, "%sobjects/pack/pack-%s.pack", remote->url, hex);
+       url = xmalloc(strlen(repo->url) + 64);
+       sprintf(url, "%sobjects/pack/pack-%s.pack", repo->url, hex);
        slot = get_active_slot();
        slot->results = &results;
        curl_easy_setopt(slot->curl, CURLOPT_URL, url);
        if (push_verbosely)
                fprintf(stderr, "Getting index for pack %s\n", hex);
  
-       sprintf(url, "%sobjects/pack/pack-%s.idx", remote->url, hex);
+       sprintf(url, "%sobjects/pack/pack-%s.idx", repo->url, hex);
  
        filename = sha1_pack_index_name(sha1);
        snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
@@@ -1018,8 -1018,8 +1018,8 @@@ static int setup_index(unsigned char *s
                return -1;
  
        new_pack = parse_pack_index(sha1);
-       new_pack->next = remote->packs;
-       remote->packs = new_pack;
+       new_pack->next = repo->packs;
+       repo->packs = new_pack;
        return 0;
  }
  
@@@ -1037,8 -1037,8 +1037,8 @@@ static int fetch_indices(void
        if (push_verbosely)
                fprintf(stderr, "Getting pack list\n");
  
-       url = xmalloc(strlen(remote->url) + 20);
-       sprintf(url, "%sobjects/info/packs", remote->url);
+       url = xmalloc(strlen(repo->url) + 20);
+       sprintf(url, "%sobjects/info/packs", repo->url);
  
        slot = get_active_slot();
        slot->results = &results;
@@@ -1223,11 -1223,11 +1223,11 @@@ static struct remote_lock *lock_remote(
        struct curl_slist *dav_headers = NULL;
        struct xml_ctx ctx;
  
-       url = xmalloc(strlen(remote->url) + strlen(path) + 1);
-       sprintf(url, "%s%s", remote->url, path);
+       url = xmalloc(strlen(repo->url) + strlen(path) + 1);
+       sprintf(url, "%s%s", repo->url, path);
  
        /* Make sure leading directories exist for the remote ref */
-       ep = strchr(url + strlen(remote->url) + 1, '/');
+       ep = strchr(url + strlen(repo->url) + 1, '/');
        while (ep) {
                char saved_character = ep[1];
                ep[1] = '\0';
        } else {
                lock->url = url;
                lock->start_time = time(NULL);
-               lock->next = remote->locks;
-               remote->locks = lock;
+               lock->next = repo->locks;
+               repo->locks = lock;
        }
  
        return lock;
@@@ -1330,7 -1330,7 +1330,7 @@@ static int unlock_remote(struct remote_
  {
        struct active_request_slot *slot;
        struct slot_results results;
-       struct remote_lock *prev = remote->locks;
+       struct remote_lock *prev = repo->locks;
        struct curl_slist *dav_headers;
        int rc = 0;
  
  
        curl_slist_free_all(dav_headers);
  
-       if (remote->locks == lock) {
-               remote->locks = lock->next;
+       if (repo->locks == lock) {
+               repo->locks = lock->next;
        } else {
                while (prev && prev->next != lock)
                        prev = prev->next;
  
  static void remove_locks(void)
  {
-       struct remote_lock *lock = remote->locks;
+       struct remote_lock *lock = repo->locks;
  
        fprintf(stderr, "Removing remote locks...\n");
        while (lock) {
@@@ -1457,7 -1457,7 +1457,7 @@@ static void handle_remote_ls_ctx(struc
                                }
                        }
                        if (path) {
-                               path += remote->path_len;
+                               path += repo->path_len;
                                ls->dentry_name = xstrdup(path);
                        }
                } else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
@@@ -1480,7 -1480,7 +1480,7 @@@ static void remote_ls(const char *path
                      void (*userFunc)(struct remote_ls_ctx *ls),
                      void *userData)
  {
-       char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
+       char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
        struct active_request_slot *slot;
        struct slot_results results;
        struct strbuf in_buffer = STRBUF_INIT;
        ls.userData = userData;
        ls.userFunc = userFunc;
  
-       sprintf(url, "%s%s", remote->url, path);
+       sprintf(url, "%s%s", repo->url, path);
  
        strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);
  
@@@ -1574,7 -1574,7 +1574,7 @@@ static int locking_available(void
        struct xml_ctx ctx;
        int lock_flags = 0;
  
-       strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);
+       strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, repo->url);
  
        dav_headers = curl_slist_append(dav_headers, "Depth: 0");
        dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
        curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
        curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
        curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
-       curl_easy_setopt(slot->curl, CURLOPT_URL, remote->url);
+       curl_easy_setopt(slot->curl, CURLOPT_URL, repo->url);
        curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
        curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
                        }
                        XML_ParserFree(parser);
                        if (!lock_flags)
 -                              error("Error: no DAV locking support on %s",
 +                              error("no DAV locking support on %s",
-                                     remote->url);
+                                     repo->url);
  
                } else {
                        error("Cannot access URL %s, return code %d",
-                             remote->url, results.curl_result);
+                             repo->url, results.curl_result);
                        lock_flags = 0;
                }
        } else {
-               error("Unable to start PROPFIND request on %s", remote->url);
+               error("Unable to start PROPFIND request on %s", repo->url);
        }
  
        strbuf_release(&out_buffer.buf);
@@@ -1792,8 -1792,21 +1792,8 @@@ static int update_remote(unsigned char 
        return 1;
  }
  
 -static struct ref *local_refs, **local_tail;
  static struct ref *remote_refs, **remote_tail;
  
 -static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 -{
 -      struct ref *ref;
 -      int len = strlen(refname) + 1;
 -      ref = xcalloc(1, sizeof(*ref) + len);
 -      hashcpy(ref->new_sha1, sha1);
 -      memcpy(ref->name, refname, len);
 -      *local_tail = ref;
 -      local_tail = &ref->next;
 -      return 0;
 -}
 -
  static void one_remote_ref(char *refname)
  {
        struct ref *ref;
  
        ref = alloc_ref(refname);
  
-       if (http_fetch_ref(remote->url, ref) != 0) {
+       if (http_fetch_ref(repo->url, ref) != 0) {
                fprintf(stderr,
                        "Unable to fetch ref %s from %s\n",
-                       refname, remote->url);
+                       refname, repo->url);
                free(ref);
                return;
        }
         * Fetch a copy of the object if it doesn't exist locally - it
         * may be required for updating server info later.
         */
-       if (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
+       if (repo->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
                obj = lookup_unknown_object(ref->old_sha1);
                if (obj) {
                        fprintf(stderr, "  fetch %s for %s\n",
        remote_tail = &ref->next;
  }
  
 -static void get_local_heads(void)
 -{
 -      local_tail = &local_refs;
 -      for_each_ref(one_local_ref, NULL);
 -}
 -
  static void get_dav_remote_heads(void)
  {
        remote_tail = &remote_refs;
@@@ -1843,6 -1862,55 +1843,6 @@@ static int is_zero_sha1(const unsigned 
        return 1;
  }
  
 -static void unmark_and_free(struct commit_list *list, unsigned int mark)
 -{
 -      while (list) {
 -              struct commit_list *temp = list;
 -              temp->item->object.flags &= ~mark;
 -              list = temp->next;
 -              free(temp);
 -      }
 -}
 -
 -static int ref_newer(const unsigned char *new_sha1,
 -                   const unsigned char *old_sha1)
 -{
 -      struct object *o;
 -      struct commit *old, *new;
 -      struct commit_list *list, *used;
 -      int found = 0;
 -
 -      /* Both new and old must be commit-ish and new is descendant of
 -       * old.  Otherwise we require --force.
 -       */
 -      o = deref_tag(parse_object(old_sha1), NULL, 0);
 -      if (!o || o->type != OBJ_COMMIT)
 -              return 0;
 -      old = (struct commit *) o;
 -
 -      o = deref_tag(parse_object(new_sha1), NULL, 0);
 -      if (!o || o->type != OBJ_COMMIT)
 -              return 0;
 -      new = (struct commit *) o;
 -
 -      if (parse_commit(new) < 0)
 -              return 0;
 -
 -      used = list = NULL;
 -      commit_list_insert(new, &list);
 -      while (list) {
 -              new = pop_most_recent_commit(&list, TMP_MARK);
 -              commit_list_insert(new, &used);
 -              if (new == old) {
 -                      found = 1;
 -                      break;
 -              }
 -      }
 -      unmark_and_free(list, TMP_MARK);
 -      unmark_and_free(used, TMP_MARK);
 -      return found;
 -}
 -
  static void add_remote_info_ref(struct remote_ls_ctx *ls)
  {
        struct strbuf *buf = (struct strbuf *)ls->userData;
  
        ref = alloc_ref(ls->dentry_name);
  
-       if (http_fetch_ref(remote->url, ref) != 0) {
+       if (http_fetch_ref(repo->url, ref) != 0) {
                fprintf(stderr,
                        "Unable to fetch ref %s from %s\n",
-                       ls->dentry_name, remote->url);
+                       ls->dentry_name, repo->url);
                aborted = 1;
                free(ref);
                return;
@@@ -1931,12 -1999,12 +1931,12 @@@ static void update_remote_info_refs(str
  
  static int remote_exists(const char *path)
  {
-       char *url = xmalloc(strlen(remote->url) + strlen(path) + 1);
+       char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
        struct active_request_slot *slot;
        struct slot_results results;
        int ret = -1;
  
-       sprintf(url, "%s%s", remote->url, path);
+       sprintf(url, "%s%s", repo->url, path);
  
        slot = get_active_slot();
        slot->results = &results;
@@@ -1966,8 -2034,8 +1966,8 @@@ static void fetch_symref(const char *pa
        struct active_request_slot *slot;
        struct slot_results results;
  
-       url = xmalloc(strlen(remote->url) + strlen(path) + 1);
-       sprintf(url, "%s%s", remote->url, path);
+       url = xmalloc(strlen(repo->url) + strlen(path) + 1);
+       sprintf(url, "%s%s", repo->url, path);
  
        slot = get_active_slot();
        slot->results = &results;
@@@ -2082,7 -2150,7 +2082,7 @@@ static int delete_remote_branch(char *p
                                     "of your current HEAD.\n"
                                     "If you are sure you want to delete it,"
                                     " run:\n\t'git http-push -D %s %s'",
-                                    remote_ref->name, remote->url, pattern);
+                                    remote_ref->name, repo->url, pattern);
                }
        }
  
        fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
        if (dry_run)
                return 0;
-       url = xmalloc(strlen(remote->url) + strlen(remote_ref->name) + 1);
-       sprintf(url, "%s%s", remote->url, remote_ref->name);
+       url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1);
+       sprintf(url, "%s%s", repo->url, remote_ref->name);
        slot = get_active_slot();
        slot->results = &results;
        curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
@@@ -2127,14 -2195,15 +2127,15 @@@ int main(int argc, char **argv
        int rc = 0;
        int i;
        int new_refs;
 -      struct ref *ref;
 +      struct ref *ref, *local_refs;
+       struct remote *remote;
        char *rewritten_url = NULL;
  
        git_extract_argv0_path(argv[0]);
  
        setup_git_directory();
  
-       remote = xcalloc(sizeof(*remote), 1);
+       repo = xcalloc(sizeof(*repo), 1);
  
        argv++;
        for (i = 1; i < argc; i++, argv++) {
                                continue;
                        }
                }
-               if (!remote->url) {
+               if (!repo->url) {
                        char *path = strstr(arg, "//");
-                       remote->url = arg;
-                       remote->path_len = strlen(arg);
+                       repo->url = arg;
+                       repo->path_len = strlen(arg);
                        if (path) {
-                               remote->path = strchr(path+2, '/');
-                               if (remote->path)
-                                       remote->path_len = strlen(remote->path);
+                               repo->path = strchr(path+2, '/');
+                               if (repo->path)
+                                       repo->path_len = strlen(repo->path);
                        }
                        continue;
                }
        die("git-push is not available for http/https repository when not compiled with USE_CURL_MULTI");
  #endif
  
-       if (!remote->url)
+       if (!repo->url)
                usage(http_push_usage);
  
        if (delete_branch && nr_refspec != 1)
  
        memset(remote_dir_exists, -1, 256);
  
-       http_init(NULL);
+       /*
+        * Create a minimum remote by hand to give to http_init(),
+        * primarily to allow it to look at the URL.
+        */
+       remote = xcalloc(sizeof(*remote), 1);
+       ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
+       remote->url[remote->url_nr++] = repo->url;
+       http_init(remote);
  
        no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:");
  
-       if (remote->url && remote->url[strlen(remote->url)-1] != '/') {
-               rewritten_url = xmalloc(strlen(remote->url)+2);
-               strcpy(rewritten_url, remote->url);
+       if (repo->url && repo->url[strlen(repo->url)-1] != '/') {
+               rewritten_url = xmalloc(strlen(repo->url)+2);
+               strcpy(rewritten_url, repo->url);
                strcat(rewritten_url, "/");
-               remote->path = rewritten_url + (remote->path - remote->url);
-               remote->path_len++;
-               remote->url = rewritten_url;
+               repo->path = rewritten_url + (repo->path - repo->url);
+               repo->path_len++;
+               repo->url = rewritten_url;
        }
  
        /* Verify DAV compliance/lock support */
        sigchain_push_common(remove_locks_on_signal);
  
        /* Check whether the remote has server info files */
-       remote->can_update_info_refs = 0;
-       remote->has_info_refs = remote_exists("info/refs");
-       remote->has_info_packs = remote_exists("objects/info/packs");
-       if (remote->has_info_refs) {
+       repo->can_update_info_refs = 0;
+       repo->has_info_refs = remote_exists("info/refs");
+       repo->has_info_packs = remote_exists("objects/info/packs");
+       if (repo->has_info_refs) {
                info_ref_lock = lock_remote("info/refs", LOCK_TIME);
                if (info_ref_lock)
-                       remote->can_update_info_refs = 1;
+                       repo->can_update_info_refs = 1;
                else {
 -                      fprintf(stderr, "Error: cannot lock existing info/refs\n");
 +                      error("cannot lock existing info/refs");
                        rc = 1;
                        goto cleanup;
                }
        }
-       if (remote->has_info_packs)
+       if (repo->has_info_packs)
                fetch_indices();
  
        /* Get a list of all local and remote heads to validate refspecs */
 -      get_local_heads();
 +      local_refs = get_local_heads();
        fprintf(stderr, "Fetching remote heads...\n");
        get_dav_remote_heads();
  
        }
  
        /* Update remote server info if appropriate */
-       if (remote->has_info_refs && new_refs) {
-               if (info_ref_lock && remote->can_update_info_refs) {
+       if (repo->has_info_refs && new_refs) {
+               if (info_ref_lock && repo->can_update_info_refs) {
                        fprintf(stderr, "Updating remote server info\n");
                        if (!dry_run)
                                update_remote_info_refs(info_ref_lock);
        free(rewritten_url);
        if (info_ref_lock)
                unlock_remote(info_ref_lock);
-       free(remote);
+       free(repo);
  
        curl_slist_free_all(no_pragma_header);