/* Copyright (C) 2003, 2004 IRCtoo Network, Pasi Hirvonen * * Parts written by FJ (David). Based on the original work by Pasi Hirvonen * and Matthew Stephenson. Various others have contributed ideas and testing.*/ /* $Id: main.c 153 2004-05-25 22:04:30Z pasi $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "spamserv.h" #include "structs.h" #include "mainloop.h" #include "configparser.h" #include "users.h" #include "pseudoclient.h" #include "irc.h" #include "log.h" #include "server.h" #include "motd.h" #include "magic.h" #include "database.h" #include "util.h" #include "cycles.h" #define DEBUG extern struct status_t status; extern struct conf_t conf; extern GSList *nicklist, *gsmotd, *users, *cyclechans; void s_do_init(void); void s_do_fork(void); void handle_ctrlc(int); void s_rehash_config(void) { /* make sure spamserv is in correct channels */ s_controlbot_del_chans(); read_config(); s_controlbot_add_chans(TRUE); } void handle_ctrlc(int signum __attr_unused__) { if (status.quitting == 1) { /* Force exit */ exit(0); } status.quitting = 1; } void s_do_init(void) { signal(SIGHUP, handle_hup); signal(SIGINT, handle_ctrlc); read_config(); status.started = time(NULL); status.stats.pseudoclient_count = 0; status.stats.global_users = 0; status.stats.parsed_privmsgs = 0; status.stats.set_autokills = 0; status.stats.killed_users = 0; status.stats.matched_spams = 0; status.connected = 0; status.forked = 0; status.synched = 0; status.quitting = 0; s_do_fork(); s_log(LOG_MISC, "Loading databases."); if (database_init() < 0) { s_log(LOG_ERROR, "Unable to load database!"); } if (database_load_channels() < 0) s_log(LOG_ERROR, "Unable to load channels!"); if (database_load_spamstrs() < 0) s_log(LOG_ERROR, "Unable to load spam strings!"); if (database_load_cycles() < 0) s_log(LOG_ERROR, "Unable to load cycle channels"); s_add_controlbot(); status.scheduler = g_timer_new(); } void s_cleanup() { database_deinit(); get_string_setting(NULL); s_free_pseudoclients(); spam_str_clean_all(); cleanup_config_strings(); s_log_close_handles(); g_timer_destroy(status.scheduler); s_free_slist_generic(&nicklist); s_free_slist_generic(&gsmotd); s_free_slist_generic(&users); s_free_slist_generic(&cyclechans); timeout_clean(); if (status.connected) s_close_connection("Shutting down SpamServ."); } void s_do_fork(void) { pid_t pid; if (!conf.fork) return; pid = fork(); if (pid == -1) s_fatal("fork() failed!"); else if (pid == 0) { /* child process */ s_log(LOG_NORMAL, "Forked to background."); status.forked = 1; } else { /* parent */ s_cleanup(); exit(1); } } void s_fatal(const char *fmt, ...) { va_list ap; va_start(ap, fmt); if (status.connected) { i_send_globops("Crashing! Fatal error!"); } (void)g_fprintf(stderr, "FATAL ERROR: "); (void)g_vfprintf(stderr, fmt, ap); va_end(ap); s_cleanup(); abort(); } int main(int argc __attr_unused__, char **argv __attr_unused__) { struct rlimit cdlim; cdlim.rlim_cur = RLIM_INFINITY; cdlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &cdlim); s_log(LOG_NORMAL, "SpamServ starting up."); s_do_init(); s_log(LOG_DEBUG, "Entering SpamServ main IO loop."); s_main_loop(); s_log(LOG_NORMAL, "SpamServ cleaning up and exiting."); s_cleanup(); return 0; }