in daemon.c [1242:1466]
int cmd_main(int argc, const char **argv)
{
int listen_port = 0;
struct string_list listen_addr = STRING_LIST_INIT_DUP;
int serve_mode = 0, inetd_mode = 0;
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
int detach = 0;
struct credentials *cred = NULL;
int i;
int ret;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
const char *v;
if (skip_prefix(arg, "--listen=", &v)) {
string_list_append_nodup(&listen_addr, xstrdup_tolower(v));
continue;
}
if (skip_prefix(arg, "--port=", &v)) {
char *end;
unsigned long n;
n = strtoul(v, &end, 0);
if (*v && !*end) {
listen_port = n;
continue;
}
}
if (!strcmp(arg, "--serve")) {
serve_mode = 1;
continue;
}
if (!strcmp(arg, "--inetd")) {
inetd_mode = 1;
continue;
}
if (!strcmp(arg, "--verbose")) {
verbose = 1;
continue;
}
if (!strcmp(arg, "--syslog")) {
log_destination = LOG_DESTINATION_SYSLOG;
continue;
}
if (skip_prefix(arg, "--log-destination=", &v)) {
if (!strcmp(v, "syslog")) {
log_destination = LOG_DESTINATION_SYSLOG;
continue;
} else if (!strcmp(v, "stderr")) {
log_destination = LOG_DESTINATION_STDERR;
continue;
} else if (!strcmp(v, "none")) {
log_destination = LOG_DESTINATION_NONE;
continue;
} else
die("unknown log destination '%s'", v);
}
if (!strcmp(arg, "--export-all")) {
export_all_trees = 1;
continue;
}
if (skip_prefix(arg, "--access-hook=", &v)) {
access_hook = v;
continue;
}
if (skip_prefix(arg, "--timeout=", &v)) {
if (strtoul_ui(v, 10, &timeout))
die(_("invalid timeout '%s', expecting a non-negative integer"), v);
continue;
}
if (skip_prefix(arg, "--init-timeout=", &v)) {
if (strtoul_ui(v, 10, &init_timeout))
die(_("invalid init-timeout '%s', expecting a non-negative integer"), v);
continue;
}
if (skip_prefix(arg, "--max-connections=", &v)) {
int parsed_value;
if (strtol_i(v, 10, &parsed_value))
die(_("invalid max-connections '%s', expecting an integer"), v);
/* A negative value indicates unlimited children. */
max_connections = parsed_value < 0 ? 0 : parsed_value;
continue;
}
if (!strcmp(arg, "--strict-paths")) {
strict_paths = 1;
continue;
}
if (skip_prefix(arg, "--base-path=", &v)) {
base_path = v;
continue;
}
if (!strcmp(arg, "--base-path-relaxed")) {
base_path_relaxed = 1;
continue;
}
if (skip_prefix(arg, "--interpolated-path=", &v)) {
interpolated_path = v;
continue;
}
if (!strcmp(arg, "--reuseaddr")) {
reuseaddr = 1;
continue;
}
if (!strcmp(arg, "--user-path")) {
user_path = "";
continue;
}
if (skip_prefix(arg, "--user-path=", &v)) {
user_path = v;
continue;
}
if (skip_prefix(arg, "--pid-file=", &v)) {
pid_file = v;
continue;
}
if (!strcmp(arg, "--detach")) {
detach = 1;
continue;
}
if (skip_prefix(arg, "--user=", &v)) {
user_name = v;
continue;
}
if (skip_prefix(arg, "--group=", &v)) {
group_name = v;
continue;
}
if (skip_prefix(arg, "--enable=", &v)) {
enable_service(v, 1);
continue;
}
if (skip_prefix(arg, "--disable=", &v)) {
enable_service(v, 0);
continue;
}
if (skip_prefix(arg, "--allow-override=", &v)) {
make_service_overridable(v, 1);
continue;
}
if (skip_prefix(arg, "--forbid-override=", &v)) {
make_service_overridable(v, 0);
continue;
}
if (!strcmp(arg, "--informative-errors")) {
informative_errors = 1;
continue;
}
if (!strcmp(arg, "--no-informative-errors")) {
informative_errors = 0;
continue;
}
if (!strcmp(arg, "--")) {
ok_paths = &argv[i+1];
break;
} else if (arg[0] != '-') {
ok_paths = &argv[i];
break;
}
usage(daemon_usage);
}
if (log_destination == LOG_DESTINATION_UNSET) {
if (inetd_mode || detach)
log_destination = LOG_DESTINATION_SYSLOG;
else
log_destination = LOG_DESTINATION_STDERR;
}
if (log_destination == LOG_DESTINATION_SYSLOG) {
openlog("git-daemon", LOG_PID, LOG_DAEMON);
set_die_routine(daemon_die);
} else
/* avoid splitting a message in the middle */
setvbuf(stderr, NULL, _IOFBF, 4096);
if (inetd_mode && (detach || group_name || user_name))
die("--detach, --user and --group are incompatible with --inetd");
if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
die("--listen= and --port= are incompatible with --inetd");
else if (listen_port == 0)
listen_port = DEFAULT_GIT_PORT;
if (group_name && !user_name)
die("--group supplied without --user");
if (user_name)
cred = prepare_credentials(user_name, group_name);
if (strict_paths && (!ok_paths || !*ok_paths))
die("option --strict-paths requires '<directory>' arguments");
if (base_path && !is_directory(base_path))
die("base-path '%s' does not exist or is not a directory",
base_path);
if (log_destination != LOG_DESTINATION_STDERR) {
if (!freopen("/dev/null", "w", stderr))
die_errno("failed to redirect stderr to /dev/null");
}
if (inetd_mode || serve_mode) {
ret = execute();
} else {
if (detach) {
if (daemonize())
die("--detach not supported on this platform");
}
if (pid_file)
write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid());
/* prepare argv for serving-processes */
strvec_push(&cld_argv, argv[0]); /* git-daemon */
strvec_push(&cld_argv, "--serve");
for (i = 1; i < argc; ++i)
strvec_push(&cld_argv, argv[i]);
ret = serve(&listen_addr, listen_port, cred);
}
string_list_clear(&listen_addr, 0);
return ret;
}