#include "cache.h"
#include "commit.h"
#include "pack.h"
-#include "fetch.h"
#include "tag.h"
#include "blob.h"
#include "http.h"
#include "diff.h"
#include "revision.h"
#include "exec_cmd.h"
+#include "remote.h"
#include <expat.h>
/* 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
{
struct remote_lock *locks;
};
-static struct repo *remote = NULL;
+static struct repo *remote;
enum transfer_state {
NEED_FETCH,
struct transfer_request *next;
};
-static struct transfer_request *request_queue_head = NULL;
+static struct transfer_request *request_queue_head;
struct xml_ctx
{
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;
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,
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);
}
}
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;
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));
request->buffer.size = stream.total_out;
request->buffer.posn = 0;
- request->url = xmalloc(strlen(remote->url) +
+ request->url = xmalloc(strlen(remote->url) +
strlen(request->lock->token) + 51);
strcpy(request->url, remote->url);
posn = request->url + strlen(remote->url);
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 =
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);
}
#ifdef USE_CURL_MULTI
-void fill_active_slots(void)
+static int fill_active_slot(void *unused)
{
struct transfer_request *request = request_queue_head;
- struct transfer_request *next;
- struct active_request_slot *slot = active_queue_head;
- int num_transfers;
if (aborted)
- return;
+ return 0;
- while (active_requests < max_requests && request != NULL) {
- next = request->next;
+ for (request = request_queue_head; request; request = request->next) {
if (request->state == NEED_FETCH) {
start_fetch_loose(request);
+ return 1;
} else if (pushing && request->state == NEED_PUSH) {
if (remote_dir_exists[request->obj->sha1[0]] == 1) {
start_put(request);
} else {
start_mkcol(request);
}
- curl_multi_perform(curlm, &num_transfers);
- }
- request = next;
- }
-
- while (slot != NULL) {
- if (!slot->in_use && slot->curl != NULL) {
- curl_easy_cleanup(slot->curl);
- slot->curl = NULL;
+ return 1;
}
- slot = slot->next;
}
+ return 0;
}
#endif
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;
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);
}
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);
}
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)
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();
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);
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;
}
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;
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;
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))
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;
}
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;
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)
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);
}
struct commit *branch = lookup_commit(branch_sha1);
struct commit_list *merge_bases = get_merge_bases(head, branch, 1);
- if (merge_bases && !merge_bases->next && merge_bases->item == branch)
- return 1;
-
- return 0;
+ return (merge_bases && !merge_bases->next && merge_bases->item == branch);
}
static int delete_remote_branch(char *pattern, int force)
struct ref *ref;
setup_git_directory();
- setup_ident();
remote = xcalloc(sizeof(*remote), 1);
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;
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;
/* 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;
objects_to_send);
#ifdef USE_CURL_MULTI
fill_active_slots();
+ add_fill_function(NULL, fill_active_slot);
#endif
finish_all_active_slots();