/* $Cambridge: hermes/src/prayer/utils/ssl_prune_main.c,v 1.3 2008/09/16 10:00:08 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */

#include "prayer_session.h"

int main(int argc, char *argv[])
{
    char *ports = NIL;
    char *config_filename = PRAYER_CONFIG_FILE;
    struct config *config = config_create();
    int i;
    extern char **environ;
    struct ssl_config ssl_config;

    /* Disable supplementary groups, look for (temporary) unprivileged group */
    if (getuid() == 0) {
        struct group *group;

        setgroups(0, NIL);

        if ((group = getgrnam("other")) != NIL)
            setgid(group->gr_gid);
        else if ((group = getgrnam("nobody")) != NIL)
            setgid(group->gr_gid);
    }

    if (getenv("PRAYER_CONFIG_FILE"))
        config_filename = getenv("PRAYER_CONFIG_FILE");

    initsetproctitle("prayer", argc, argv, environ);

    os_signal_init();

    response_record_version(VERSION_PRAYER);

    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "--help")) {
            fprintf(stderr, "Options:\n");
            fprintf(stderr,
                    ("  --config-file:     Define prayer config file\n"));
            fprintf(stderr,
                    ("                     "
                     "(Overrides compilation default and PRAYER_CONFIG_FILE)\n"));
            fprintf(stderr,
                    ("  --config-option:   Override single configuration option\n"));
            fprintf(stderr, "\n");
            fprintf(stderr,
                    ("  --help:            Show this list of options\n"));
            fprintf(stderr,
                    ("  --:                "
                     "End of prayer options: remaining options will be passed\n"));
            fprintf(stderr,
                    ("                     to prayer-session server process\n"));
            exit(0);
        } else if (!strncmp(argv[i],
                            "--config-file=", strlen("--config-file="))) {
            config_filename = strdup(argv[i] + strlen("--config-file="));
        } else if (!strcmp(argv[i], "--config-option")) {
            i++;                /* Processes next argv */
        } else if (!strncmp(argv[i], "--ports=", strlen("--ports="))) {
            ports = argv[i] + strlen("--ports=");
        } else if (!strcmp(argv[i], "--")) {
            continue;
        } else {
            fprintf(stderr, "Unknown option: %s\n", argv[i]);
            exit(1);
        }
    }

    config = config_create();
    if (!config_parse_file(config, config_filename))
        exit(1);

    /* prayer-ssl-prune doesn't care about hostname */
    if (config->hostname && !strcmp(config->hostname, "__UNDEFINED__"))
        config->hostname = "undefined";

    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "--config-option")) {
            if (++i < argc) {
                if (!config_parse_option(config, strdup(argv[i])))
                    exit(1);
            } else
                fprintf(stderr, "--config processes following option");
        }
    }

    if (!config_check(config))
        exit(1);

    if (!config_expand(config))
        exit(1);

    /* Generate a clean copy of the configuration without all of the noise */
    {
        struct config *config_clean = config_clone_parsed(config);

        config_free(config);
        config = config_clean;
    }

    /* Don't need root privs any more */
    if (getuid() == 0) {
        if ((config->prayer_uid == 0) || (config->prayer_uid == 0))
            log_fatal("Configured to run as root!");

        if (config->prayer_gid)
            setgid(config->prayer_gid);

        if (config->prayer_uid)
            setuid(config->prayer_uid);
    }

    if (getuid() == 0)
        log_fatal("Configured to run as root!");

    config_mkdirs(config);
    log_misc_init(config, argv[0], "prayer");

    config_extract_ssl(config, &ssl_config);
    ssl_prune_sessions(&ssl_config);

    /* NOTREACHED */
    return (0);
}
