Example #1
0
int strbuf_grow(struct strbuf *sb, size_t extra)
{
	char *buf;
	size_t nr = sb->len + extra + 1;

	if (nr < sb->alloc)
		return 0;

	if (nr <= sb->len)
		return -E2BIG;

	if (alloc_nr(sb->alloc) > nr)
		nr = alloc_nr(sb->alloc);

	/*
	 * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
	 * a static variable. Thus we have to avoid passing it to realloc.
	 */
	buf = realloc(sb->alloc ? sb->buf : NULL, nr * sizeof(*buf));
	if (!buf)
		return -ENOMEM;

	sb->buf = buf;
	sb->alloc = nr;
	return 0;
}
Example #2
0
static struct cache_tree_sub *find_subtree(struct cache_tree *it,
					   const char *path,
					   int pathlen,
					   int create)
{
	struct cache_tree_sub *down;
	int pos = subtree_pos(it, path, pathlen);
	if (0 <= pos)
		return it->down[pos];
	if (!create)
		return NULL;

	pos = -pos-1;
	if (it->subtree_alloc <= it->subtree_nr) {
		it->subtree_alloc = alloc_nr(it->subtree_alloc);
		it->down = xrealloc(it->down, it->subtree_alloc *
				    sizeof(*it->down));
	}
	it->subtree_nr++;

	down = xmalloc(sizeof(*down) + pathlen + 1);
	down->cache_tree = NULL;
	down->namelen = pathlen;
	memcpy(down->name, path, pathlen);
	down->name[pathlen] = 0;

	if (pos < it->subtree_nr)
		memmove(it->down + pos + 1,
			it->down + pos,
			sizeof(down) * (it->subtree_nr - pos - 1));
	it->down[pos] = down;
	return down;
}
Example #3
0
void created_object(unsigned char *sha1, struct object *obj)
{
	int pos = find_object(sha1);

	obj->parsed = 0;
	memcpy(obj->sha1, sha1, 20);
	obj->type = NULL;
	obj->refs = NULL;
	obj->used = 0;

	if (pos >= 0)
		die("Inserting %s twice\n", sha1_to_hex(sha1));
	pos = -pos-1;

	if (obj_allocs == nr_objs) {
		obj_allocs = alloc_nr(obj_allocs);
		objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
	}

	/* Insert it into the right place */
	memmove(objs + pos + 1, objs + pos, (nr_objs - pos) * 
		sizeof(struct object *));

	objs[pos] = obj;
	nr_objs++;
}
Example #4
0
int nerd_mkchan(const char *name, const char *description, int (*handler)(int, void *), unsigned int callbacks)
{
	struct nerd_channel *chan, **ptr;
	int i;

	if(num_channels + 1 >= alloc_channels) {
		alloc_channels = alloc_nr(alloc_channels);
		ptr = realloc(channels, alloc_channels * sizeof(struct nerd_channel *));
		if(!ptr)
			return -1;
		channels = ptr;
	}

	if(!(chan = calloc(1, sizeof(*chan))))
		return -1;

	chan->name = name;
	chan->description = description;
	chan->handler = handler;
	for(i = 0; callbacks && i < NEBCALLBACK_NUMITEMS; i++) {
		if(!(callbacks & (1 << i)))
			continue;

		chan->callbacks[chan->num_callbacks++] = i;
	}

	channels[num_channels++] = chan;

	logit(NSLOG_INFO_MESSAGE, TRUE, "nerd: Channel %s registered successfully\n", chan->name);
	return num_channels - 1;
}
Example #5
0
static int register_replace_object(struct replace_object *replace,
				   int ignore_dups)
{
	int pos = replace_object_pos(replace->sha1[0]);

	if (0 <= pos) {
		if (ignore_dups)
			free(replace);
		else {
			free(replace_object[pos]);
			replace_object[pos] = replace;
		}
		return 1;
	}
	pos = -pos - 1;
	if (replace_object_alloc <= ++replace_object_nr) {
		replace_object_alloc = alloc_nr(replace_object_alloc);
		replace_object = xrealloc(replace_object,
					  sizeof(*replace_object) *
					  replace_object_alloc);
	}
	if (pos < replace_object_nr)
		memmove(replace_object + pos + 1,
			replace_object + pos,
			(replace_object_nr - pos - 1) *
			sizeof(*replace_object));
	replace_object[pos] = replace;
	return 0;
}
Example #6
0
static struct revision *lookup_rev(unsigned char *sha1)
{
	int pos = find_rev(sha1);
	struct revision *n;

	if (pos >= 0)
		return revs[pos];
	
	pos = -pos-1;

	if (rev_allocs == nr_revs) {
		rev_allocs = alloc_nr(rev_allocs);
		revs = realloc(revs, rev_allocs * sizeof(struct revision *));
	}
	n = malloc(sizeof(struct revision));

	n->flags = 0;
	memcpy(n->sha1, sha1, 20);
	n->parent = NULL;

	/* Insert it into the right place */
	memmove(revs + pos + 1, revs + pos, (nr_revs - pos) * sizeof(struct revision *));
	revs[pos] = n;
	nr_revs++;

	return n;
}
Example #7
0
static int add_cache_entry(struct cache_entry *ce)
{
	int pos;

	pos = cache_name_pos(ce->name, ce->namelen);

	/* existing match? Just replace it */
	if (pos < 0) {
		active_cache[-pos-1] = ce;
		return 0;
	}

	/* Make sure the array is big enough .. */
	if (active_nr == active_alloc) {
		active_alloc = alloc_nr(active_alloc);
		active_cache = realloc(active_cache, active_alloc * sizeof(struct cache_entry *));
	}

	/* Add it in.. */
	active_nr++;
	if (active_nr > pos)
		memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
	active_cache[pos] = ce;
	return 0;
}
Example #8
0
static void add_list(const char *name)
{
	if (list.nr >= list.alloc) {
		list.alloc = alloc_nr(list.alloc);
		list.name = xrealloc(list.name, list.alloc * sizeof(const char *));
	}
	list.name[list.nr++] = name;
}
Example #9
0
static void prepare_commit_graft(void)
{
	char *graft_file = get_graft_file();
	FILE *fp = fopen(graft_file, "r");
	char buf[1024];
	if (!fp) {
		commit_graft = (struct commit_graft **) "hack";
		return;
	}
	while (fgets(buf, sizeof(buf), fp)) {
		/* The format is just "Commit Parent1 Parent2 ...\n" */
		int len = strlen(buf);
		int i;
		struct commit_graft *graft = NULL;

		if (buf[len-1] == '\n')
			buf[--len] = 0;
		if (buf[0] == '#')
			continue;
		if ((len + 1) % 41) {
		bad_graft_data:
			error("bad graft data: %s", buf);
			free(graft);
			continue;
		}
		i = (len + 1) / 41 - 1;
		graft = xmalloc(sizeof(*graft) + 20 * i);
		graft->nr_parent = i;
		if (get_sha1_hex(buf, graft->sha1))
			goto bad_graft_data;
		for (i = 40; i < len; i += 41) {
			if (buf[i] != ' ')
				goto bad_graft_data;
			if (get_sha1_hex(buf + i + 1, graft->parent[i/41]))
				goto bad_graft_data;
		}
		i = commit_graft_pos(graft->sha1);
		if (0 <= i) {
			error("duplicate graft data: %s", buf);
			free(graft);
			continue;
		}
		i = -i - 1;
		if (commit_graft_alloc <= ++commit_graft_nr) {
			commit_graft_alloc = alloc_nr(commit_graft_alloc);
			commit_graft = xrealloc(commit_graft,
						sizeof(*commit_graft) *
						commit_graft_alloc);
		}
		if (i < commit_graft_nr)
			memmove(commit_graft + i + 1,
				commit_graft + i,
				(commit_graft_nr - i - 1) *
				sizeof(*commit_graft));
		commit_graft[i] = graft;
	}
	fclose(fp);
}
Example #10
0
static LPWSTR expand_variables(LPWSTR buffer, size_t alloc)
{
	LPWSTR buf = buffer;
	size_t len = wcslen(buf), move_len;

	for (;;) {
		LPWSTR atat = wcsstr(buf, L"@@"), atat2;
		WCHAR save;
		int env_len, delta;

		if (!atat)
			break;

		atat2 = wcsstr(atat + 2, L"@@");
		if (!atat2)
			break;

		*atat2 = L'\0';
		atat2 += 2;
		env_len = GetEnvironmentVariable(atat + 2, NULL, 0);
		delta = env_len - 1 - (atat2 - atat);
		if (len + delta >= alloc) {
			LPWSTR buf2;
			alloc = alloc_nr(alloc);
			if (alloc <= len + delta)
				alloc = len + delta + 1;
			if (buf != buffer)
				buf2 = realloc(buf, sizeof(WCHAR) * alloc);
			else {
				buf2 = malloc(sizeof(WCHAR) * alloc);
				if (buf2)
					memcpy(buf2, buf, sizeof(WCHAR)
							* (len + 1));
			}
			if (!buf2) {
				fwprintf(stderr,
					L"Substituting '%s' results in too "
					L"large a command-line\n", atat + 2);
				exit(1);
			}
			atat += buf2 - buf;
			atat2 += buf2 - buf;
			buf = buf2;
		}
		move_len = sizeof(WCHAR) * (len + 1 - (atat2 - buf));
		if (delta > 0)
			memmove(atat2 + delta, atat2, move_len);
		len += delta;
		save = atat[env_len - 1 + (delta < 0 ? -delta : 0)];
		GetEnvironmentVariable(atat + 2, atat, env_len);
		if (delta < 0)
			memmove(atat2 + delta, atat2, move_len);
		atat[env_len - 1] = save;
	}

	return buf;
}
Example #11
0
int read_cache(void)
{
	int fd, i;
	struct stat st;
	unsigned long size, offset;
	void *map;
	struct cache_header *hdr;

	errno = EBUSY;
	if (active_cache)
		return error("more than one cachefile");
	errno = ENOENT;
	sha1_file_directory = getenv(DB_ENVIRONMENT);
	if (!sha1_file_directory)
		sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
	if (access(sha1_file_directory, X_OK) < 0)
		return error("no access to SHA1 file directory");
	fd = open(get_index_file(), O_RDONLY);
	if (fd < 0)
		return (errno == ENOENT) ? 0 : error("open failed");

	size = 0; // avoid gcc warning
	map = (void *)-1;
	if (!fstat(fd, &st)) {
		size = st.st_size;
		errno = EINVAL;
		if (size >= sizeof(struct cache_header) + 20)
			map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
	}
	close(fd);
	if (-1 == (int)(long)map)
		return error("mmap failed");

	hdr = map;
	if (verify_hdr(hdr, size) < 0)
		goto unmap;

	active_nr = ntohl(hdr->hdr_entries);
	active_alloc = alloc_nr(active_nr);
	active_cache = calloc(active_alloc, sizeof(struct cache_entry *));

	offset = sizeof(*hdr);
	for (i = 0; i < active_nr; i++) {
		struct cache_entry *ce = map + offset;
		offset = offset + ce_size(ce);
		active_cache[i] = ce;
	}
	return active_nr;

unmap:
	munmap(map, size);
	errno = EINVAL;
	return error("verify header failed");
}
Example #12
0
File: bundle.c Project: avish/git
static void add_to_ref_list(const unsigned char *sha1, const char *name,
		struct ref_list *list)
{
	if (list->nr + 1 >= list->alloc) {
		list->alloc = alloc_nr(list->nr + 1);
		list->list = xrealloc(list->list,
				list->alloc * sizeof(list->list[0]));
	}
	memcpy(list->list[list->nr].sha1, sha1, 20);
	list->list[list->nr].name = xstrdup(name);
	list->nr++;
}
Example #13
0
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
	struct ref_list *ref_list = (struct ref_list*)(cb_data);
	struct ref_item *newitem;
	struct commit *commit;
	int kind;
	int len;

	/* Detect kind */
	if (!prefixcmp(refname, "refs/heads/")) {
		kind = REF_LOCAL_BRANCH;
		refname += 11;
	} else if (!prefixcmp(refname, "refs/remotes/")) {
		kind = REF_REMOTE_BRANCH;
		refname += 13;
	} else
		return 0;

	commit = lookup_commit_reference_gently(sha1, 1);
	if (!commit)
		return error("branch '%s' does not point at a commit", refname);

	/* Filter with with_commit if specified */
	if (!is_descendant_of(commit, ref_list->with_commit))
		return 0;

	/* Don't add types the caller doesn't want */
	if ((kind & ref_list->kinds) == 0)
		return 0;

	if (merge_filter != NO_FILTER)
		add_pending_object(&ref_list->revs,
				   (struct object *)commit, refname);

	/* Resize buffer */
	if (ref_list->index >= ref_list->alloc) {
		ref_list->alloc = alloc_nr(ref_list->alloc);
		ref_list->list = xrealloc(ref_list->list,
				ref_list->alloc * sizeof(struct ref_item));
	}

	/* Record the new item */
	newitem = &(ref_list->list[ref_list->index++]);
	newitem->name = xstrdup(refname);
	newitem->kind = kind;
	newitem->commit = commit;
	len = strlen(newitem->name);
	if (len > ref_list->maxwidth)
		ref_list->maxwidth = len;

	return 0;
}
Example #14
0
/* Resize group node's sub-id array */
static void
group_node_expand(struct mib_group_node *gn, int index)
{
  int i;

  assert(!is_raw_group(gn));

  if (gn->sub_id_cnt + 1 > gn->sub_id_cap) {
    /* resize new sub-id array */
    oid_t *sub_id = xcalloc(alloc_nr(gn->sub_id_cap), sizeof(oid_t));
    void **sub_ptr = xcalloc(alloc_nr(gn->sub_id_cap), sizeof(void *));

    gn->sub_id_cap = alloc_nr(gn->sub_id_cap);

    /* duplicate and insert */
    for (i = 0; i < gn->sub_id_cnt; i++) {
      if (i < index) {
        sub_id[i] = gn->sub_id[i];
        sub_ptr[i] = gn->sub_ptr[i];
      } else {
        sub_id[i + 1] = gn->sub_id[i];
        sub_ptr[i + 1] = gn->sub_ptr[i];
      }
    }

    /* abandon old ones */
    free(gn->sub_id);
    free(gn->sub_ptr);
    gn->sub_id = sub_id;
    gn->sub_ptr = sub_ptr;
  } else {
    /* Insert new sub-node(s) without expanding */
    for (i = gn->sub_id_cnt - 1; i >= index; i--) {
      gn->sub_id[i + 1] = gn->sub_id[i];
      gn->sub_ptr[i + 1] = gn->sub_ptr[i];
    }
  }
}
Example #15
0
static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
{
	struct treeent *ent;
	int len = strlen(path);
	if (strchr(path, '/'))
		die("path %s contains slash", path);

	if (alloc <= used) {
		alloc = alloc_nr(used);
		entries = xrealloc(entries, sizeof(*entries) * alloc);
	}
	ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1);
	ent->mode = mode;
	ent->len = len;
	hashcpy(ent->sha1, sha1);
	memcpy(ent->name, path, len+1);
}
Example #16
0
static void grow_hash_table(struct hash_table *table)
{
	unsigned int i;
	unsigned int old_size = table->size, new_size;
	struct hash_table_entry *old_array = table->array, *new_array;
	new_size = alloc_nr(old_size);
	new_array = xzmalloc(sizeof(struct hash_table_entry) * new_size);
	table->size = new_size;
	table->array = new_array;
	table->nr = 0;
	for (i = 0; i < old_size; i++) {
		unsigned int hash = old_array[i].hash;
		void *ptr = old_array[i].ptr;
		if (ptr)
			insert_hash_entry(hash, ptr, table);
	}
	if (old_array)
		xfree(old_array);
}
Example #17
0
int add_cache_entry(struct cache_entry *ce, int ok_to_add)
{
	int pos;

	pos = cache_name_pos(ce->name, htons(ce->ce_flags));

	/* existing match? Just replace it */
	if (pos >= 0) {
		active_cache[pos] = ce;
		return 0;
	}
	pos = -pos-1;

	/*
	 * Inserting a merged entry ("stage 0") into the index
	 * will always replace all non-merged entries..
	 */
	if (pos < active_nr && ce_stage(ce) == 0) {
		while (same_name(active_cache[pos], ce)) {
			ok_to_add = 1;
			if (!remove_entry_at(pos))
				break;
		}
	}

	if (!ok_to_add)
		return -1;

	/* Make sure the array is big enough .. */
	if (active_nr == active_alloc) {
		active_alloc = alloc_nr(active_alloc);
		active_cache = xrealloc(active_cache, active_alloc * sizeof(struct cache_entry *));
	}

	/* Add it in.. */
	active_nr++;
	if (active_nr > pos)
		memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
	active_cache[pos] = ce;
	return 0;
}
int main(int argc, char **argv)
{
	unsigned long size, offset, val;
	int i, entries = read_cache();
	char *buffer;

	if (entries <= 0) {
		fprintf(stderr, "No file-cache to create a tree of\n");
		exit(1);
	}

	/* Guess at an initial size */
	size = entries * 40 + 400;
	buffer = malloc(size);
	offset = ORIG_OFFSET;

	for (i = 0; i < entries; i++) {
		struct cache_entry *ce = active_cache[i];
		if (check_valid_sha1(ce->sha1) < 0)
			exit(1);
		if (offset + ce->namelen + 60 > size) {
			size = alloc_nr(offset + ce->namelen + 60);
			buffer = realloc(buffer, size);
		}
		offset += sprintf(buffer + offset, "%o %s", ce->st_mode, ce->name);
		buffer[offset++] = 0;
		memcpy(buffer + offset, ce->sha1, 20);
		offset += 20;
	}

	i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
	i -= 5;
	memcpy(buffer+i, "tree ", 5);

	buffer += i;
	offset -= i;

	write_sha1_file(buffer, offset);
	return 0;
}
Example #19
0
File: dir.c Project: CCorreia/git
static struct path_simplify *create_simplify(const char **pathspec)
{
	int nr, alloc = 0;
	struct path_simplify *simplify = NULL;

	if (!pathspec)
		return NULL;

	for (nr = 0 ; ; nr++) {
		const char *match;
		if (nr >= alloc) {
			alloc = alloc_nr(alloc);
			simplify = xrealloc(simplify, alloc * sizeof(*simplify));
		}
		match = *pathspec++;
		if (!match)
			break;
		simplify[nr].path = match;
		simplify[nr].len = simple_length(match);
	}
	simplify[nr].path = NULL;
	simplify[nr].len = 0;
	return simplify;
}
Example #20
0
/*
 * This is basically strbuf_read(), except that if we
 * hit max_request_buffer we die (we'd rather reject a
 * maliciously large request than chew up infinite memory).
 */
static ssize_t read_request(int fd, unsigned char **out)
{
	size_t len = 0, alloc = 8192;
	unsigned char *buf = xmalloc(alloc);

	if (max_request_buffer < alloc)
		max_request_buffer = alloc;

	while (1) {
		ssize_t cnt;

		cnt = read_in_full(fd, buf + len, alloc - len);
		if (cnt < 0) {
			free(buf);
			return -1;
		}

		/* partial read from read_in_full means we hit EOF */
		len += cnt;
		if (len < alloc) {
			*out = buf;
			return len;
		}

		/* otherwise, grow and try again (if we can) */
		if (alloc == max_request_buffer)
			die("request was larger than our maximum size (%lu);"
			    " try setting GIT_HTTP_MAX_REQUEST_BUFFER",
			    max_request_buffer);

		alloc = alloc_nr(alloc);
		if (alloc > max_request_buffer)
			alloc = max_request_buffer;
		REALLOC_ARRAY(buf, alloc);
	}
}
Example #21
0
static void insert_one_record(struct shortlog *log,
                              const char *author,
                              const char *oneline)
{
    const char *dot3 = log->common_repo_prefix;
    char *buffer, *p;
    struct path_list_item *item;
    struct path_list *onelines;
    char namebuf[1024];
    size_t len;
    const char *eol;
    const char *boemail, *eoemail;

    boemail = strchr(author, '<');
    if (!boemail)
        return;
    eoemail = strchr(boemail, '>');
    if (!eoemail)
        return;
    if (!map_email(&log->mailmap, boemail+1, namebuf, sizeof(namebuf))) {
        while (author < boemail && isspace(*author))
            author++;
        for (len = 0;
                len < sizeof(namebuf) - 1 && author + len < boemail;
                len++)
            namebuf[len] = author[len];
        while (0 < len && isspace(namebuf[len-1]))
            len--;
        namebuf[len] = '\0';
    }
    else
        len = strlen(namebuf);

    if (log->email) {
        size_t room = sizeof(namebuf) - len - 1;
        int maillen = eoemail - boemail + 1;
        snprintf(namebuf + len, room, " %.*s", maillen, boemail);
    }

    buffer = xstrdup(namebuf);
    item = path_list_insert(buffer, &log->list);
    if (item->util == NULL)
        item->util = xcalloc(1, sizeof(struct path_list));
    else
        free(buffer);

    /* Skip any leading whitespace, including any blank lines. */
    while (*oneline && isspace(*oneline))
        oneline++;
    eol = strchr(oneline, '\n');
    if (!eol)
        eol = oneline + strlen(oneline);
    if (!prefixcmp(oneline, "[PATCH")) {
        char *eob = strchr(oneline, ']');
        if (eob && (!eol || eob < eol))
            oneline = eob + 1;
    }
    while (*oneline && isspace(*oneline) && *oneline != '\n')
        oneline++;
    len = eol - oneline;
    while (len && isspace(oneline[len-1]))
        len--;
    buffer = xmemdupz(oneline, len);

    if (dot3) {
        int dot3len = strlen(dot3);
        if (dot3len > 5) {
            while ((p = strstr(buffer, dot3)) != NULL) {
                int taillen = strlen(p) - dot3len;
                memcpy(p, "/.../", 5);
                memmove(p + 5, p + dot3len, taillen + 1);
            }
        }
    }

    onelines = item->util;
    if (onelines->nr >= onelines->alloc) {
        onelines->alloc = alloc_nr(onelines->nr);
        onelines->items = xrealloc(onelines->items,
                                   onelines->alloc
                                   * sizeof(struct path_list_item));
    }

    onelines->items[onelines->nr].util = NULL;
    onelines->items[onelines->nr++].path = buffer;
}
Example #22
0
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
	struct ref_list *ref_list = (struct ref_list*)(cb_data);
	struct ref_item *newitem;
	struct commit *commit;
	int kind, i;
	const char *prefix, *orig_refname = refname;

	static struct {
		int kind;
		const char *prefix;
		int pfxlen;
	} ref_kind[] = {
		{ REF_LOCAL_BRANCH, "refs/heads/", 11 },
		{ REF_REMOTE_BRANCH, "refs/remotes/", 13 },
	};

	/* Detect kind */
	for (i = 0; i < ARRAY_SIZE(ref_kind); i++) {
		prefix = ref_kind[i].prefix;
		if (strncmp(refname, prefix, ref_kind[i].pfxlen))
			continue;
		kind = ref_kind[i].kind;
		refname += ref_kind[i].pfxlen;
		break;
	}
	if (ARRAY_SIZE(ref_kind) <= i)
		return 0;

	/* Don't add types the caller doesn't want */
	if ((kind & ref_list->kinds) == 0)
		return 0;

	commit = NULL;
	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
		commit = lookup_commit_reference_gently(sha1, 1);
		if (!commit)
			return error("branch '%s' does not point at a commit", refname);

		/* Filter with with_commit if specified */
		if (!is_descendant_of(commit, ref_list->with_commit))
			return 0;

		if (merge_filter != NO_FILTER)
			add_pending_object(&ref_list->revs,
					   (struct object *)commit, refname);
	}

	/* Resize buffer */
	if (ref_list->index >= ref_list->alloc) {
		ref_list->alloc = alloc_nr(ref_list->alloc);
		ref_list->list = xrealloc(ref_list->list,
				ref_list->alloc * sizeof(struct ref_item));
	}

	/* Record the new item */
	newitem = &(ref_list->list[ref_list->index++]);
	newitem->name = xstrdup(refname);
	newitem->kind = kind;
	newitem->commit = commit;
	newitem->len = strlen(refname);
	newitem->dest = resolve_symref(orig_refname, prefix);
	/* adjust for "remotes/" */
	if (newitem->kind == REF_REMOTE_BRANCH &&
	    ref_list->kinds != REF_REMOTE_BRANCH)
		newitem->len += 8;
	if (newitem->len > ref_list->maxwidth)
		ref_list->maxwidth = newitem->len;

	return 0;
}
Example #23
0
static int write_index(git_oid *oid, git_index *index, const char *base, int baselen, int entry_no, int maxentries)
{
	size_t size, offset;
	char *buffer;
	int nr, error;

	/* Guess at some random initial size */
	size = maxentries * 40;
	buffer = git__malloc(size);
	if (buffer == NULL)
		return GIT_ENOMEM;
		
	offset = 0;
	
	for (nr = entry_no; nr < maxentries; ++nr) {
		git_index_entry *entry = git_index_get(index, nr);

		const char *pathname = entry->path, *filename, *dirname;
		int pathlen = strlen(pathname), entrylen;

		unsigned int write_mode;
		git_oid subtree_oid;
		git_oid *write_oid;
		
		/* Did we hit the end of the directory? Return how many we wrote */
		if (baselen >= pathlen || memcmp(base, pathname, baselen) != 0)
			break;
		
		/* Do we have _further_ subdirectories? */
		filename = pathname + baselen;
		dirname = strchr(filename, '/');

		write_oid = &entry->oid;
		write_mode = entry->mode;

		if (dirname) {
			int subdir_written;

#if 0
			if (entry->mode != S_IFDIR) {
				free(buffer);
				return GIT_EOBJCORRUPTED;
			}
#endif
			subdir_written = write_index(&subtree_oid, index, pathname, dirname - pathname + 1, nr, maxentries);

			if (subdir_written < GIT_SUCCESS) {
				free(buffer);
				return subdir_written;
			}
			
			nr = subdir_written - 1;
			
			/* Now we need to write out the directory entry into this tree.. */
			pathlen = dirname - pathname;
			write_oid = &subtree_oid;
			write_mode = S_IFDIR;
		}

		entrylen = pathlen - baselen;
		if (offset + entrylen + 32 > size) {
			size = alloc_nr(offset + entrylen + 32);
			buffer = git__realloc(buffer, size);
			
			if (buffer == NULL)
				return GIT_ENOMEM;
		}

		offset += write_index_entry(buffer + offset, write_mode, filename, entrylen, write_oid);
	}
	
	error = git_odb_write(oid, index->repository->db, buffer, offset, GIT_OBJ_TREE);
	free(buffer);

	return (error == GIT_SUCCESS) ? nr : error;
}