int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, struct exclude_list *el, int check_index) { struct stat st; int fd, i, lineno = 1; size_t size = 0; char *buf, *entry; fd = open(fname, O_RDONLY); if (fd < 0 || fstat(fd, &st) < 0) { if (errno != ENOENT) warn_on_inaccessible(fname); if (0 <= fd) close(fd); if (!check_index || (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL) return -1; if (size == 0) { free(buf); return 0; } if (buf[size-1] != '\n') { buf = xrealloc(buf, size+1); buf[size++] = '\n'; } } else { size = xsize_t(st.st_size); if (size == 0) { close(fd); return 0; } buf = xmalloc(size+1); if (read_in_full(fd, buf, size) != size) { free(buf); close(fd); return -1; } buf[size++] = '\n'; close(fd); } el->filebuf = buf; entry = buf; for (i = 0; i < size; i++) { if (buf[i] == '\n') { if (entry != buf + i && entry[0] != '#') { buf[i - (i && buf[i-1] == '\r')] = 0; trim_trailing_spaces(entry); add_exclude(entry, base, baselen, el, lineno); } lineno++; entry = buf + i + 1; } } return 0; }
/* * Try to read the location of the git directory from the .git file, * return path to git directory if found. */ const char *read_gitfile_gently(const char *path) { char *buf; struct stat st; int fd; size_t len; if (stat(path, &st)) return NULL; if (!S_ISREG(st.st_mode)) return NULL; fd = open(path, O_RDONLY); if (fd < 0) die_errno("Error opening '%s'", path); buf = xmalloc(st.st_size + 1); len = read_in_full(fd, buf, st.st_size); close(fd); if (len != st.st_size) die("Error reading %s", path); buf[len] = '\0'; if (prefixcmp(buf, "gitdir: ")) die("Invalid gitfile format: %s", path); while (buf[len - 1] == '\n' || buf[len - 1] == '\r') len--; if (len < 9) die("No path in gitfile: %s", path); buf[len] = '\0'; if (!is_git_directory(buf + 8)) die("Not a git repository: %s", buf + 8); path = make_absolute_path(buf + 8); free(buf); return path; }
static int grep_source_load_file(struct grep_source *gs) { const char *filename = gs->identifier; struct stat st; char *data; size_t size; int i; if (lstat(filename, &st) < 0) { err_ret: if (errno != ENOENT) error(_("'%s': %s"), filename, strerror(errno)); return -1; } if (!S_ISREG(st.st_mode)) return -1; size = xsize_t(st.st_size); i = open(filename, O_RDONLY); if (i < 0) goto err_ret; data = xmalloc(size + 1); if (st.st_size != read_in_full(i, data, size)) { error(_("'%s': short read %s"), filename, strerror(errno)); close(i); free(data); return -1; } close(i); data[size] = 0; gs->buf = data; gs->size = size; return 0; }
static int grep_file(struct grep_opt *opt, const char *filename) { struct stat st; int i; char *data; size_t sz; if (lstat(filename, &st) < 0) { err_ret: if (errno != ENOENT) error("'%s': %s", filename, strerror(errno)); return 0; } if (!st.st_size) return 0; /* empty file -- no grep hit */ if (!S_ISREG(st.st_mode)) return 0; sz = xsize_t(st.st_size); i = open(filename, O_RDONLY); if (i < 0) goto err_ret; data = xmalloc(sz + 1); if (st.st_size != read_in_full(i, data, sz)) { error("'%s': short read %s", filename, strerror(errno)); close(i); free(data); return 0; } close(i); if (opt->relative && opt->prefix_length) filename += opt->prefix_length; i = grep_buffer(opt, filename, data, sz); free(data); return i; }
static int read_loose_refs(struct strbuf *path, int name_offset, struct ref **tail) { DIR *dir = opendir(path->buf); struct dirent *de; struct { char **entries; int nr, alloc; } list; int i, pathlen; if (!dir) return -1; memset (&list, 0, sizeof(list)); while ((de = readdir(dir))) { if (is_dot_or_dotdot(de->d_name)) continue; ALLOC_GROW(list.entries, list.nr + 1, list.alloc); list.entries[list.nr++] = xstrdup(de->d_name); } closedir(dir); /* sort the list */ qsort(list.entries, list.nr, sizeof(char *), str_cmp); pathlen = path->len; strbuf_addch(path, '/'); for (i = 0; i < list.nr; i++, strbuf_setlen(path, pathlen + 1)) { strbuf_addstr(path, list.entries[i]); if (read_loose_refs(path, name_offset, tail)) { int fd = open(path->buf, O_RDONLY); char buffer[40]; struct ref *next; if (fd < 0) continue; next = alloc_ref(path->buf + name_offset); if (read_in_full(fd, buffer, 40) != 40 || get_sha1_hex(buffer, next->old_sha1)) { close(fd); free(next); continue; } close(fd); (*tail)->next = next; *tail = next; } } strbuf_setlen(path, pathlen); for (i = 0; i < list.nr; i++) free(list.entries[i]); free(list.entries); return 0; }
ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) { size_t oldlen = sb->len; size_t oldalloc = sb->alloc; strbuf_grow(sb, hint ? hint : 8192); for (;;) { ssize_t want = sb->alloc - sb->len - 1; ssize_t got = read_in_full(fd, sb->buf + sb->len, want); if (got < 0) { if (oldalloc == 0) strbuf_release(sb); else strbuf_setlen(sb, oldlen); return -1; } sb->len += got; if (got < want) break; strbuf_grow(sb, 8192); } sb->buf[sb->len] = '\0'; return sb->len - oldlen; }
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; char *content = buffer + RECORDSIZE; const char *comment; ssize_t n; if (argc != 1) usage(builtin_get_tar_commit_id_usage); git_config(git_default_config, NULL); n = read_in_full(0, buffer, HEADERSIZE); if (n < 0) die_errno("git get-tar-commit-id: read error"); if (n != HEADERSIZE) die_errno("git get-tar-commit-id: EOF before reading tar header"); if (header->typeflag[0] != 'g') return 1; if (!skip_prefix(content, "52 comment=", &comment)) return 1; if (write_in_full(1, comment, 41) < 0) die_errno("git get-tar-commit-id: write error"); return 0; }
static int send_request(const char *socket, const struct strbuf *out) { int got_data = 0; int fd = unix_stream_connect(socket); if (fd < 0) return -1; if (write_in_full(fd, out->buf, out->len) < 0) die_errno("unable to write to cache daemon"); shutdown(fd, SHUT_WR); while (1) { char in[1024]; int r; r = read_in_full(fd, in, sizeof(in)); if (r == 0) break; if (r < 0) die_errno("read error from cache daemon"); write_or_die(1, in, r); got_data = 1; } return got_data; }
static const char *prune_repo_dir(const char *id, struct stat *st) { char *path; int fd, len; if (file_exists(git_path("repos/%s/locked", id))) return NULL; if (stat(git_path("repos/%s/gitdir", id), st)) { st->st_mtime = expire; return _("gitdir does not exist"); } fd = open(git_path("repos/%s/gitdir", id), O_RDONLY); len = st->st_size; path = xmalloc(len + 1); read_in_full(fd, path, len); close(fd); while (path[len - 1] == '\n' || path[len - 1] == '\r') len--; path[len] = '\0'; if (!file_exists(path)) { struct stat st_link; free(path); /* * the repo is moved manually and has not been * accessed since? */ if (!stat(git_path("repos/%s/link", id), &st_link) && st_link.st_nlink > 1) return NULL; return _("gitdir points to non-existing file"); } free(path); return NULL; }
static void *load_file(const char *filename, size_t *sz) { struct stat st; char *data; int i; if (lstat(filename, &st) < 0) { err_ret: if (errno != ENOENT) error("'%s': %s", filename, strerror(errno)); return 0; } if (!S_ISREG(st.st_mode)) return 0; *sz = xsize_t(st.st_size); i = open(filename, O_RDONLY); if (i < 0) goto err_ret; data = xmalloc(*sz + 1); if (st.st_size != read_in_full(i, data, *sz)) { error("'%s': short read %s", filename, strerror(errno)); close(i); free(data); return 0; } close(i); data[*sz] = 0; return data; }
static int get_packet_data(int fd, char **src_buf, size_t *src_size, void *dst, unsigned size, int options) { ssize_t ret; if (fd >= 0 && src_buf && *src_buf) die("BUG: multiple sources given to packet_read"); /* Read up to "size" bytes from our source, whatever it is. */ if (src_buf && *src_buf) { ret = size < *src_size ? size : *src_size; memcpy(dst, *src_buf, ret); *src_buf += ret; *src_size -= ret; } else { ret = read_in_full(fd, dst, size); if (ret < 0) die_errno("read error"); } /* And complain if we didn't get enough bytes to satisfy the read. */ if (ret < size) { if (options & PACKET_READ_GENTLE_ON_EOF) return -1; die("The remote end hung up unexpectedly"); } return ret; }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, const char *orig_name, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, const struct ll_merge_options *opts, int marker_size) { char temp[4][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[6]; struct strbuf path_sq = STRBUF_INIT; const char *args[] = { NULL, NULL }; int status, fd, i; struct stat st; assert(opts); sq_quote_buf(&path_sq, path); dict[0].placeholder = "O"; dict[0].value = temp[0]; dict[1].placeholder = "A"; dict[1].value = temp[1]; dict[2].placeholder = "B"; dict[2].value = temp[2]; dict[3].placeholder = "L"; dict[3].value = temp[3]; dict[4].placeholder = "P"; dict[4].value = path_sq.buf; dict[5].placeholder = NULL; dict[5].value = NULL; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0], sizeof(temp[0])); create_temp(src1, temp[1], sizeof(temp[1])); create_temp(src2, temp[2], sizeof(temp[2])); xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[0] = cmd.buf; status = run_command_v_opt(args, RUN_USING_SHELL); fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmallocz(result->size); if (read_in_full(fd, result->ptr, result->size) != result->size) { FREE_AND_NULL(result->ptr); result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); strbuf_release(&path_sq); return status; }
static void safe_read(int fd, void *buffer, unsigned size) { ssize_t ret = read_in_full(fd, buffer, size); if (ret < 0) die_errno("read error"); else if (ret < size) die("The remote end hung up unexpectedly"); }
int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index) { struct stat st; int fd, i; size_t size = 0; char *buf, *entry; fd = open(fname, O_RDONLY); if (fd < 0 || fstat(fd, &st) < 0) { if (0 <= fd) close(fd); if (!check_index || (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL) return -1; if (size == 0) { free(buf); return 0; } if (buf[size-1] != '\n') { buf = xrealloc(buf, size+1); buf[size++] = '\n'; } } else { size = xsize_t(st.st_size); if (size == 0) { close(fd); return 0; } buf = xmalloc(size+1); if (read_in_full(fd, buf, size) != size) { free(buf); close(fd); return -1; } buf[size++] = '\n'; close(fd); } if (buf_p) *buf_p = buf; entry = buf; for (i = 0; i < size; i++) { if (buf[i] == '\n') { if (entry != buf + i && entry[0] != '#') { buf[i - (i && buf[i-1] == '\r')] = 0; add_exclude(entry, base, baselen, which); } entry = buf + i + 1; } } return 0; }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, int virtual_ancestor) { char temp[3][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[] = { { "O", temp[0] }, { "A", temp[1] }, { "B", temp[2] }, { NULL } }; const char *args[] = { "sh", "-c", NULL, NULL }; int status, fd, i; struct stat st; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0]); create_temp(src1, temp[1]); create_temp(src2, temp[2]); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[2] = cmd.buf; status = run_command_v_opt(args, 0); if (status < -ERR_RUN_COMMAND_FORK) ; /* failure in run-command */ else status = -status; fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmalloc(result->size + 1); if (read_in_full(fd, result->ptr, result->size) != result->size) { free(result->ptr); result->ptr = NULL; result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); return status; }
/* * User defined low-level merge driver support. */ static int ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, mmfile_t *orig, mmfile_t *src1, const char *name1, mmfile_t *src2, const char *name2, int flag, int marker_size) { char temp[4][50]; struct strbuf cmd = STRBUF_INIT; struct strbuf_expand_dict_entry dict[] = { { "O", temp[0] }, { "A", temp[1] }, { "B", temp[2] }, { "L", temp[3] }, { NULL } }; const char *args[] = { NULL, NULL }; int status, fd, i; struct stat st; if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); result->ptr = NULL; result->size = 0; create_temp(orig, temp[0]); create_temp(src1, temp[1]); create_temp(src2, temp[2]); sprintf(temp[3], "%d", marker_size); strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); args[0] = cmd.buf; status = run_command_v_opt(args, RUN_USING_SHELL); fd = open(temp[1], O_RDONLY); if (fd < 0) goto bad; if (fstat(fd, &st)) goto close_bad; result->size = st.st_size; result->ptr = xmalloc(result->size + 1); if (read_in_full(fd, result->ptr, result->size) != result->size) { free(result->ptr); result->ptr = NULL; result->size = 0; } close_bad: close(fd); bad: for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); return status; }
static int prune_worktree(const char *id, struct strbuf *reason) { struct stat st; char *path; int fd, len; if (!is_directory(git_path("worktrees/%s", id))) { strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id); return 1; } if (file_exists(git_path("worktrees/%s/locked", id))) return 0; if (stat(git_path("worktrees/%s/gitdir", id), &st)) { strbuf_addf(reason, _("Removing worktrees/%s: gitdir file does not exist"), id); return 1; } fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY); if (fd < 0) { strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"), id, strerror(errno)); return 1; } len = st.st_size; path = xmallocz(len); read_in_full(fd, path, len); close(fd); while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) len--; if (!len) { strbuf_addf(reason, _("Removing worktrees/%s: invalid gitdir file"), id); free(path); return 1; } path[len] = '\0'; if (!file_exists(path)) { struct stat st_link; free(path); /* * the repo is moved manually and has not been * accessed since? */ if (!stat(git_path("worktrees/%s/link", id), &st_link) && st_link.st_nlink > 1) return 0; if (st.st_mtime <= expire) { strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id); return 1; } else { return 0; } } free(path); return 0; }
/* * Try to read the location of the git directory from the .git file, * return path to git directory if found. */ const char *read_gitfile(const char *path) { char *buf; char *dir; const char *slash; struct stat st; int fd; ssize_t len; if (stat(path, &st)) return NULL; if (!S_ISREG(st.st_mode)) return NULL; fd = open(path, O_RDONLY); if (fd < 0) die_errno("Error opening '%s'", path); buf = xmalloc(st.st_size + 1); len = read_in_full(fd, buf, st.st_size); close(fd); if (len != st.st_size) die("Error reading %s", path); buf[len] = '\0'; if (!starts_with(buf, "gitdir: ")) die("Invalid gitfile format: %s", path); while (buf[len - 1] == '\n' || buf[len - 1] == '\r') len--; if (len < 9) die("No path in gitfile: %s", path); buf[len] = '\0'; dir = buf + 8; if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) { size_t pathlen = slash+1 - path; size_t dirlen = pathlen + len - 8; dir = xmalloc(dirlen + 1); strncpy(dir, path, pathlen); strncpy(dir + pathlen, buf + 8, len - 8); dir[dirlen] = '\0'; free(buf); buf = dir; } if (!is_git_directory(dir)) die("Not a git repository: %s", dir); update_linked_gitdir(path, dir); path = real_path(dir); free(buf); return path; }
int validate_headref(const char *path) { struct stat st; char buffer[256]; const char *refname; struct object_id oid; int fd; ssize_t len; if (lstat(path, &st) < 0) return -1; /* Make sure it is a "refs/.." symlink */ if (S_ISLNK(st.st_mode)) { len = readlink(path, buffer, sizeof(buffer)-1); if (len >= 5 && !memcmp("refs/", buffer, 5)) return 0; return -1; } /* * Anything else, just open it and try to see if it is a symbolic ref. */ fd = open(path, O_RDONLY); if (fd < 0) return -1; len = read_in_full(fd, buffer, sizeof(buffer)-1); close(fd); if (len < 0) return -1; buffer[len] = '\0'; /* * Is it a symbolic ref? */ if (skip_prefix(buffer, "ref:", &refname)) { while (isspace(*refname)) refname++; if (starts_with(refname, "refs/")) return 0; } /* * Is this a detached HEAD? */ if (!get_oid_hex(buffer, &oid)) return 0; return -1; }
int validate_headref(const char *path) { struct stat st; char *buf, buffer[256]; unsigned char sha1[20]; int fd; ssize_t len; if (lstat(path, &st) < 0) return -1; /* Make sure it is a "refs/.." symlink */ if (S_ISLNK(st.st_mode)) { len = readlink(path, buffer, sizeof(buffer)-1); if (len >= 5 && !memcmp("refs/", buffer, 5)) return 0; return -1; } /* * Anything else, just open it and try to see if it is a symbolic ref. */ fd = open(path, O_RDONLY); if (fd < 0) return -1; len = read_in_full(fd, buffer, sizeof(buffer)-1); close(fd); /* * Is it a symbolic ref? */ if (len < 4) return -1; if (!memcmp("ref:", buffer, 4)) { buf = buffer + 4; len -= 4; while (len && isspace(*buf)) buf++, len--; if (len >= 5 && !memcmp("refs/", buf, 5)) return 0; } /* * Is this a detached HEAD? */ if (!get_sha1_hex(buffer, sha1)) return 0; return -1; }
/* * Depending on `mmap_strategy`, either mmap or read the contents of * the `packed-refs` file into the snapshot. Return 1 if the file * existed and was read, or 0 if the file was absent. Die on errors. */ static int load_contents(struct snapshot *snapshot) { int fd; struct stat st; size_t size; ssize_t bytes_read; fd = open(snapshot->refs->path, O_RDONLY); if (fd < 0) { if (errno == ENOENT) { /* * This is OK; it just means that no * "packed-refs" file has been written yet, * which is equivalent to it being empty, * which is its state when initialized with * zeros. */ return 0; } else { die_errno("couldn't read %s", snapshot->refs->path); } } stat_validity_update(&snapshot->validity, fd); if (fstat(fd, &st) < 0) die_errno("couldn't stat %s", snapshot->refs->path); size = xsize_t(st.st_size); switch (mmap_strategy) { case MMAP_NONE: snapshot->buf = xmalloc(size); bytes_read = read_in_full(fd, snapshot->buf, size); if (bytes_read < 0 || bytes_read != size) die_errno("couldn't read %s", snapshot->refs->path); snapshot->eof = snapshot->buf + size; snapshot->mmapped = 0; break; case MMAP_TEMPORARY: case MMAP_OK: snapshot->buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); snapshot->eof = snapshot->buf + size; snapshot->mmapped = 1; break; } close(fd); return 1; }
ssize_t git_pread(int fd, void *buf, size_t count, off_t offset) { off_t current_offset; ssize_t rc; current_offset = lseek(fd, 0, SEEK_CUR); if (lseek(fd, offset, SEEK_SET) < 0) return -1; rc = read_in_full(fd, buf, count); if (current_offset != lseek(fd, current_offset, SEEK_SET)) return -1; return rc; }
static int add_excludes_from_file_1(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which) { struct stat st; int fd, i; size_t size; char *buf, *entry; fd = open(fname, O_RDONLY); if (fd < 0 || fstat(fd, &st) < 0) goto err; size = xsize_t(st.st_size); if (size == 0) { close(fd); return 0; } buf = xmalloc(size+1); if (read_in_full(fd, buf, size) != size) { free(buf); goto err; } close(fd); if (buf_p) *buf_p = buf; buf[size++] = '\n'; entry = buf; for (i = 0; i < size; i++) { if (buf[i] == '\n') { if (entry != buf + i && entry[0] != '#') { buf[i - (i && buf[i-1] == '\r')] = 0; add_exclude(entry, base, baselen, which); } entry = buf + i + 1; } } return 0; err: if (0 <= fd) close(fd); return -1; }
static const char *get_repo_path_1(struct strbuf *path, int *is_bundle) { static char *suffix[] = { "/.git", "", ".git/.git", ".git" }; static char *bundle_suffix[] = { ".bundle", "" }; size_t baselen = path->len; struct stat st; int i; for (i = 0; i < ARRAY_SIZE(suffix); i++) { strbuf_setlen(path, baselen); strbuf_addstr(path, suffix[i]); if (stat(path->buf, &st)) continue; if (S_ISDIR(st.st_mode) && is_git_directory(path->buf)) { *is_bundle = 0; return path->buf; } else if (S_ISREG(st.st_mode) && st.st_size > 8) { /* Is it a "gitfile"? */ char signature[8]; const char *dst; int len, fd = open(path->buf, O_RDONLY); if (fd < 0) continue; len = read_in_full(fd, signature, 8); close(fd); if (len != 8 || strncmp(signature, "gitdir: ", 8)) continue; dst = read_gitfile(path->buf); if (dst) { *is_bundle = 0; return dst; } } } for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) { strbuf_setlen(path, baselen); strbuf_addstr(path, bundle_suffix[i]); if (!stat(path->buf, &st) && S_ISREG(st.st_mode)) { *is_bundle = 1; return path->buf; } } return NULL; }
static char *get_repo_path(const char *repo, int *is_bundle) { static char *suffix[] = { "/.git", "", ".git/.git", ".git" }; static char *bundle_suffix[] = { ".bundle", "" }; struct stat st; int i; for (i = 0; i < ARRAY_SIZE(suffix); i++) { const char *path; path = mkpath("%s%s", repo, suffix[i]); if (stat(path, &st)) continue; if (S_ISDIR(st.st_mode) && is_git_directory(path)) { *is_bundle = 0; return xstrdup(absolute_path(path)); } else if (S_ISREG(st.st_mode) && st.st_size > 8) { /* Is it a "gitfile"? */ char signature[8]; int len, fd = open(path, O_RDONLY); if (fd < 0) continue; len = read_in_full(fd, signature, 8); close(fd); if (len != 8 || strncmp(signature, "gitdir: ", 8)) continue; path = read_gitfile(path); if (path) { *is_bundle = 0; return xstrdup(absolute_path(path)); } } } for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) { const char *path; path = mkpath("%s%s", repo, bundle_suffix[i]); if (!stat(path, &st) && S_ISREG(st.st_mode)) { *is_bundle = 1; return xstrdup(absolute_path(path)); } } return NULL; }
static ssize_t read_request_fixed_len(int fd, ssize_t req_len, unsigned char **out) { unsigned char *buf = NULL; ssize_t cnt = 0; if (max_request_buffer < req_len) { die("request was larger than our maximum size (%lu): " "%" PRIuMAX "; try setting GIT_HTTP_MAX_REQUEST_BUFFER", max_request_buffer, (uintmax_t)req_len); } buf = xmalloc(req_len); cnt = read_in_full(fd, buf, req_len); if (cnt < 0) { free(buf); return -1; } *out = buf; return cnt; }
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; char *content = buffer + RECORDSIZE; ssize_t n; n = read_in_full(0, buffer, HEADERSIZE); if (n < HEADERSIZE) die("git get-tar-commit-id: read error"); if (header->typeflag[0] != 'g') return 1; if (memcmp(content, "52 comment=", 11)) return 1; n = write_in_full(1, content + 11, 41); if (n < 41) die("git get-tar-commit-id: write error"); return 0; }
static void spawn_daemon(const char *socket) { struct child_process daemon = CHILD_PROCESS_INIT; const char *argv[] = { NULL, NULL, NULL }; char buf[128]; int r; argv[0] = "git-credential-cache--daemon"; argv[1] = socket; daemon.argv = argv; daemon.no_stdin = 1; daemon.out = -1; if (start_command(&daemon)) die_errno("unable to start cache daemon"); r = read_in_full(daemon.out, buf, sizeof(buf)); if (r < 0) die_errno("unable to read result code from cache daemon"); if (r != 3 || memcmp(buf, "ok\n", 3)) die("cache daemon did not start: %.*s", r, buf); close(daemon.out); }
static int get_reachable_list(struct object_array *src, struct object_array *reachable) { struct child_process cmd = CHILD_PROCESS_INIT; int i; struct object *o; char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ const unsigned hexsz = the_hash_algo->hexsz; if (do_reachable_revlist(&cmd, src, reachable) < 0) return -1; while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) { struct object_id sha1; const char *p; if (parse_oid_hex(namebuf, &sha1, &p) || *p != '\n') break; o = lookup_object(sha1.hash); if (o && o->type == OBJ_COMMIT) { o->flags &= ~TMP_MARK; } } for (i = get_max_object_index(); 0 < i; i--) { o = get_indexed_object(i - 1); if (o && o->type == OBJ_COMMIT && (o->flags & TMP_MARK)) { add_object_array(o, NULL, reachable); o->flags &= ~TMP_MARK; } } close(cmd.out); if (finish_command(&cmd)) return -1; return 0; }
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; char *content = buffer + RECORDSIZE; const char *comment; ssize_t n; long len; char *end; if (argc != 1) usage(builtin_get_tar_commit_id_usage); git_config(git_default_config, NULL); n = read_in_full(0, buffer, HEADERSIZE); if (n < 0) die_errno("git get-tar-commit-id: read error"); if (n != HEADERSIZE) die_errno("git get-tar-commit-id: EOF before reading tar header"); if (header->typeflag[0] != 'g') return 1; len = strtol(content, &end, 10); if (errno == ERANGE || end == content || len < 0) return 1; if (!skip_prefix(end, " comment=", &comment)) return 1; len -= comment - content; if (len < 1 || !(len % 2) || hash_algo_by_length((len - 1) / 2) == GIT_HASH_UNKNOWN) return 1; if (write_in_full(1, comment, len) < 0) die_errno("git get-tar-commit-id: write error"); return 0; }