+ int ret, afs_socket, daemon_pipe = -1;
+ char *errctx;
+
+ valid_fd_012();
+ /* parse command line options */
+ ret = lls(lls_parse(argc, argv, CMD_PTR, &cmdline_lpr, &errctx));
+ if (ret < 0)
+ goto fail;
+ server_lpr = cmdline_lpr;
+ daemon_set_loglevel(ENUM_STRING_VAL(LOGLEVEL));
+ daemon_drop_privileges_or_die(OPT_STRING_VAL(USER),
+ OPT_STRING_VAL(GROUP));
+ version_handle_flag("server", OPT_GIVEN(VERSION));
+ handle_help_flags();
+ parse_config_or_die(false);
+ /* become daemon */
+ if (OPT_GIVEN(DAEMON))
+ daemon_pipe = daemonize(true /* parent waits for SIGTERM */);
+ server_pid = getpid();
+ crypt_init();
+ daemon_log_welcome("server");
+ init_ipc_or_die(); /* init mmd struct, mmd and log mutex */
+ daemon_set_start_time();
+ daemon_set_hooks(pre_log_hook, post_log_hook);
+ PARA_NOTICE_LOG("initializing audio format handlers\n");
+ afh_init();
+
+ /*
+ * Although afs uses its own signal handling we must ignore SIGUSR1
+ * _before_ the afs child process gets born by init_afs() below. It's
+ * racy to do this in the child because the parent might send SIGUSR1
+ * before the child gets a chance to ignore this signal.
+ *
+ * We also have to block SIGCHLD before the afs process is created
+ * because otherwise para_server does not notice if afs dies before the
+ * SIGCHLD handler has been installed for the parent process by
+ * init_signal_task() below.
+ */
+ para_sigaction(SIGUSR1, SIG_IGN);
+ para_block_signal(SIGCHLD);
+ PARA_NOTICE_LOG("initializing the audio file selector\n");
+ afs_socket = init_afs(argc, argv);
+ init_signal_task();
+ para_unblock_signal(SIGCHLD);
+ PARA_NOTICE_LOG("initializing virtual streaming system\n");
+ vss_init(afs_socket, &sched);
+ init_server_command_task(sct, argc, argv);
+ if (daemon_pipe >= 0) {
+ if (write(daemon_pipe, "\0", 1) < 0) {
+ PARA_EMERG_LOG("daemon_pipe: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ close(daemon_pipe);
+ }
+ PARA_NOTICE_LOG("server init complete\n");
+ return;
+fail:
+ assert(ret < 0);
+ if (errctx)
+ PARA_ERROR_LOG("%s\n", errctx);
+ PARA_EMERG_LOG("%s\n", para_strerror(-ret));
+ exit(EXIT_FAILURE);