void
test_load_paths (void)
{
    const gchar *config_dir;

    config_dir = g_getenv("MILTER_MANAGER_CONFIG_DIR");
    if (config_dir)
        expected_load_paths = g_list_append(expected_load_paths,
                                            g_strdup(config_dir));
    expected_load_paths = g_list_append(expected_load_paths,
                                        g_strdup(CONFIG_DIR));
    gcut_assert_equal_list_string(
        expected_load_paths,
        milter_manager_configuration_get_load_paths(config));

    expected_load_paths = g_list_append(expected_load_paths,
                                        g_strdup("append/XXX"));
    milter_manager_configuration_append_load_path(config, "append/XXX");
    gcut_assert_equal_list_string(
        expected_load_paths,
        milter_manager_configuration_get_load_paths(config));

    expected_load_paths = g_list_prepend(expected_load_paths,
                                         g_strdup("prepend/XXX"));
    milter_manager_configuration_prepend_load_path(config, "prepend/XXX");
    gcut_assert_equal_list_string(
        expected_load_paths,
        milter_manager_configuration_get_load_paths(config));


    milter_manager_configuration_clear_load_paths(config);
    gcut_assert_equal_list_string(
        NULL,
        milter_manager_configuration_get_load_paths(config));
}
void
test_save_custom (void)
{
    GError *error = NULL;
    gchar *custom_config_path;

    custom_config_path = g_build_filename(tmp_dir,
                                          CUSTOM_CONFIG_FILE_NAME,
                                          NULL);
    cut_take_string(custom_config_path);

    milter_manager_configuration_prepend_load_path(config, tmp_dir);

    cut_assert_path_not_exist(custom_config_path);
    milter_manager_configuration_save_custom(config, "XXX", -1, &error);
    gcut_assert_error(error);
    cut_assert_path_exist(custom_config_path);
}
gboolean
milter_manager_main (void)
{
    MilterClient *client;
    MilterManager *manager;
    MilterManagerController *controller;
    MilterManagerConfiguration *config;
    MilterEventLoop *loop;
    gboolean remove_socket, daemon;
    GError *error = NULL;
    struct sigaction shutdown_client_action;
    struct sigaction reload_configuration_request_action;
    struct sigaction reopen_log_action;

    manager = the_manager;
    config = milter_manager_get_configuration(manager);

    if (option_config_dir) {
        milter_manager_configuration_prepend_load_path(config,
                                                       option_config_dir);
        if (!milter_manager_reload(manager, &error)) {
            milter_manager_error("[manager][configuration][reload]"
                                 "[command-line-load-path][error] %s",
                                 error->message);
            g_error_free(error);
            error = NULL;
        }
    }
    if (getuid() != 0)
        milter_manager_configuration_set_privilege_mode(config, FALSE);


    client = MILTER_CLIENT(manager);
    g_signal_connect(client, "error", G_CALLBACK(cb_error), NULL);

    append_custom_configuration_directory(config);
    load_configuration(manager);

    if (option_show_config) {
        gchar *dumped_config;

        dumped_config = milter_manager_configuration_dump(config);
        if (dumped_config) {
            g_print("%s", dumped_config);
            if (!g_str_has_suffix(dumped_config, "\n"))
                g_print("\n");
            g_free(dumped_config);
        }
        return TRUE;
    }

    update_max_file_descriptors(manager);

    if (milter_manager_configuration_is_privilege_mode(config) &&
        !start_process_launcher_process(manager)) {
        return FALSE;
    }

    remove_socket = milter_manager_configuration_is_remove_manager_unix_socket_on_create(config);
    milter_client_set_remove_unix_socket_on_create(client, remove_socket);

    if (!milter_client_listen(client, &error)) {
        milter_manager_error("failed to listen: %s", error->message);
        g_error_free(error);
        return FALSE;
    }

    if (!milter_client_drop_privilege(client, &error)) {
        milter_manager_error("failed to drop privilege: %s", error->message);
        g_error_free(error);
        return FALSE;
    }

    loop = milter_client_get_event_loop(client);
    controller = milter_manager_controller_new(manager, loop);
    if (controller && !milter_manager_controller_listen(controller, &error)) {
        milter_manager_error("failed to listen controller socket: %s",
                             error->message);
        g_error_free(error);
        error = NULL;
        g_object_unref(controller);
        controller = NULL;
    }

    daemon = milter_client_is_run_as_daemon(client);
    if (daemon) {
        if (milter_client_daemonize(client, &error)) {
            io_detached = TRUE;
        } else {
            milter_manager_error("failed to daemonize: %s", error->message);
            g_error_free(error);
            if (controller)
                g_object_unref(controller);
            return FALSE;
        }
    }

    the_manager = manager;

#define SETUP_SIGNAL_ACTION(handler)            \
    handler ## _action.sa_handler = handler;    \
    sigemptyset(&handler ## _action.sa_mask);   \
    handler ## _action.sa_flags = 0

    SETUP_SIGNAL_ACTION(shutdown_client);
    SETUP_SIGNAL_ACTION(reload_configuration_request);
    SETUP_SIGNAL_ACTION(reopen_log);
#undef SETUP_SIGNAL_ACTION

#define SET_SIGNAL_ACTION(SIGNAL, signal, action)               \
    if (sigaction(SIG ## SIGNAL,                                \
                  &action,                                      \
                  &default_sig ## signal ## _action) == -1)     \
        set_sig ## signal ## _action = FALSE

    SET_SIGNAL_ACTION(INT, int, shutdown_client_action);
    SET_SIGNAL_ACTION(TERM, term, shutdown_client_action);
    SET_SIGNAL_ACTION(HUP, hup, reload_configuration_request_action);
    SET_SIGNAL_ACTION(USR1, usr1, reopen_log_action);
#undef SET_SIGNAL_ACTION

    if (!milter_client_run(client, &error)) {
        milter_manager_error("failed to start milter-manager process: %s",
                             error->message);
        g_error_free(error);
    }

#define UNSET_SIGNAL_ACTION(SIGNAL, signal)                             \
    if (set_sig ## signal ## _action)                                   \
        sigaction(SIG ## SIGNAL, &default_sig ## signal ## _action, NULL)

    UNSET_SIGNAL_ACTION(SEGV, segv);
    UNSET_SIGNAL_ACTION(ABRT, abort);
    UNSET_SIGNAL_ACTION(INT, int);
    UNSET_SIGNAL_ACTION(TERM, term);
    UNSET_SIGNAL_ACTION(HUP, hup);
    UNSET_SIGNAL_ACTION(USR1, usr1);
#undef UNSET_SIGNAL_ACTION

    if (controller)
        g_object_unref(controller);

    return TRUE;
}