OPT_SC_RESOLVE_UID(opts); OPT_SC_RESOLVE_GID(opts);
static void serv_cmd_line(int argc, char *argv[]){  int optchar = 0;  const char *program_name = NULL;  struct option long_options[] =  {   OPT_SERV_DECL_GETOPTS(),      {"configuration-file", required_argument, NULL, 'C'},   {"config-file",        required_argument, NULL, 'C'},   {"configuration-data-daemon", required_argument, NULL, 143},   {"config-data-daemon",        required_argument, NULL, 143},   {"configuration-data-httpd", required_argument, NULL, 144},   {"config-data-httpd",        required_argument, NULL, 144},   {"configuration-data-and-httpd", required_argument, NULL, 144},   {"config-data-and-httpd",        required_argument, NULL, 144},      {"sendfile", optional_argument, NULL, 31},   {"mmap", optional_argument, NULL, 30},      {"max-header-sz", required_argument, NULL, 128},   {"keep-alive", optional_argument, NULL, 129},   {"keep-alive-1.0", optional_argument, NULL, 130},   {"vhosts", optional_argument, NULL, 131},   {"virtual-hosts", optional_argument, NULL, 131},   {"range", optional_argument, NULL, 132},   {"range-1.0", optional_argument, NULL, 133},   {"public-only", optional_argument, NULL, 134}, /* FIXME: rm ? */   {"dir-filename", required_argument, NULL, 135},   {"server-name", required_argument, NULL, 136},   {"gzip-content-replacement", optional_argument, NULL, 137},   /* 138 */   {"error-406", optional_argument, NULL, 139},   /* 140 */   {"mime-types-main", required_argument, NULL, 141},   {"mime-types-extra", required_argument, NULL, 142},   {"mime-types-xtra", required_argument, NULL, 142},   /* 143 -- config data above */   /* 144 -- config data above */   {"unspecified-hostname", required_argument, NULL, 145},   {"canonize-host", optional_argument, NULL, 146},   {"error-host-400", optional_argument, NULL, 147},   {"check-host", optional_argument, NULL, 148},   /* {"404-file", required_argument, NULL, 0}, */   {NULL, 0, NULL, 0}  };  const char *chroot_dir = NULL;  const char *document_root = NULL;  Vstr_base *out = vstr_make_base(NULL);  Httpd_policy_opts *popts = NULL;  if (!out)    errno = ENOMEM, err(EXIT_FAILURE, "command line");  evnt_opt_nagle = TRUE;    program_name = opt_program_name(argv[0], HTTPD_CONF_PROG_NAME);  httpd_opts->s->name_cstr = program_name;  httpd_opts->s->name_len  = strlen(program_name);  httpd_opts->s->make_policy = httpd_policy_make;  httpd_opts->s->copy_policy = httpd_policy_copy;  if (!httpd_conf_main_init(httpd_opts))    errno = ENOMEM, err(EXIT_FAILURE, "options");  if (!geteuid()) /* If root */    httpd_opts->s->addr_beg->tcp_port = HTTPD_CONF_SERV_DEF_PORT;  else /* somewhat common unprived port */    httpd_opts->s->addr_beg->tcp_port = 8008;      popts = (Httpd_policy_opts *)httpd_opts->s->def_policy;  while ((optchar = getopt_long(argc, argv, "C:dhH:M:nP:t:V",                                long_options, NULL)) != -1)  {    switch (optchar)    {      case '?': usage(program_name, EXIT_FAILURE, "");      case 'h': usage(program_name, EXIT_SUCCESS, "");              case 'V':        vstr_add_fmt(out, 0, " %s version %s.\n",                     program_name, HTTPD_CONF_VERSION);                if (io_put_all(out, STDOUT_FILENO) == IO_FAIL)          err(EXIT_FAILURE, "write");                exit (EXIT_SUCCESS);            OPT_SERV_GETOPTS(httpd_opts->s);      case 'C':        if (!httpd_conf_main_parse_file(out, httpd_opts, optarg))          goto out_err_conf_msg;        break;      case 143: /* FIXME: ... need to integrate */        if (!opt_serv_conf_parse_cstr(out, httpd_opts->s, optarg))          goto out_err_conf_msg;      break;      case 144:        if (!httpd_conf_main_parse_cstr(out, httpd_opts, optarg))          goto out_err_conf_msg;        break;              case 128: OPT_NUM_NR_ARG(popts->max_header_sz, "max header size"); break;              case  31: OPT_TOGGLE_ARG(popts->use_sendfile);                 break;      case  30: OPT_TOGGLE_ARG(popts->use_mmap);                     break;              case 129: OPT_TOGGLE_ARG(popts->use_keep_alive);               break;      case 130: OPT_TOGGLE_ARG(popts->use_keep_alive_1_0);           break;      case 131: OPT_TOGGLE_ARG(popts->use_vhosts_name);              break;      case 132: OPT_TOGGLE_ARG(popts->use_range);                    break;      case 133: OPT_TOGGLE_ARG(popts->use_range_1_0);                break;      case 134: OPT_TOGGLE_ARG(popts->use_public_only);              break;      case 135: OPT_VSTR_ARG(popts->dir_filename);                   break;      case 136: OPT_VSTR_ARG(popts->server_name);                    break;      case 137: OPT_TOGGLE_ARG(popts->use_enc_content_replacement);  break;      case 139: OPT_TOGGLE_ARG(popts->use_err_406);                  break;        /* case 140: */      case 141: OPT_VSTR_ARG(popts->mime_types_main);                break;      case 142: OPT_VSTR_ARG(popts->mime_types_xtra);                break;        /* case 143: */        /* case 144: */      case 145: OPT_VSTR_ARG(popts->default_hostname);               break;      case 146: OPT_TOGGLE_ARG(popts->use_canonize_host);            break;      case 147: OPT_TOGGLE_ARG(popts->use_host_err_400);             break;      case 148: OPT_TOGGLE_ARG(popts->use_host_err_chk);                    ASSERT_NO_SWITCH_DEF();    }  }  vstr_free_base(out); out = NULL;    argc -= optind;  argv += optind;  if (argc > 1)    usage(program_name, EXIT_FAILURE, " Too many arguments.\n");  if (argc == 1)  {    Vstr_base *tmp = popts->document_root;    vstr_sub_cstr_ptr(tmp, 1, tmp->len, argv[0]);  }  if (!popts->document_root->len)    usage(program_name, EXIT_FAILURE, " Not specified a document root.\n");    if (httpd_opts->s->become_daemon)  {    if (daemon(FALSE, FALSE) == -1)      err(EXIT_FAILURE, "daemon");    vlg_daemon(vlg, program_name);  }  if (httpd_opts->s->rlim_core_call)    opt_serv_sc_rlim_core_num(httpd_opts->s->rlim_core_num);  if (httpd_opts->s->rlim_file_call)    opt_serv_sc_rlim_file_num(httpd_opts->s->rlim_file_num);    {    const char *pid_file = NULL;    const char *cntl_file = NULL;    Opt_serv_opts *opts = httpd_opts->s;        OPT_SC_EXPORT_CSTR(pid_file,   opts->pid_file,   FALSE, "pid file");    OPT_SC_EXPORT_CSTR(cntl_file,  opts->cntl_file,  FALSE, "control file");    OPT_SC_EXPORT_CSTR(chroot_dir, opts->chroot_dir, FALSE, "chroot directory");        serv_make_bind(program_name);    if (!httpd_init_default_hostname(httpd_opts->s->def_policy))      errno = ENOMEM, err(EXIT_FAILURE, "default_hostname");      if (pid_file)      vlg_pid_file(vlg, pid_file);    if (cntl_file)      cntl_make_file(vlg, cntl_file);    serv_canon_policies();      OPT_SC_EXPORT_CSTR(document_root, popts->document_root, TRUE,                       "document root");        serv_mime_types(program_name);        if (chroot_dir)    { /* preload locale info. so syslog can log in localtime, this doesn't work       * with current glibc's as they re-stat ... maybe set the ENV somehow? */      time_t now = time(NULL);      (void)localtime(&now);            vlg_sc_bind_mount(chroot_dir);    }        /* after daemon so don't use err() anymore ... */        if (chroot_dir && ((chroot(chroot_dir) == -1) || (chdir("/") == -1)))      vlg_err(vlg, EXIT_FAILURE, "chroot(%s): %m\n", chroot_dir);        if (opts->drop_privs)    {      if (opts->keep_cap_fowner && (PROC_CNTL_KEEPCAPS(TRUE) == -1))      {        vlg_warn(vlg, "prctl(%s, %s): %m\n", "PR_SET_KEEPCAPS", "TRUE");        opts->keep_cap_fowner = FALSE;      }            OPT_SC_RESOLVE_UID(opts);      OPT_SC_RESOLVE_GID(opts);      opt_serv_sc_drop_privs(opts);            if (opts->keep_cap_fowner)      {        cap_t caps = cap_from_text("cap_fowner+ep-i");        if (!caps)          vlg_err(vlg, EXIT_FAILURE, "cap_from_text(%s): %m\n",                  "cap_fowner+pe-i");                if (PROC_CNTL_KEEPCAPS(FALSE) == -1)          vlg_err(vlg, EXIT_FAILURE,                  "prctl(%s, %s): %m\n", "PR_SET_KEEPCAPS", "FALSE");                if (cap_set_proc(caps) == -1)          vlg_err(vlg, EXIT_FAILURE, "cap_set_proc(%s): %m\n",                  "cap_fowner+ep-i");        if (cap_free(caps) == -1)          vlg_err(vlg, EXIT_FAILURE, "cap_free(): %m\n");      }    }    if (opts->num_procs > 1)      cntl_sc_multiproc(vlg, opts->num_procs, !!cntl_file, opts->use_pdeathsig);        if (opts->make_dumpable && (PROC_CNTL_DUMPABLE(TRUE) == -1))      vlg_warn(vlg, "prctl(%s, %s): %m\n", "PR_SET_DUMPABLE", "TRUE");  }  httpd_opts->beg_time = time(NULL);    {    struct Evnt *evnt = evnt_queue("accept");        while (evnt)    {      vlg_info(vlg, "READY [$<sa:%p>]: %s%s%s\n", EVNT_SA(evnt),               chroot_dir ? chroot_dir : "",               chroot_dir ?        "/" : "",               document_root);      evnt = evnt->next;    }  }    opt_serv_conf_free(httpd_opts->s);  return; out_err_conf_msg:  vstr_add_cstr_ptr(out, out->len, "\n");  if (io_put_all(out, STDERR_FILENO) == IO_FAIL)    err(EXIT_FAILURE, "write");  exit (EXIT_FAILURE);  }