Code clean-up.
* rs/child-process-init:
run-command: inline prepare_run_command_v_opt()
run-command: call run_command_v_opt_cd_env() instead of duplicating it
run-command: introduce child_process_init()
run-command: introduce CHILD_PROCESS_INIT
unsigned int mode;
memset(&header, 0, sizeof(header));
*header.typeflag = TYPEFLAG_EXT_HEADER;
- mode = 0100666;
+ mode = 0100666 & ~tar_umask;
sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
prepare_header(args, &header, mode, size);
write_blocked(&header, sizeof(header));
strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
memset(&header, 0, sizeof(header));
*header.typeflag = TYPEFLAG_GLOBAL_HEADER;
- mode = 0100666;
+ mode = 0100666 & ~tar_umask;
strcpy(header.name, "pax_global_header");
prepare_header(args, &header, mode, ext_header.len);
write_blocked(&header, sizeof(header));
struct archiver_args *args)
{
struct strbuf cmd = STRBUF_INIT;
- struct child_process filter;
+ struct child_process filter = CHILD_PROCESS_INIT;
const char *argv[2];
int r;
if (args->compression_level >= 0)
strbuf_addf(&cmd, " -%d", args->compression_level);
- memset(&filter, 0, sizeof(filter));
argv[0] = cmd.buf;
argv[1] = NULL;
filter.argv = argv;
NULL
};
-static const char implicit_ident_advice[] =
+static const char implicit_ident_advice_noconfig[] =
+N_("Your name and email address were configured automatically based\n"
+"on your username and hostname. Please check that they are accurate.\n"
+"You can suppress this message by setting them explicitly. Run the\n"
+"following command and follow the instructions in your editor to edit\n"
+"your configuration file:\n"
+"\n"
+" git config --global --edit\n"
+"\n"
+"After doing this, you may fix the identity used for this commit with:\n"
+"\n"
+" git commit --amend --reset-author\n");
+
+static const char implicit_ident_advice_config[] =
N_("Your name and email address were configured automatically based\n"
"on your username and hostname. Please check that they are accurate.\n"
"You can suppress this message by setting them explicitly:\n"
revs.mailmap = &mailmap;
read_mailmap(revs.mailmap, NULL);
- prepare_revision_walk(&revs);
+ if (prepare_revision_walk(&revs))
+ die(_("revision walk setup failed"));
commit = get_revision(&revs);
if (commit) {
struct pretty_print_context ctx = {0};
return 0;
}
+static const char *implicit_ident_advice(void)
+{
+ char *user_config = NULL;
+ char *xdg_config = NULL;
+ int config_exists;
+
+ home_config_paths(&user_config, &xdg_config, "config");
+ config_exists = file_exists(user_config) || file_exists(xdg_config);
+ free(user_config);
+ free(xdg_config);
+
+ if (config_exists)
+ return _(implicit_ident_advice_config);
+ else
+ return _(implicit_ident_advice_noconfig);
+
+}
+
static void print_summary(const char *prefix, const unsigned char *sha1,
int initial_commit)
{
strbuf_addbuf_percentquote(&format, &committer_ident);
if (advice_implicit_identity) {
strbuf_addch(&format, '\n');
- strbuf_addstr(&format, _(implicit_ident_advice));
+ strbuf_addstr(&format, implicit_ident_advice());
}
}
strbuf_release(&author_ident);
{
/* oldsha1 SP newsha1 LF NUL */
static char buf[2*40 + 3];
- struct child_process proc;
+ struct child_process proc = CHILD_PROCESS_INIT;
const char *argv[3];
int code;
size_t n;
argv[1] = "amend";
argv[2] = NULL;
- memset(&proc, 0, sizeof(proc));
proc.argv = argv;
proc.in = -1;
proc.stdout_to_stderr = 1;
line = memmem(buf, size, "\ntagger ", 8);
if (!line++)
return 1;
- lineend = memchr(line, buf + size - line, '\n');
- line = memchr(line, lineend ? lineend - line : buf + size - line, '>');
+ lineend = memchr(line, '\n', buf + size - line);
+ line = memchr(line, '>', lineend ? lineend - line : buf + size - line);
if (!line++)
return 1;
date = strtoul(line, NULL, 10);
int i, ref_count = 0;
struct strbuf buf = STRBUF_INIT;
struct rev_info revs;
- struct child_process rls;
+ struct child_process rls = CHILD_PROCESS_INIT;
FILE *rls_fout;
bundle_to_stdout = !strcmp(path, "-");
init_revisions(&revs, NULL);
/* write prerequisites */
- memset(&rls, 0, sizeof(rls));
argv_array_pushl(&rls.args,
"rev-list", "--boundary", "--pretty=oneline",
NULL);
{
const char *argv_index_pack[] = {"index-pack",
"--fix-thin", "--stdin", NULL, NULL};
- struct child_process ip;
+ struct child_process ip = CHILD_PROCESS_INIT;
if (flags & BUNDLE_VERBOSE)
argv_index_pack[3] = "-v";
if (verify_bundle(header, 0))
return -1;
- memset(&ip, 0, sizeof(ip));
ip.argv = argv_index_pack;
ip.in = bundle_fd;
ip.no_stdout = 1;
int overridable;
};
-static struct daemon_service *service_looking_at;
-static int service_enabled;
-
-static int git_daemon_config(const char *var, const char *value, void *cb)
-{
- const char *service;
-
- if (skip_prefix(var, "daemon.", &service) &&
- !strcmp(service, service_looking_at->config_name)) {
- service_enabled = git_config_bool(var, value);
- return 0;
- }
-
- /* we are not interested in parsing any other configuration here */
- return 0;
-}
-
static int daemon_error(const char *dir, const char *msg)
{
if (!informative_errors)
static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)
{
- struct child_process child;
+ struct child_process child = CHILD_PROCESS_INIT;
struct strbuf buf = STRBUF_INIT;
const char *argv[8];
const char **arg = argv;
*arg = NULL;
#undef STRARG
- memset(&child, 0, sizeof(child));
child.use_shell = 1;
child.argv = argv;
child.no_stdin = 1;
{
const char *path;
int enabled = service->enabled;
+ struct strbuf var = STRBUF_INIT;
loginfo("Request %s for '%s'", service->name, dir);
}
if (service->overridable) {
- service_looking_at = service;
- service_enabled = -1;
- git_config(git_daemon_config, NULL);
- if (0 <= service_enabled)
- enabled = service_enabled;
+ strbuf_addf(&var, "daemon.%s", service->config_name);
+ git_config_get_bool(var.buf, &enabled);
+ strbuf_release(&var);
}
if (!enabled) {
logerror("'%s': service not enabled for '%s'",
static int run_service_command(const char **argv)
{
- struct child_process cld;
+ struct child_process cld = CHILD_PROCESS_INIT;
- memset(&cld, 0, sizeof(cld));
cld.argv = argv;
cld.git_cmd = 1;
cld.err = -1;
static char **cld_argv;
static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
{
- struct child_process cld = { NULL };
+ struct child_process cld = CHILD_PROCESS_INIT;
char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
char *env[] = { addrbuf, portbuf, NULL };
char hdr_arg[256];
const char **av, *cmd_name;
int do_keep = args->keep_pack;
- struct child_process cmd;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int ret;
memset(&demux, 0, sizeof(demux));
else
demux.out = xd[0];
- memset(&cmd, 0, sizeof(cmd));
cmd.argv = argv;
av = argv;
*hdr_arg = 0;
return ref;
}
-static int fetch_pack_config(const char *var, const char *value, void *cb)
+static void fetch_pack_config(void)
{
- if (strcmp(var, "fetch.unpacklimit") == 0) {
- fetch_unpack_limit = git_config_int(var, value);
- return 0;
- }
-
- if (strcmp(var, "transfer.unpacklimit") == 0) {
- transfer_unpack_limit = git_config_int(var, value);
- return 0;
- }
-
- if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
- prefer_ofs_delta = git_config_bool(var, value);
- return 0;
- }
-
- if (!strcmp(var, "fetch.fsckobjects")) {
- fetch_fsck_objects = git_config_bool(var, value);
- return 0;
- }
-
- if (!strcmp(var, "transfer.fsckobjects")) {
- transfer_fsck_objects = git_config_bool(var, value);
- return 0;
- }
+ git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit);
+ git_config_get_int("transfer.unpacklimit", &transfer_unpack_limit);
+ git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
+ git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
+ git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
- return git_default_config(var, value, cb);
+ git_config(git_default_config, NULL);
}
static void fetch_pack_setup(void)
static int did_setup;
if (did_setup)
return;
- git_config(fetch_pack_config, NULL);
+ fetch_pack_config();
if (0 <= transfer_unpack_limit)
unpack_limit = transfer_unpack_limit;
else if (0 <= fetch_unpack_limit)
send_local_file("application/x-git-packed-objects-toc", name);
}
-static int http_config(const char *var, const char *value, void *cb)
+static void http_config(void)
{
- const char *p;
+ int i, value = 0;
+ struct strbuf var = STRBUF_INIT;
- if (!strcmp(var, "http.getanyfile")) {
- getanyfile = git_config_bool(var, value);
- return 0;
- }
+ git_config_get_bool("http.getanyfile", &getanyfile);
- if (skip_prefix(var, "http.", &p)) {
- int i;
-
- for (i = 0; i < ARRAY_SIZE(rpc_service); i++) {
- struct rpc_service *svc = &rpc_service[i];
- if (!strcmp(p, svc->config_name)) {
- svc->enabled = git_config_bool(var, value);
- return 0;
- }
- }
+ for (i = 0; i < ARRAY_SIZE(rpc_service); i++) {
+ struct rpc_service *svc = &rpc_service[i];
+ strbuf_addf(&var, "http.%s", svc->config_name);
+ if (!git_config_get_bool(var.buf, &value))
+ svc->enabled = value;
+ strbuf_reset(&var);
}
- /* we are not interested in parsing any other configuration here */
- return 0;
+ strbuf_release(&var);
}
static struct rpc_service *select_service(const char *name)
const char *host = getenv("REMOTE_ADDR");
struct argv_array env = ARGV_ARRAY_INIT;
int gzipped_request = 0;
- struct child_process cld;
+ struct child_process cld = CHILD_PROCESS_INIT;
if (encoding && !strcmp(encoding, "gzip"))
gzipped_request = 1;
argv_array_pushf(&env, "GIT_COMMITTER_EMAIL=%s@http.%s",
user, host);
- memset(&cld, 0, sizeof(cld));
cld.argv = argv;
cld.env = env.argv;
if (gzipped_request)
access("git-daemon-export-ok", F_OK) )
not_found("Repository not exported: '%s'", dir);
- git_config(http_config, NULL);
+ http_config();
cmd->imp(cmd_arg);
return 0;
}
char *data;
int dlen;
int uid;
- unsigned create:1, trycreate:1;
};
struct imap_cmd {
return ret;
}
-static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
- struct imap_cmd_cb *cb,
- const char *fmt, va_list ap)
+static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
+ struct imap_cmd_cb *cb,
+ const char *fmt, va_list ap)
{
struct imap *imap = ctx->imap;
struct imap_cmd *cmd;
return cmd;
}
-__attribute__((format (printf, 3, 4)))
-static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
- struct imap_cmd_cb *cb,
- const char *fmt, ...)
-{
- struct imap_cmd *ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = v_issue_imap_cmd(ctx, cb, fmt, ap);
- va_end(ap);
- return ret;
-}
-
__attribute__((format (printf, 3, 4)))
static int imap_exec(struct imap_store *ctx, struct imap_cmd_cb *cb,
const char *fmt, ...)
struct imap_cmd *cmdp;
va_start(ap, fmt);
- cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ cmdp = issue_imap_cmd(ctx, cb, fmt, ap);
va_end(ap);
if (!cmdp)
return RESP_BAD;
struct imap_cmd *cmdp;
va_start(ap, fmt);
- cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ cmdp = issue_imap_cmd(ctx, cb, fmt, ap);
va_end(ap);
if (!cmdp)
return DRV_STORE_BAD;
static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
{
struct imap *imap = ctx->imap;
- struct imap_cmd *cmdp, **pcmdp, *ncmdp;
- char *cmd, *arg, *arg1, *p;
+ struct imap_cmd *cmdp, **pcmdp;
+ char *cmd, *arg, *arg1;
int n, resp, resp2, tag;
for (;;) {
if (!strcmp("OK", arg))
resp = DRV_OK;
else {
- if (!strcmp("NO", arg)) {
- if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp(cmd, "[TRYCREATE]", 11))) { /* SELECT, APPEND or UID COPY */
- p = strchr(cmdp->cmd, '"');
- if (!issue_imap_cmd(ctx, NULL, "CREATE \"%.*s\"", (int)(strchr(p + 1, '"') - p + 1), p)) {
- resp = RESP_BAD;
- goto normal;
- }
- /* not waiting here violates the spec, but a server that does not
- grok this nonetheless violates it too. */
- cmdp->cb.create = 0;
- if (!(ncmdp = issue_imap_cmd(ctx, &cmdp->cb, "%s", cmdp->cmd))) {
- resp = RESP_BAD;
- goto normal;
- }
- free(cmdp->cmd);
- free(cmdp);
- if (!tcmd)
- return 0; /* ignored */
- if (cmdp == tcmd)
- tcmd = ncmdp;
- continue;
- }
+ if (!strcmp("NO", arg))
resp = RESP_NO;
- } else /*if (!strcmp("BAD", arg))*/
+ else /*if (!strcmp("BAD", arg))*/
resp = RESP_BAD;
fprintf(stderr, "IMAP command '%s' returned response (%s) - %s\n",
memcmp(cmdp->cmd, "LOGIN", 5) ?
}
if ((resp2 = parse_response_code(ctx, &cmdp->cb, cmd)) > resp)
resp = resp2;
- normal:
if (cmdp->cb.done)
cmdp->cb.done(ctx, cmdp, resp);
free(cmdp->cb.data);
return 0;
}
-static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
+static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *folder)
{
struct credential cred = CREDENTIAL_INIT;
struct imap_store *ctx;
if (srvc->tunnel) {
const char *argv[] = { srvc->tunnel, NULL };
- struct child_process tunnel = {NULL};
+ struct child_process tunnel = CHILD_PROCESS_INIT;
imap_info("Starting tunnel '%s'... ", srvc->tunnel);
credential_approve(&cred);
credential_clear(&cred);
+ /* check the target mailbox exists */
+ ctx->name = folder;
+ switch (imap_exec(ctx, NULL, "EXAMINE \"%s\"", ctx->name)) {
+ case RESP_OK:
+ /* ok */
+ break;
+ case RESP_BAD:
+ fprintf(stderr, "IMAP error: could not check mailbox\n");
+ goto out;
+ case RESP_NO:
+ if (imap_exec(ctx, NULL, "CREATE \"%s\"", ctx->name) == RESP_OK) {
+ imap_info("Created missing mailbox\n");
+ } else {
+ fprintf(stderr, "IMAP error: could not create missing mailbox\n");
+ goto out;
+ }
+ break;
+ }
+
ctx->prefix = "";
return ctx;
credential_reject(&cred);
credential_clear(&cred);
+ out:
imap_close_store(ctx);
return NULL;
}
box = ctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
- cb.create = 0;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" ", prefix, box);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
static char *imap_folder;
-static int git_imap_config(const char *key, const char *val, void *cb)
+static void git_imap_config(void)
{
- if (!skip_prefix(key, "imap.", &key))
- return 0;
+ const char *val = NULL;
- /* check booleans first, and barf on others */
- if (!strcmp("sslverify", key))
- server.ssl_verify = git_config_bool(key, val);
- else if (!strcmp("preformattedhtml", key))
- server.use_html = git_config_bool(key, val);
- else if (!val)
- return config_error_nonbool(key);
-
- if (!strcmp("folder", key)) {
- imap_folder = xstrdup(val);
- } else if (!strcmp("host", key)) {
- if (starts_with(val, "imap:"))
- val += 5;
- else if (starts_with(val, "imaps:")) {
- val += 6;
- server.use_ssl = 1;
+ git_config_get_bool("imap.sslverify", &server.ssl_verify);
+ git_config_get_bool("imap.preformattedhtml", &server.use_html);
+ git_config_get_string("imap.folder", &imap_folder);
+
+ if (!git_config_get_value("imap.host", &val)) {
+ if (!val) {
+ git_die_config("imap.host", "Missing value for 'imap.host'");
+ } else {
+ if (starts_with(val, "imap:"))
+ val += 5;
+ else if (starts_with(val, "imaps:")) {
+ val += 6;
+ server.use_ssl = 1;
+ }
+ if (starts_with(val, "//"))
+ val += 2;
+ server.host = xstrdup(val);
}
- if (starts_with(val, "//"))
- val += 2;
- server.host = xstrdup(val);
- } else if (!strcmp("user", key))
- server.user = xstrdup(val);
- else if (!strcmp("pass", key))
- server.pass = xstrdup(val);
- else if (!strcmp("port", key))
- server.port = git_config_int(key, val);
- else if (!strcmp("tunnel", key))
- server.tunnel = xstrdup(val);
- else if (!strcmp("authmethod", key))
- server.auth_method = xstrdup(val);
+ }
- return 0;
+ git_config_get_string("imap.user", &server.user);
+ git_config_get_string("imap.pass", &server.pass);
+ git_config_get_int("imap.port", &server.port);
+ git_config_get_string("imap.tunnel", &server.tunnel);
+ git_config_get_string("imap.authmethod", &server.auth_method);
}
int main(int argc, char **argv)
usage(imap_send_usage);
setup_git_directory_gently(&nongit_ok);
- git_config(git_imap_config, NULL);
+ git_imap_config();
if (!server.port)
server.port = server.use_ssl ? 993 : 143;
}
/* write it to the imap server */
- ctx = imap_open_store(&server);
+ ctx = imap_open_store(&server, imap_folder);
if (!ctx) {
fprintf(stderr, "failed to open store\n");
return 1;
}
fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
- ctx->name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
#define DEFAULT_PAGER "less"
#endif
-struct pager_config {
- const char *cmd;
- int want;
- char *value;
-};
-
/*
* This is split up from the rest of git so that we can do
* something different on Windows.
*/
static const char *pager_argv[] = { NULL, NULL };
- static struct child_process pager_process;
+ static struct child_process pager_process = CHILD_PROCESS_INIT;
static void wait_for_pager(void)
{
return width;
}
-static int pager_command_config(const char *var, const char *value, void *data)
+/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
+int check_pager_config(const char *cmd)
{
- struct pager_config *c = data;
- if (starts_with(var, "pager.") && !strcmp(var + 6, c->cmd)) {
- int b = git_config_maybe_bool(var, value);
+ int want = -1;
+ struct strbuf key = STRBUF_INIT;
+ const char *value = NULL;
+ strbuf_addf(&key, "pager.%s", cmd);
+ if (!git_config_get_value(key.buf, &value)) {
+ int b = git_config_maybe_bool(key.buf, value);
if (b >= 0)
- c->want = b;
+ want = b;
else {
- c->want = 1;
- c->value = xstrdup(value);
+ want = 1;
+ pager_program = xstrdup(value);
}
}
- return 0;
-}
-
-/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
-int check_pager_config(const char *cmd)
-{
- struct pager_config c;
- c.cmd = cmd;
- c.want = -1;
- c.value = NULL;
- git_config(pager_command_config, &c);
- if (c.value)
- pager_program = c.value;
- return c.want;
+ strbuf_release(&key);
+ return want;
}