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; }
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; }
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++; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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"); }
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++; }
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; }
/* 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]; } } }
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); }
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); }
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; }
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; }
/* * 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); } }
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; }
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; }
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; }