X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=transport.c;h=babaa21398522939076151f1c240a4f18f9a90a1;hb=a41acc63badf20cbb22cca61039dca9309deaa19;hp=e8a2608372de06ef3f77d9a450776e3095057c9f;hpb=37ec2b4c26901d5f1ca19948189dc2b6f21523d5;p=git.git diff --git a/transport.c b/transport.c index e8a260837..babaa2139 100644 --- a/transport.c +++ b/transport.c @@ -6,6 +6,7 @@ #endif #include "pkt-line.h" #include "fetch-pack.h" +#include "send-pack.h" #include "walker.h" #include "bundle.h" #include "dir.h" @@ -117,7 +118,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list) if (hexval(buffer[0]) > 0xf) continue; len = strlen(buffer); - if (buffer[len - 1] == '\n') + if (len && buffer[len - 1] == '\n') buffer[--len] = '\0'; if (len < 41) continue; @@ -141,7 +142,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list) } } -static struct ref *get_refs_via_rsync(const struct transport *transport) +static struct ref *get_refs_via_rsync(struct transport *transport) { struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT; struct ref dummy, *tail = &dummy; @@ -283,6 +284,9 @@ static int rsync_transport_push(struct transport *transport, struct child_process rsync; const char *args[10]; + if (flags & TRANSPORT_PUSH_MIRROR) + return error("rsync transport does not support mirror mode"); + /* first push the objects */ strbuf_addstr(&buf, transport->url); @@ -344,6 +348,7 @@ static int rsync_transport_push(struct transport *transport, /* Generic functions for using commit walkers */ +#ifndef NO_CURL /* http fetch is the only user */ static int fetch_objs_via_walker(struct transport *transport, int nr_objs, struct ref **to_fetch) { @@ -370,6 +375,7 @@ static int fetch_objs_via_walker(struct transport *transport, free(dest); return 0; } +#endif /* NO_CURL */ static int disconnect_walker(struct transport *transport) { @@ -386,6 +392,9 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons int argc; int err; + if (flags & TRANSPORT_PUSH_MIRROR) + return error("http transport does not support mirror mode"); + argv = xmalloc((refspec_nr + 12) * sizeof(char *)); argv[0] = "http-push"; argc = 1; @@ -417,22 +426,9 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons return !!err; } -static int missing__target(int code, int result) -{ - return /* file:// URL -- do we ever use one??? */ - (result == CURLE_FILE_COULDNT_READ_FILE) || - /* http:// and https:// URL */ - (code == 404 && result == CURLE_HTTP_RETURNED_ERROR) || - /* ftp:// URL */ - (code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE) - ; -} - -#define missing_target(a) missing__target((a)->http_code, (a)->curl_result) - -static struct ref *get_refs_via_curl(const struct transport *transport) +static struct ref *get_refs_via_curl(struct transport *transport) { - struct buffer buffer; + struct strbuf buffer = STRBUF_INIT; char *data, *start, *mid; char *ref_name; char *refs_url; @@ -445,11 +441,6 @@ static struct ref *get_refs_via_curl(const struct transport *transport) struct ref *ref = NULL; struct ref *last_ref = NULL; - data = xmalloc(4096); - buffer.size = 4096; - buffer.posn = 0; - buffer.buffer = data; - refs_url = xmalloc(strlen(transport->url) + 11); sprintf(refs_url, "%s/info/refs", transport->url); @@ -461,30 +452,33 @@ static struct ref *get_refs_via_curl(const struct transport *transport) curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); curl_easy_setopt(slot->curl, CURLOPT_URL, refs_url); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL); + if (transport->remote->http_proxy) + curl_easy_setopt(slot->curl, CURLOPT_PROXY, + transport->remote->http_proxy); + if (start_active_slot(slot)) { run_active_slot(slot); if (results.curl_result != CURLE_OK) { + strbuf_release(&buffer); if (missing_target(&results)) { - free(buffer.buffer); return NULL; } else { - free(buffer.buffer); error("%s", curl_errorstr); return NULL; } } } else { - free(buffer.buffer); + strbuf_release(&buffer); error("Unable to start request"); return NULL; } http_cleanup(); - data = buffer.buffer; + data = buffer.buf; start = NULL; mid = data; - while (i < buffer.posn) { + while (i < buffer.len) { if (!start) start = &data[i]; if (data[i] == '\t') @@ -507,7 +501,7 @@ static struct ref *get_refs_via_curl(const struct transport *transport) i++; } - free(buffer.buffer); + strbuf_release(&buffer); return refs; } @@ -527,7 +521,7 @@ struct bundle_transport_data { struct bundle_header header; }; -static struct ref *get_refs_from_bundle(const struct transport *transport) +static struct ref *get_refs_from_bundle(struct transport *transport) { struct bundle_transport_data *data = transport->data; struct ref *result = NULL; @@ -599,7 +593,7 @@ static int set_git_option(struct transport *connection, return 1; } -static struct ref *get_refs_via_connect(const struct transport *transport) +static struct ref *get_refs_via_connect(struct transport *transport) { struct git_transport_data *data = transport->data; struct ref *refs; @@ -646,56 +640,23 @@ static int fetch_refs_via_pack(struct transport *transport, free(heads); free_refs(refs); free(dest); - return 0; + return (refs ? 0 : -1); } static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) { struct git_transport_data *data = transport->data; - const char **argv; - char *rem; - int argc; - int err; + struct send_pack_args args; - argv = xmalloc((refspec_nr + 12) * sizeof(char *)); - argv[0] = "send-pack"; - argc = 1; - if (flags & TRANSPORT_PUSH_ALL) - argv[argc++] = "--all"; - if (flags & TRANSPORT_PUSH_FORCE) - argv[argc++] = "--force"; - if (flags & TRANSPORT_PUSH_DRY_RUN) - argv[argc++] = "--dry-run"; - if (flags & TRANSPORT_PUSH_VERBOSE) - argv[argc++] = "--verbose"; - if (data->receivepack) { - char *rp = xmalloc(strlen(data->receivepack) + 16); - sprintf(rp, "--receive-pack=%s", data->receivepack); - argv[argc++] = rp; - } - if (data->thin) - argv[argc++] = "--thin"; - rem = xmalloc(strlen(transport->remote->name) + 10); - sprintf(rem, "--remote=%s", transport->remote->name); - argv[argc++] = rem; - argv[argc++] = transport->url; - while (refspec_nr--) - argv[argc++] = *refspec++; - argv[argc] = NULL; - err = run_command_v_opt(argv, RUN_GIT_CMD); - switch (err) { - case -ERR_RUN_COMMAND_FORK: - error("unable to fork for %s", argv[0]); - case -ERR_RUN_COMMAND_EXEC: - error("unable to exec %s", argv[0]); - break; - case -ERR_RUN_COMMAND_WAITPID: - case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: - case -ERR_RUN_COMMAND_WAITPID_SIGNAL: - case -ERR_RUN_COMMAND_WAITPID_NOEXIT: - error("%s died with strange error", argv[0]); - } - return !!err; + args.receivepack = data->receivepack; + args.send_all = !!(flags & TRANSPORT_PUSH_ALL); + args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR); + args.force_update = !!(flags & TRANSPORT_PUSH_FORCE); + args.use_thin_pack = data->thin; + args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE); + args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN); + + return send_pack(&args, transport->url, transport->remote, refspec_nr, refspec); } static int disconnect_git(struct transport *transport) @@ -787,7 +748,7 @@ int transport_push(struct transport *transport, return transport->push(transport, refspec_nr, refspec, flags); } -struct ref *transport_get_remote_refs(struct transport *transport) +const struct ref *transport_get_remote_refs(struct transport *transport) { if (!transport->remote_refs) transport->remote_refs = transport->get_refs_list(transport);