/* * Run "gpg" to see if the payload matches the detached signature. * gpg_output, when set, receives the diagnostic output from GPG. * gpg_status, when set, receives the status output from GPG. */ int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL}; char path[PATH_MAX]; int fd, ret; struct strbuf buf = STRBUF_INIT; struct strbuf *pbuf = &buf; args_gpg[0] = gpg_program; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX"); if (fd < 0) return error(_("could not create temporary file '%s': %s"), path, strerror(errno)); if (write_in_full(fd, signature, signature_size) < 0) return error(_("failed writing detached signature to '%s': %s"), path, strerror(errno)); close(fd); gpg.argv = args_gpg; gpg.in = -1; gpg.out = -1; if (gpg_output) gpg.err = -1; args_gpg[3] = path; if (start_command(&gpg)) { unlink(path); return error(_("could not run gpg.")); } sigchain_push(SIGPIPE, SIG_IGN); write_in_full(gpg.in, payload, payload_size); close(gpg.in); if (gpg_output) { strbuf_read(gpg_output, gpg.err, 0); close(gpg.err); } if (gpg_status) pbuf = gpg_status; strbuf_read(pbuf, gpg.out, 0); close(gpg.out); ret = finish_command(&gpg); sigchain_pop(SIGPIPE); unlink_or_warn(path); ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(&buf); /* no matter it was used or not */ return ret; }
static int save_state(unsigned char *stash) { int len; struct child_process cp; struct strbuf buffer = STRBUF_INIT; const char *argv[] = {"stash", "create", NULL}; memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.out = -1; cp.git_cmd = 1; if (start_command(&cp)) die(_("could not run stash.")); len = strbuf_read(&buffer, cp.out, 1024); close(cp.out); if (finish_command(&cp) || len < 0) die(_("stash failed")); else if (!len) /* no changes */ return -1; strbuf_setlen(&buffer, buffer.len-1); if (get_sha1(buffer.buf, stash)) die(_("not a valid object: %s"), buffer.buf); return 0; }
static int is_submodule_commit_present(const char *path, unsigned char sha1[20]) { int is_present = 0; if (!add_submodule_odb(path) && lookup_commit_reference(sha1)) { /* Even if the submodule is checked out and the commit is * present, make sure it is reachable from a ref. */ struct child_process cp; const char *argv[] = {"rev-list", "-n", "1", NULL, "--not", "--all", NULL}; struct strbuf buf = STRBUF_INIT; argv[3] = sha1_to_hex(sha1); memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = local_repo_env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; cp.dir = path; if (!run_command(&cp) && !strbuf_read(&buf, cp.out, 1024)) is_present = 1; close(cp.out); strbuf_release(&buf); } return is_present; }
int cmd_mktag(int argc, const char **argv, const char *prefix) { struct strbuf buf = STRBUF_INIT; struct object_id result; if (argc != 1) usage("git mktag"); git_config(git_default_config, NULL); if (strbuf_read(&buf, 0, 4096) < 0) { die_errno("could not read from stdin"); } /* Verify it for some basic sanity: it needs to start with "object <sha1>\ntype\ntagger " */ if (verify_tag(buf.buf, buf.len) < 0) die("invalid tag signature file"); if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0) die("unable to write tag file"); strbuf_release(&buf); printf("%s\n", oid_to_hex(&result)); return 0; }
static int run_access_hook(struct daemon_service *service, const char *dir, const char *path, struct hostinfo *hi) { struct child_process child = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; const char *argv[8]; const char **arg = argv; char *eol; int seen_errors = 0; *arg++ = access_hook; *arg++ = service->name; *arg++ = path; *arg++ = hi->hostname.buf; *arg++ = get_canon_hostname(hi); *arg++ = get_ip_address(hi); *arg++ = hi->tcp_port.buf; *arg = NULL; child.use_shell = 1; child.argv = argv; child.no_stdin = 1; child.no_stderr = 1; child.out = -1; if (start_command(&child)) { logerror("daemon access hook '%s' failed to start", access_hook); goto error_return; } if (strbuf_read(&buf, child.out, 0) < 0) { logerror("failed to read from pipe to daemon access hook '%s'", access_hook); strbuf_reset(&buf); seen_errors = 1; } if (close(child.out) < 0) { logerror("failed to close pipe to daemon access hook '%s'", access_hook); seen_errors = 1; } if (finish_command(&child)) seen_errors = 1; if (!seen_errors) { strbuf_release(&buf); return 0; } error_return: strbuf_ltrim(&buf); if (!buf.len) strbuf_addstr(&buf, "service rejected"); eol = strchr(buf.buf, '\n'); if (eol) *eol = '\0'; errno = EACCES; daemon_error(dir, buf.buf); strbuf_release(&buf); return -1; }
static void write_commented_object(int fd, const unsigned char *object) { const char *show_args[5] = {"show", "--stat", "--no-notes", sha1_to_hex(object), NULL}; struct child_process show = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; struct strbuf cbuf = STRBUF_INIT; /* Invoke "git show --stat --no-notes $object" */ show.argv = show_args; show.no_stdin = 1; show.out = -1; show.err = 0; show.git_cmd = 1; if (start_command(&show)) die(_("unable to start 'show' for object '%s'"), sha1_to_hex(object)); if (strbuf_read(&buf, show.out, 0) < 0) die_errno(_("could not read 'show' output")); strbuf_add_commented_lines(&cbuf, buf.buf, buf.len); write_or_die(fd, cbuf.buf, cbuf.len); strbuf_release(&cbuf); strbuf_release(&buf); if (finish_command(&show)) die(_("failed to finish 'show' for object '%s'"), sha1_to_hex(object)); }
void cmd_adduser(void) { Ceo__AddUser *in_proto; Ceo__AddUserResponse *out_proto = response_create(); struct strbuf in = STRBUF_INIT; struct strbuf out = STRBUF_INIT; if (strbuf_read(&in, STDIN_FILENO, 0) < 0) fatalpe("read"); in_proto = ceo__add_user__unpack(&protobuf_c_default_allocator, in.len, (uint8_t *)in.buf); if (!in_proto) fatal("malformed add user message"); char *client = getenv("CEO_USER"); if (!client) fatal("environment variable CEO_USER is not set"); adduser(in_proto, out_proto, client); strbuf_grow(&out, ceo__add_user_response__get_packed_size(out_proto)); strbuf_setlen(&out, ceo__add_user_response__pack(out_proto, (uint8_t *)out.buf)); if (full_write(STDOUT_FILENO, out.buf, out.len)) fatalpe("write: stdout"); ceo__add_user__free_unpacked(in_proto, &protobuf_c_default_allocator); response_delete(out_proto); strbuf_release(&in); strbuf_release(&out); }
int main(int argc, char **argv) { struct strbuf buf = STRBUF_INIT; unsigned char result_sha1[20]; if (argc != 1) usage("git mktag < signaturefile"); git_extract_argv0_path(argv[0]); setup_git_directory(); if (strbuf_read(&buf, 0, 4096) < 0) { die("could not read from stdin"); } /* Verify it for some basic sanity: it needs to start with "object <sha1>\ntype\ntagger " */ if (verify_tag(buf.buf, buf.len) < 0) die("invalid tag signature file"); if (write_sha1_file(buf.buf, buf.len, tag_type, result_sha1) < 0) die("unable to write tag file"); strbuf_release(&buf); printf("%s\n", sha1_to_hex(result_sha1)); return 0; }
static int submodule_needs_pushing(const char *path, const unsigned char sha1[20]) { if (add_submodule_odb(path) || !lookup_commit_reference(sha1)) return 0; if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) { struct child_process cp; const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL}; struct strbuf buf = STRBUF_INIT; int needs_pushing = 0; argv[1] = sha1_to_hex(sha1); memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = local_repo_env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; cp.dir = path; if (start_command(&cp)) die("Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s", sha1_to_hex(sha1), path); if (strbuf_read(&buf, cp.out, 41)) needs_pushing = 1; finish_command(&cp); close(cp.out); strbuf_release(&buf); return needs_pushing; } return 0; }
int cmd_stripspace(int argc, const char **argv, const char *prefix) { struct strbuf buf = STRBUF_INIT; enum stripspace_mode mode = STRIP_DEFAULT; const struct option options[] = { OPT_CMDMODE('s', "strip-comments", &mode, N_("skip and remove all lines starting with comment character"), STRIP_COMMENTS), OPT_CMDMODE('c', "comment-lines", &mode, N_("prepend comment character and space to each line"), COMMENT_LINES), OPT_END() }; argc = parse_options(argc, argv, prefix, options, stripspace_usage, 0); if (argc) usage_with_options(stripspace_usage, options); if (mode == STRIP_COMMENTS || mode == COMMENT_LINES) git_config(git_default_config, NULL); if (strbuf_read(&buf, 0, 1024) < 0) die_errno("could not read the input"); if (mode == STRIP_DEFAULT || mode == STRIP_COMMENTS) strbuf_stripspace(&buf, mode == STRIP_COMMENTS); else comment_lines(&buf); write_or_die(1, buf.buf, buf.len); strbuf_release(&buf); return 0; }
void load_rewritten(struct rewritten *list, const char *file) { struct strbuf buf = STRBUF_INIT; char *p; int fd; fd = open(file, O_RDONLY); if (fd < 0) return; if (strbuf_read(&buf, fd, 0) < 0) { close(fd); strbuf_release(&buf); return; } close(fd); for (p = buf.buf; *p;) { unsigned char from[20]; unsigned char to[20]; char *eol = strchrnul(p, '\n'); if (eol - p != 81) /* wrong size */ break; if (get_sha1_hex(p, from)) break; if (get_sha1_hex(p + 41, to)) break; add_rewritten(list, from, to); p = *eol ? eol + 1 : eol; } strbuf_release(&buf); }
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) { const char *inpath = NULL; const char *message = NULL; struct option options[] = { { OPTION_INTEGER, 0, "log", &shortlog_len, "n", "populate log with at most <n> entries from shortlog", PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN }, { OPTION_INTEGER, 0, "summary", &shortlog_len, "n", "alias for --log (deprecated)", PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, NULL, DEFAULT_MERGE_LOG_LEN }, OPT_STRING('m', "message", &message, "text", "use <text> as start of message"), OPT_FILENAME('F', "file", &inpath, "file to read from"), OPT_END() }; FILE *in = stdin; struct strbuf input = STRBUF_INIT, output = STRBUF_INIT; int ret; git_config(fmt_merge_msg_config, NULL); argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage, 0); if (argc > 0) usage_with_options(fmt_merge_msg_usage, options); if (message && !shortlog_len) { char nl = '\n'; write_in_full(STDOUT_FILENO, message, strlen(message)); write_in_full(STDOUT_FILENO, &nl, 1); return 0; } if (shortlog_len < 0) die("Negative --log=%d", shortlog_len); if (inpath && strcmp(inpath, "-")) { in = fopen(inpath, "r"); if (!in) die_errno("cannot open '%s'", inpath); } if (strbuf_read(&input, fileno(in), 0) < 0) die_errno("could not read input file"); if (message) strbuf_addstr(&output, message); ret = fmt_merge_msg(&input, &output, message ? 0 : 1, shortlog_len); if (ret) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); return 0; }
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) { const char *inpath = NULL; const char *message = NULL; int shortlog_len = -1; struct option options[] = { { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"), N_("populate log with at most <n> entries from shortlog"), PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN }, { OPTION_INTEGER, 0, "summary", &shortlog_len, N_("n"), N_("alias for --log (deprecated)"), PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, NULL, DEFAULT_MERGE_LOG_LEN }, OPT_STRING('m', "message", &message, N_("text"), N_("use <text> as start of message")), OPT_FILENAME('F', "file", &inpath, N_("file to read from")), OPT_END() }; FILE *in = stdin; struct strbuf input = STRBUF_INIT, output = STRBUF_INIT; int ret; struct fmt_merge_msg_opts opts; git_config(fmt_merge_msg_config, NULL); argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage, 0); if (argc > 0) usage_with_options(fmt_merge_msg_usage, options); if (shortlog_len < 0) shortlog_len = (merge_log_config > 0) ? merge_log_config : 0; if (inpath && strcmp(inpath, "-")) { in = fopen(inpath, "r"); if (!in) die_errno("cannot open '%s'", inpath); } if (strbuf_read(&input, fileno(in), 0) < 0) die_errno("could not read input file"); if (message) strbuf_addstr(&output, message); memset(&opts, 0, sizeof(opts)); opts.add_title = !message; opts.credit_people = 1; opts.shortlog_len = shortlog_len; ret = fmt_merge_msg(&input, &output, &opts); if (ret) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); return 0; }
static int rpc_service(struct rpc_state *rpc, struct discovery *heads) { const char *svc = rpc->service_name; struct strbuf buf = STRBUF_INIT; struct child_process client; int err = 0; memset(&client, 0, sizeof(client)); client.in = -1; client.out = -1; client.git_cmd = 1; client.argv = rpc->argv; if (start_command(&client)) exit(1); if (heads) write_or_die(client.in, heads->buf, heads->len); rpc->alloc = http_post_buffer; rpc->buf = xmalloc(rpc->alloc); rpc->in = client.in; rpc->out = client.out; strbuf_init(&rpc->result, 0); strbuf_addf(&buf, "%s%s", url, svc); rpc->service_url = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); rpc->hdr_content_type = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "Accept: application/x-%s-result", svc); rpc->hdr_accept = strbuf_detach(&buf, NULL); while (!err) { int n = packet_read_line(rpc->out, rpc->buf, rpc->alloc); if (!n) break; rpc->pos = 0; rpc->len = n; err |= post_rpc(rpc); } strbuf_read(&rpc->result, client.out, 0); close(client.in); close(client.out); client.in = -1; client.out = -1; err |= finish_command(&client); free(rpc->service_url); free(rpc->hdr_content_type); free(rpc->hdr_accept); free(rpc->buf); strbuf_release(&buf); return err; }
static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge_names) { const char *filename; int fd, pos, npos; struct strbuf fetch_head_file = STRBUF_INIT; if (!merge_names) merge_names = &fetch_head_file; filename = git_path_fetch_head(); fd = open(filename, O_RDONLY); if (fd < 0) die_errno(_("could not open '%s' for reading"), filename); if (strbuf_read(merge_names, fd, 0) < 0) die_errno(_("could not read '%s'"), filename); if (close(fd) < 0) die_errno(_("could not close '%s'"), filename); for (pos = 0; pos < merge_names->len; pos = npos) { unsigned char sha1[20]; char *ptr; struct commit *commit; ptr = strchr(merge_names->buf + pos, '\n'); if (ptr) npos = ptr - merge_names->buf + 1; else npos = merge_names->len; if (npos - pos < 40 + 2 || get_sha1_hex(merge_names->buf + pos, sha1)) commit = NULL; /* bad */ else if (memcmp(merge_names->buf + pos + 40, "\t\t", 2)) continue; /* not-for-merge */ else { char saved = merge_names->buf[pos + 40]; merge_names->buf[pos + 40] = '\0'; commit = get_merge_parent(merge_names->buf + pos); merge_names->buf[pos + 40] = saved; } if (!commit) { if (ptr) *ptr = '\0'; die(_("not something we can merge in %s: %s"), filename, merge_names->buf + pos); } remotes = &commit_list_insert(commit, remotes)->next; } if (merge_names == &fetch_head_file) strbuf_release(&fetch_head_file); }
/* * This is to create corrupt objects for debugging and as such it * needs to bypass the data conversion performed by, and the type * limitation imposed by, index_fd() and its callees. */ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigned flags) { struct strbuf buf = STRBUF_INIT; int ret; if (strbuf_read(&buf, fd, 4096) < 0) ret = -1; else ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags); strbuf_release(&buf); return ret; }
static char *shell_prompt(const char *prompt, int echo) { const char *read_input[] = { /* Note: call 'bash' explicitly, as 'read -s' is bash-specific */ "bash", "-c", echo ? "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r line </dev/tty && echo \"$line\"" : "test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&" " read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty", NULL }; struct child_process child = CHILD_PROCESS_INIT; static struct strbuf buffer = STRBUF_INIT; int prompt_len = strlen(prompt), len = -1, code; child.argv = read_input; child.in = -1; child.out = -1; child.silent_exec_failure = 1; if (start_command(&child)) return NULL; if (write_in_full(child.in, prompt, prompt_len) != prompt_len) { error("could not write to prompt script"); close(child.in); goto ret; } close(child.in); strbuf_reset(&buffer); len = strbuf_read(&buffer, child.out, 1024); if (len < 0) { error("could not read from prompt script"); goto ret; } strbuf_strip_suffix(&buffer, "\n"); strbuf_strip_suffix(&buffer, "\r"); ret: close(child.out); code = finish_command(&child); if (code) { if (code != 127) error("failed to execute prompt script (exit code %d)", code); return NULL; } return len < 0 ? NULL : buffer.buf; }
/* * Create a detached signature for the contents of "buffer" and append * it after "signature"; "buffer" and "signature" can be the same * strbuf instance, which would cause the detached signature appended * at the end. */ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key) { struct child_process gpg; const char *args[4]; ssize_t len; size_t i, j, bottom; memset(&gpg, 0, sizeof(gpg)); gpg.argv = args; gpg.in = -1; gpg.out = -1; args[0] = gpg_program; args[1] = "-bsau"; args[2] = signing_key; args[3] = NULL; if (start_command(&gpg)) return error(_("could not run gpg.")); /* * When the username signingkey is bad, program could be terminated * because gpg exits without reading and then write gets SIGPIPE. */ sigchain_push(SIGPIPE, SIG_IGN); if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { close(gpg.in); close(gpg.out); finish_command(&gpg); return error(_("gpg did not accept the data")); } close(gpg.in); bottom = signature->len; len = strbuf_read(signature, gpg.out, 1024); close(gpg.out); sigchain_pop(SIGPIPE); if (finish_command(&gpg) || !len || len < 0) return error(_("gpg failed to sign the data")); /* Strip CR from the line endings, in case we are on Windows. */ for (i = j = bottom; i < signature->len; i++) if (signature->buf[i] != '\r') { if (i != j) signature->buf[j] = signature->buf[i]; j++; } strbuf_setlen(signature, j); return 0; }
int is_submodule_modified(const char *path) { int len; struct child_process cp; const char *argv[] = { "status", "--porcelain", NULL, }; char *env[4]; struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "%s/.git/", path); if (!is_directory(buf.buf)) { strbuf_release(&buf); /* The submodule is not checked out, so it is not modified */ return 0; } strbuf_reset(&buf); strbuf_addf(&buf, "GIT_WORK_TREE=%s", path); env[0] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_DIR=%s/.git", path); env[1] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_INDEX_FILE"); env[2] = strbuf_detach(&buf, NULL); env[3] = NULL; memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = (const char *const *)env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; if (start_command(&cp)) die("Could not run git status --porcelain"); len = strbuf_read(&buf, cp.out, 1024); close(cp.out); if (finish_command(&cp)) die("git status --porcelain failed"); free(env[0]); free(env[1]); free(env[2]); strbuf_release(&buf); return len != 0; }
int is_submodule_modified(const char *path) { int len, i; struct child_process cp; const char *argv[] = { "status", "--porcelain", NULL, }; const char *env[LOCAL_REPO_ENV_SIZE + 3]; struct strbuf buf = STRBUF_INIT; for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++) env[i] = local_repo_env[i]; strbuf_addf(&buf, "%s/.git/", path); if (!is_directory(buf.buf)) { strbuf_release(&buf); /* The submodule is not checked out, so it is not modified */ return 0; } strbuf_reset(&buf); strbuf_addf(&buf, "GIT_WORK_TREE=%s", path); env[i++] = strbuf_detach(&buf, NULL); strbuf_addf(&buf, "GIT_DIR=%s/.git", path); env[i++] = strbuf_detach(&buf, NULL); env[i] = NULL; memset(&cp, 0, sizeof(cp)); cp.argv = argv; cp.env = env; cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; if (start_command(&cp)) die("Could not run git status --porcelain"); len = strbuf_read(&buf, cp.out, 1024); close(cp.out); if (finish_command(&cp)) die("git status --porcelain failed"); for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++) free((char *)env[i]); strbuf_release(&buf); return len != 0; }
int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint) { int fd, len; fd = open(path, O_RDONLY); if (fd < 0) return -1; len = strbuf_read(sb, fd, hint); close(fd); if (len < 0) return -1; return len; }
int capture_command(struct child_process *cmd, struct strbuf *buf, size_t hint) { cmd->out = -1; if (start_command(cmd) < 0) return -1; if (strbuf_read(buf, cmd->out, hint) < 0) { close(cmd->out); finish_command(cmd); /* throw away exit code */ return -1; } close(cmd->out); return finish_command(cmd); }
static int populate_from_stdin(struct diff_filespec *s) { struct strbuf buf = STRBUF_INIT; size_t size = 0; if (strbuf_read(&buf, 0, 0) < 0) return error_errno("error while reading from stdin"); s->should_munmap = 0; s->data = strbuf_detach(&buf, &size); s->size = size; s->should_free = 1; s->is_stdin = 1; return 0; }
static int parse_file_arg(const struct option *opt, const char *arg, int unset) { struct msg_arg *msg = opt->value; if (msg->buf.len) strbuf_addch(&(msg->buf), '\n'); if (!strcmp(arg, "-")) { if (strbuf_read(&(msg->buf), 0, 1024) < 0) die_errno("cannot read '%s'", arg); } else if (strbuf_read_file(&(msg->buf), arg, 1024) < 0) die_errno("could not open or read '%s'", arg); stripspace(&(msg->buf), 0); msg->given = 1; return 0; }
static int parse_file_arg(const struct option *opt, const char *arg, int unset) { struct note_data *d = opt->value; if (d->buf.len) strbuf_addch(&d->buf, '\n'); if (!strcmp(arg, "-")) { if (strbuf_read(&d->buf, 0, 1024) < 0) die_errno(_("cannot read '%s'"), arg); } else strbuf_read_file_or_die(&(d->buf), arg, 0); stripspace(&d->buf, 0); d->given = 1; return 0; }
/** * Sign buffer */ static int do_sign(struct strbuf *buffer, char * signingkey) { struct child_process gpg; const char *args[4]; int len; int i, j; /* When the username signingkey is bad, program could be terminated * because gpg exits without reading and then write gets SIGPIPE. */ signal(SIGPIPE, SIG_IGN); memset(&gpg, 0, sizeof(gpg)); gpg.argv = args; gpg.in = -1; gpg.out = -1; args[0] = "gpg"; args[1] = "-bsau"; args[2] = signingkey; args[3] = NULL; if (start_command(&gpg)) return error("could not run gpg."); if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { close(gpg.in); close(gpg.out); finish_command(&gpg); return error("gpg did not accept the tag data"); } close(gpg.in); len = strbuf_read(buffer, gpg.out, 1024); close(gpg.out); if (finish_command(&gpg) || !len || len < 0) return error("gpg failed to sign the tag"); /* Strip CR from the line endings, in case we are on Windows. */ for (i = j = 0; i < buffer->len; i++) if (buffer->buf[i] != '\r') { if (i != j) buffer->buf[j] = buffer->buf[i]; j++; } strbuf_setlen(buffer, j); return 0; }
static int fill_entry_new_sha1(struct trunk_entry *entry) { struct strbuf buf = STRBUF_INIT; int fd, ret = 0; struct sha1_file_hdr hdr = { .priv = 0 }; memcpy(hdr.tag, TAG_DATA, TAG_LEN); strbuf_addstr(&buf, obj_path); strbuf_addf(&buf, "%016" PRIx64, entry->oid); fd = open(buf.buf, O_RDONLY); strbuf_reset(&buf); if (fd < 0) { dprintf("%m\n"); ret = -1; goto out; } if (!strbuf_read(&buf, fd, SD_DATA_OBJ_SIZE) == SD_DATA_OBJ_SIZE) { dprintf("strbuf_read fail to read full\n"); ret = -1; goto out_close; } hdr.size = buf.len; strbuf_insert(&buf, 0, &hdr, sizeof(hdr)); if (sha1_file_write((void *)buf.buf, buf.len, entry->sha1) < 0) { ret = -1; goto out_close; } dprintf("data sha1:%s, %"PRIx64"\n", sha1_to_hex(entry->sha1), entry->oid); out_close: close(fd); out: strbuf_release(&buf); return ret; } static int inc_object_nr(uint64_t oid, void *arg) { uint64_t *object_nr = arg; (*object_nr)++; return 0; }
static int check_emacsclient_version(void) { struct strbuf buffer = STRBUF_INIT; struct child_process ec_process; const char *argv_ec[] = { "emacsclient", "--version", NULL }; int version; int ret = -1; /* emacsclient prints its version number on stderr */ memset(&ec_process, 0, sizeof(ec_process)); ec_process.argv = argv_ec; ec_process.err = -1; ec_process.stdout_to_stderr = 1; if (start_command(&ec_process)) { fprintf(stderr, "Failed to start emacsclient.\n"); return -1; } if (strbuf_read(&buffer, ec_process.err, 20) < 0) { fprintf(stderr, "Failed to read emacsclient version\n"); goto out; } close(ec_process.err); /* * Don't bother checking return value, because "emacsclient --version" * seems to always exits with code 1. */ finish_command(&ec_process); if (prefixcmp(buffer.buf, "emacsclient")) { fprintf(stderr, "Failed to parse emacsclient version.\n"); goto out; } version = atoi(buffer.buf + strlen("emacsclient")); if (version < 22) { fprintf(stderr, "emacsclient version '%d' too old (< 22).\n", version); } else ret = 0; out: strbuf_release(&buffer); return ret; }
int cmd_stripspace(int argc, const char **argv, const char *prefix) { struct strbuf buf = STRBUF_INIT; int strip_comments = 0; if (argc > 1 && (!strcmp(argv[1], "-s") || !strcmp(argv[1], "--strip-comments"))) strip_comments = 1; if (strbuf_read(&buf, 0, 1024) < 0) die_errno("could not read the input"); stripspace(&buf, strip_comments); write_or_die(1, buf.buf, buf.len); strbuf_release(&buf); return 0; }
static int fill_entry_new_sha1(struct trunk_entry_incore *entry) { struct strbuf buf = STRBUF_INIT; int fd, ret = 0; struct sha1_file_hdr hdr = { .priv = 0 }; memcpy(hdr.tag, TAG_DATA, TAG_LEN); strbuf_addstr(&buf, obj_path); strbuf_addf(&buf, "%016" PRIx64, entry->raw.oid); fd = open(buf.buf, O_RDONLY); strbuf_reset(&buf); if (fd < 0) { dprintf("%m\n"); ret = -1; goto out; } if (!strbuf_read(&buf, fd, SD_DATA_OBJ_SIZE) == SD_DATA_OBJ_SIZE) { dprintf("strbuf_read fail to read full\n"); ret = -1; goto out_close; } hdr.size = buf.len; strbuf_insert(&buf, 0, &hdr, sizeof(hdr)); if (sha1_file_write((void *)buf.buf, buf.len, entry->raw.sha1) < 0) { ret = -1; goto out_close; } dprintf("data sha1:%s, %"PRIx64"\n", sha1_to_hex(entry->raw.sha1), entry->raw.oid); out_close: close(fd); out: strbuf_release(&buf); return ret; } static inline int trunk_entry_no_sha1(struct trunk_entry_incore *entry) { unsigned char empty[SHA1_LEN] = {0}; return memcmp(entry->raw.sha1, empty, SHA1_LEN) == 0; }