From: Junio C Hamano Date: Tue, 3 Mar 2015 22:37:04 +0000 (-0800) Subject: Merge branch 'rs/daemon-interpolate' X-Git-Tag: v2.4.0-rc0~76 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/ef4cdb8bb7c56a431f2f553ed39b896f32488a18?ds=inline;hp=-c Merge branch 'rs/daemon-interpolate' "git daemon" looked up the hostname even when "%CH" and "%IP" interpolations are not requested, which was unnecessary. * rs/daemon-interpolate: daemon: use callback to build interpolated path daemon: look up client-supplied hostname lazily --- ef4cdb8bb7c56a431f2f553ed39b896f32488a18 diff --combined daemon.c index 54a03bd527,df9768fecc..09fa652fd1 --- a/daemon.c +++ b/daemon.c @@@ -61,6 -61,22 +61,22 @@@ static char *canon_hostname static char *ip_address; static char *tcp_port; + static int hostname_lookup_done; + + static void lookup_hostname(void); + + static const char *get_canon_hostname(void) + { + lookup_hostname(); + return canon_hostname; + } + + static const char *get_ip_address(void) + { + lookup_hostname(); + return ip_address; + } + static void logreport(int priority, const char *err, va_list params) { if (log_syslog) { @@@ -106,6 -122,46 +122,46 @@@ static void NORETURN daemon_die(const c exit(1); } + static void strbuf_addstr_or_null(struct strbuf *sb, const char *s) + { + if (s) + strbuf_addstr(sb, s); + } + + struct expand_path_context { + const char *directory; + }; + + static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx) + { + struct expand_path_context *context = ctx; + + switch (placeholder[0]) { + case 'H': + strbuf_addstr_or_null(sb, hostname); + return 1; + case 'C': + if (placeholder[1] == 'H') { + strbuf_addstr_or_null(sb, get_canon_hostname()); + return 2; + } + break; + case 'I': + if (placeholder[1] == 'P') { + strbuf_addstr_or_null(sb, get_ip_address()); + return 2; + } + break; + case 'P': + strbuf_addstr_or_null(sb, tcp_port); + return 1; + case 'D': + strbuf_addstr(sb, context->directory); + return 1; + } + return 0; + } + static const char *path_ok(const char *directory) { static char rpath[PATH_MAX]; @@@ -144,14 -200,10 +200,10 @@@ } else if (interpolated_path && saw_extended_args) { struct strbuf expanded_path = STRBUF_INIT; - struct strbuf_expand_dict_entry dict[6]; - - dict[0].placeholder = "H"; dict[0].value = hostname; - dict[1].placeholder = "CH"; dict[1].value = canon_hostname; - dict[2].placeholder = "IP"; dict[2].value = ip_address; - dict[3].placeholder = "P"; dict[3].value = tcp_port; - dict[4].placeholder = "D"; dict[4].value = directory; - dict[5].placeholder = NULL; dict[5].value = NULL; + struct expand_path_context context; + + context.directory = directory; + if (*dir != '/') { /* Allow only absolute */ logerror("'%s': Non-absolute path denied (interpolated-path active)", dir); @@@ -159,7 -211,7 +211,7 @@@ } strbuf_expand(&expanded_path, interpolated_path, - strbuf_expand_dict_cb, &dict); + expand_path, &context); strlcpy(interp_path, expanded_path.buf, PATH_MAX); strbuf_release(&expanded_path); loginfo("Interpolated dir '%s'", interp_path); @@@ -230,6 -282,23 +282,6 @@@ struct daemon_service 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) @@@ -242,7 -311,7 +294,7 @@@ static const char *access_hook 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; @@@ -254,12 -323,13 +306,12 @@@ *arg++ = service->name; *arg++ = path; *arg++ = STRARG(hostname); - *arg++ = STRARG(canon_hostname); - *arg++ = STRARG(ip_address); + *arg++ = STRARG(get_canon_hostname()); + *arg++ = STRARG(get_ip_address()); *arg++ = STRARG(tcp_port); *arg = NULL; #undef STRARG - memset(&child, 0, sizeof(child)); child.use_shell = 1; child.argv = argv; child.no_stdin = 1; @@@ -306,7 -376,6 +358,7 @@@ static int run_service(const char *dir { const char *path; int enabled = service->enabled; + struct strbuf var = STRBUF_INIT; loginfo("Request %s for '%s'", service->name, dir); @@@ -337,9 -406,11 +389,9 @@@ } 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'", @@@ -387,8 -458,9 +439,8 @@@ static void copy_to_log(int fd 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; @@@ -509,6 -581,7 +561,7 @@@ static void parse_host_arg(char *extra_ } free(hostname); hostname = xstrdup_tolower(host); + hostname_lookup_done = 0; } /* On to the next one */ @@@ -517,11 -590,14 +570,14 @@@ if (extra_args < end && *extra_args) die("Invalid request"); } + } - /* - * Locate canonical hostname and its IP address. - */ - if (hostname) { + /* + * Locate canonical hostname and its IP address. + */ + static void lookup_hostname(void) + { + if (!hostname_lookup_done && hostname) { #ifndef NO_IPV6 struct addrinfo hints; struct addrinfo *ai; @@@ -569,6 -645,7 +625,7 @@@ ip_address = xstrdup(addrbuf); } #endif + hostname_lookup_done = 1; } } @@@ -714,7 -791,7 +771,7 @@@ static void check_dead_children(void 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 };