X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=http-push.c;h=79d2c3860825ba1e68fff555b4433731d51c1b52;hb=3520e1e86878c6787c3abfe677e6472ce2c97f66;hp=d45733ef64ecb8c153a0f62cfb193eed332402e6;hpb=67e31d6234c0332334d7aedd70b2f101bc010cf9;p=git.git diff --git a/http-push.c b/http-push.c index d45733ef6..79d2c3860 100644 --- a/http-push.c +++ b/http-push.c @@ -9,6 +9,7 @@ #include "diff.h" #include "revision.h" #include "exec_cmd.h" +#include "remote.h" #include @@ -70,18 +71,18 @@ enum XML_Status { /* We allow "recursive" symbolic refs. Only within reason, though */ #define MAXDEPTH 5 -static int pushing = 0; -static int aborted = 0; +static int pushing; +static int aborted; static signed char remote_dir_exists[256]; static struct curl_slist *no_pragma_header; static struct curl_slist *default_headers; -static int push_verbosely = 0; -static int push_all = 0; -static int force_all = 0; +static int push_verbosely; +static int push_all; +static int force_all; -static struct object_list *objects = NULL; +static struct object_list *objects; struct repo { @@ -94,7 +95,7 @@ struct repo struct remote_lock *locks; }; -static struct repo *remote = NULL; +static struct repo *remote; enum transfer_state { NEED_FETCH, @@ -134,7 +135,7 @@ struct transfer_request struct transfer_request *next; }; -static struct transfer_request *request_queue_head = NULL; +static struct transfer_request *request_queue_head; struct xml_ctx { @@ -195,7 +196,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, int posn = 0; struct transfer_request *request = (struct transfer_request *)data; do { - ssize_t retval = write(request->local_fileno, + ssize_t retval = xwrite(request->local_fileno, (char *) ptr + posn, size - posn); if (retval < 0) return posn; @@ -288,7 +289,7 @@ static void start_fetch_loose(struct transfer_request *request) prevlocal = open(prevfile, O_RDONLY); if (prevlocal != -1) { do { - prev_read = read(prevlocal, prev_buf, PREV_BUF_SIZE); + prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE); if (prev_read>0) { if (fwrite_sha1_file(prev_buf, 1, @@ -312,7 +313,7 @@ static void start_fetch_loose(struct transfer_request *request) SHA1_Init(&request->c); if (prev_posn>0) { prev_posn = 0; - lseek(request->local_fileno, SEEK_SET, 0); + lseek(request->local_fileno, 0, SEEK_SET); ftruncate(request->local_fileno, 0); } } @@ -479,7 +480,7 @@ static void start_put(struct transfer_request *request) char *hex = sha1_to_hex(request->obj->sha1); struct active_request_slot *slot; char *posn; - char type[20]; + enum object_type type; char hdr[50]; void *unpacked; unsigned long len; @@ -487,8 +488,8 @@ static void start_put(struct transfer_request *request) ssize_t size; z_stream stream; - unpacked = read_sha1_file(request->obj->sha1, type, &len); - hdrlen = sprintf(hdr, "%s %lu", type, len) + 1; + unpacked = read_sha1_file(request->obj->sha1, &type, &len); + hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1; /* Set it up */ memset(&stream, 0, sizeof(stream)); @@ -745,7 +746,7 @@ static void finish_request(struct transfer_request *request) SHA1_Final(request->real_sha1, &request->c); if (request->zret != Z_STREAM_END) { unlink(request->tmpfile); - } else if (memcmp(request->obj->sha1, request->real_sha1, 20)) { + } else if (hashcmp(request->obj->sha1, request->real_sha1)) { unlink(request->tmpfile); } else { request->rename = @@ -770,11 +771,14 @@ static void finish_request(struct transfer_request *request) request->url, curl_errorstr); remote->can_update_info_refs = 0; } else { + off_t pack_size = ftell(request->local_stream); + fclose(request->local_stream); request->local_stream = NULL; if (!move_temp_to_file(request->tmpfile, request->filename)) { target = (struct packed_git *)request->userData; + target->pack_size = pack_size; lst = &remote->packs; while (*lst != target) lst = &((*lst)->next); @@ -1057,8 +1061,8 @@ static int fetch_indices(void) case 'P': i++; if (i + 52 < buffer.posn && - !strncmp(data + i, " pack-", 6) && - !strncmp(data + i + 46, ".pack\n", 6)) { + !prefixcmp(data + i, " pack-") && + !prefixcmp(data + i + 46, ".pack\n")) { get_sha1_hex(data + i + 6, sha1); setup_index(sha1); i += 51; @@ -1203,11 +1207,11 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed) lock->owner = xmalloc(strlen(ctx->cdata) + 1); strcpy(lock->owner, ctx->cdata); } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) { - if (!strncmp(ctx->cdata, "Second-", 7)) + if (!prefixcmp(ctx->cdata, "Second-")) lock->timeout = strtol(ctx->cdata + 7, NULL, 10); } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) { - if (!strncmp(ctx->cdata, "opaquelocktoken:", 16)) { + if (!prefixcmp(ctx->cdata, "opaquelocktoken:")) { lock->token = xmalloc(strlen(ctx->cdata) - 15); strcpy(lock->token, ctx->cdata + 16); } @@ -1238,10 +1242,8 @@ xml_start_tag(void *userData, const char *name, const char **atts) strcat(ctx->name, "."); strcat(ctx->name, c); - if (ctx->cdata) { - free(ctx->cdata); - ctx->cdata = NULL; - } + free(ctx->cdata); + ctx->cdata = NULL; ctx->userFunc(ctx, 0); } @@ -1268,10 +1270,11 @@ static void xml_cdata(void *userData, const XML_Char *s, int len) { struct xml_ctx *ctx = (struct xml_ctx *)userData; - if (ctx->cdata) - free(ctx->cdata); + free(ctx->cdata); ctx->cdata = xmalloc(len + 1); - strlcpy(ctx->cdata, s, len + 1); + /* NB: 's' is not null-terminated, can not use strlcpy here */ + memcpy(ctx->cdata, s, len); + ctx->cdata[len] = '\0'; } static struct remote_lock *lock_remote(const char *path, long timeout) @@ -1295,7 +1298,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout) sprintf(url, "%s%s", remote->url, path); /* Make sure leading directories exist for the remote ref */ - ep = strchr(url + strlen(remote->url) + 11, '/'); + ep = strchr(url + strlen(remote->url) + 1, '/'); while (ep) { *ep = 0; slot = get_active_slot(); @@ -1473,7 +1476,8 @@ static void process_ls_object(struct remote_ls_ctx *ls) return; path += 8; obj_hex = xmalloc(strlen(path)); - strlcpy(obj_hex, path, 3); + /* NB: path is not null-terminated, can not use strlcpy here */ + memcpy(obj_hex, path, 2); strcpy(obj_hex + 2, path + 3); one_remote_object(obj_hex); free(obj_hex); @@ -1518,9 +1522,7 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed) ls->dentry_flags |= IS_DIR; } } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) { - if (ls->dentry_name) { - free(ls->dentry_name); - } + free(ls->dentry_name); ls->dentry_name = NULL; ls->dentry_flags = 0; } @@ -1544,7 +1546,7 @@ static void remote_ls(const char *path, int flags, struct remote_ls_ctx ls; ls.flags = flags; - ls.path = strdup(path); + ls.path = xstrdup(path); ls.dentry_name = NULL; ls.dentry_flags = 0; ls.userData = userData; @@ -1700,7 +1702,7 @@ static int locking_available(void) return lock_flags; } -struct object_list **add_one_object(struct object *obj, struct object_list **p) +static struct object_list **add_one_object(struct object *obj, struct object_list **p) { struct object_list *entry = xmalloc(sizeof(struct object_list)); entry->item = obj; @@ -1743,14 +1745,13 @@ static struct object_list **process_tree(struct tree *tree, die("bad tree object %s", sha1_to_hex(obj->sha1)); obj->flags |= SEEN; - name = strdup(name); + name = xstrdup(name); p = add_one_object(obj, p); me.up = path; me.elem = name; me.elem_len = strlen(name); - desc.buf = tree->buffer; - desc.size = tree->size; + init_tree_desc(&desc, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { if (S_ISDIR(entry.mode)) @@ -1869,12 +1870,12 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock) 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) +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); - memcpy(ref->new_sha1, sha1, 20); + hashcpy(ref->new_sha1, sha1); memcpy(ref->name, refname, len); *local_tail = ref; local_tail = &ref->next; @@ -1909,7 +1910,7 @@ static void one_remote_ref(char *refname) } ref = xcalloc(1, sizeof(*ref) + len); - memcpy(ref->old_sha1, remote_sha1, 20); + hashcpy(ref->old_sha1, remote_sha1); memcpy(ref->name, refname, len); *remote_tail = ref; remote_tail = &ref->next; @@ -1918,7 +1919,7 @@ static void one_remote_ref(char *refname) static void get_local_heads(void) { local_tail = &local_refs; - for_each_ref(one_local_ref); + for_each_ref(one_local_ref, NULL); } static void get_dav_remote_heads(void) @@ -2164,15 +2165,16 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1) if (*symref != NULL) free(*symref); *symref = NULL; - memset(sha1, 0, 20); + hashclr(sha1); if (buffer.posn == 0) return; /* If it's a symref, set the refname; otherwise try for a sha1 */ - if (!strncmp((char *)buffer.buffer, "ref: ", 5)) { + if (!prefixcmp((char *)buffer.buffer, "ref: ")) { *symref = xmalloc(buffer.posn - 5); - strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5); + memcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 6); + (*symref)[buffer.posn - 6] = '\0'; } else { get_sha1_hex(buffer.buffer, sha1); } @@ -2182,49 +2184,11 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1) static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1) { - int pipe_fd[2]; - pid_t merge_base_pid; - char line[PATH_MAX + 20]; - unsigned char merge_sha1[20]; - int verified = 0; - - if (pipe(pipe_fd) < 0) - die("Verify merge base: pipe failed"); - - merge_base_pid = fork(); - if (!merge_base_pid) { - static const char *args[] = { - "merge-base", - "-a", - NULL, - NULL, - NULL - }; - args[2] = strdup(sha1_to_hex(head_sha1)); - args[3] = sha1_to_hex(branch_sha1); - - dup2(pipe_fd[1], 1); - close(pipe_fd[0]); - close(pipe_fd[1]); - execv_git_cmd(args); - die("merge-base setup failed"); - } - if (merge_base_pid < 0) - die("merge-base fork failed"); - - dup2(pipe_fd[0], 0); - close(pipe_fd[0]); - close(pipe_fd[1]); - while (fgets(line, sizeof(line), stdin) != NULL) { - if (get_sha1_hex(line, merge_sha1)) - die("expected sha1, got garbage:\n %s", line); - if (!memcmp(branch_sha1, merge_sha1, 20)) { - verified = 1; - break; - } - } + struct commit *head = lookup_commit(head_sha1); + struct commit *branch = lookup_commit(branch_sha1); + struct commit_list *merge_bases = get_merge_bases(head, branch, 1); - return verified; + return (merge_bases && !merge_bases->next && merge_bases->item == branch); } static int delete_remote_branch(char *pattern, int force) @@ -2339,7 +2303,6 @@ int main(int argc, char **argv) struct ref *ref; setup_git_directory(); - setup_ident(); remote = xcalloc(sizeof(*remote), 1); @@ -2454,7 +2417,7 @@ int main(int argc, char **argv) if (!ref->peer_ref) continue; - if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) { + if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) { if (push_verbosely || 1) fprintf(stderr, "'%s': up-to-date\n", ref->name); continue; @@ -2483,7 +2446,7 @@ int main(int argc, char **argv) continue; } } - memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20); + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); if (is_zero_sha1(ref->new_sha1)) { error("cannot happen anymore"); rc = -3; @@ -2510,7 +2473,7 @@ int main(int argc, char **argv) /* Set up revision info for this refspec */ commit_argc = 3; - new_sha1_hex = strdup(sha1_to_hex(ref->new_sha1)); + new_sha1_hex = xstrdup(sha1_to_hex(ref->new_sha1)); old_sha1_hex = NULL; commit_argv[1] = "--objects"; commit_argv[2] = new_sha1_hex;