/* * Detta {r serverns huvudprogram. Det kommer f|rhoppningsvis bli st|rre * {n det {r just nu... * * Created by Willf|r 31/3-90 * * It has grown! /ceder */ #include #include #include #include #include #include #include #include #include #include #include #include #include "std-disclaimer.h" #include "s-string.h" #include #include "string-malloc.h" #include #include "internal-services.h" #include "lyskomd.h" #include "isc.h" #include "smalloc.h" #include "cache.h" #include "log.h" #include "com.h" #include "connections.h" #include "config.h" #include "exp.h" #include "memory.h" #include "internal-connections.h" Kom_err kom_errno; u_long err_stat; Bool send_async_messages = TRUE; #ifdef DEBUG int buglevel = 0; Bool never_save = FALSE; #endif EXPORT char datafilename[1024]; /* Full pathname to the database file */ EXPORT char backupfilename[1024]; /* Full pathname to the backup file */ EXPORT char textfilename[1024]; /* Full pathname to the text file. */ EXPORT char statisticfile[1024]; /* Dito to statistics file. */ EXPORT char pidfile[1024]; /* Dito pid-file. */ INTERNAL char memusefile[1024]; /* Memory usage file. */ char ip_client_port[80]; /* Port to listen to for clients */ char ip_mux_port[80]; /* Port to listen to for mux:es */ int listen_client = -1; /* ISC listen identifier */ int listen_mux = -1; /* -"- */ static char *dbase_dir = NULL; /* Directory where database resides */ static void server_init( char * client_port, char * mux_port) { /* ** Setup some parameters here */ isc_setlogfn(&logv); isc_setallocfn(&smalloc, &srealloc, &sfree); /* isc_setabortfn(&restart_kom); */ kom_server_mcb = isc_initialize(NULL); if ( kom_server_mcb == NULL ) restart_kom("server_init: can't isc_setup()\n"); if ((listen_client = isc_listentcp(kom_server_mcb, client_port)) < 0) restart_kom("server_init: can't isc_listen(CLIENT)\n"); if ((listen_mux = isc_listentcp(kom_server_mcb, mux_port)) < 0) restart_kom("server_init: can't isc_listen(MUX)\n"); /* * Ignore SIGPIPE, which the server gets if it tries to write to a * socket and the client has died. The server will anyhow handle * this situation correct. */ signal(SIGPIPE, SIG_IGN); } static void init_data_base(const char *dbase_dir) { String a = EMPTY_STRING, b = EMPTY_STRING, c = EMPTY_STRING, d = EMPTY_STRING; if (dbase_dir == NULL) dbase_dir = DEFAULT_DBASE_DIR; sprintf(datafilename, "%s/%s", dbase_dir, DATAFILE_NAME); sprintf(backupfilename, "%s/%s", dbase_dir, BACKUPFILE_NAME); sprintf(textfilename, "%s/%s", dbase_dir, TEXTFILE_NAME); sprintf(statisticfile, "%s/%s", dbase_dir, STATISTIC_NAME); sprintf(pidfile, "%s/%s", dbase_dir, PID_NAME); sprintf(memusefile, "%s/%s", dbase_dir, MEMUSE_NAME); log("Database = %s\n", datafilename); log("Backup = %s\n", backupfilename); if ( init_cache() == FAILURE ) { log ( "Setting up first four conferences.\n"); if ( s_crea_str(&a, "Presentation (av nya) m|ten") != OK || s_crea_str(&b, "Presentation (av nya) medlemmar") != OK || s_crea_str(&c, "Lappar (p}) d|rren") != OK || s_crea_str(&d, "Nyheter om LysKOM") != OK) { restart_kom("init_data_base: can't create strings\n"); } if ( ! ( do_create_conf(a, 0, 0, 0, NULL_CONF_TYPE) && do_create_conf(b, 0, 0, 0, NULL_CONF_TYPE) && do_create_conf(c, 0, 0, 0, NULL_CONF_TYPE) && do_create_conf(d, 0, 0, 0, NULL_CONF_TYPE))) { restart_kom("init_data_base: Kan ej skapa m|ten\n"); } s_clear(&a); s_clear(&b); s_clear(&c); s_clear(&d); } } void sighandler_hup (int sig) { log ("Signal HUP received. Shutting down server.\n"); go_and_die = TRUE; } void sighandler_quit (int sig) { log ("Signal QUIT received - syncing...\n"); cache_sync_all(); log ("Dumping core now.\n"); chdir ("/usr/lyskom/etc"); abort(); } void sighandler_usr1 (int sig) { do_sync_db = TRUE; } void sighandler_usr2 (int sig) { int child; extern int fork(void); log ("Signal USR2 received - will dump core now. (Check that child dies.)\n"); if ((child = fork()) == 0) { chdir ("/usr/lyskom/etc"); abort(); log ("Abort() failed!!!"); exit(1); } else if (child < 0) { log ("Couldn't fork.\n"); } else { wait (NULL); } } void save_pid(void) { FILE *fp; if ( (fp = fopen(pidfile, "w")) == NULL ) return; fprintf(fp, "%d", getpid()); fclose(fp); } int main (int argc, char **argv) { int i; FILE *stat_file; extern int number_of_allocated_strings(void); /* From s-string.c */ s_set_storage_management(string_malloc, string_realloc, string_free); setlocale(LC_CTYPE, "iso_8859_1"); strcpy(ip_client_port, DEFAULT_CLIENT_SERVICE); strcpy(ip_mux_port, DEFAULT_MUX_SERVICE); for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'd': buglevel++; break; case 'q': never_save = TRUE; break; case 'D': /* Database directory */ dbase_dir = argv[i]+2; break; case 'p': /* TCP/IP port number for clients */ strcpy(ip_client_port, argv[i]+2); break; case 'P': /* TCP/IP port number for MUXes */ strcpy(ip_mux_port, argv[i]+2); break; case 'a': send_async_messages = FALSE; break; default: restart_kom("usage: ramkomd [options]\n"); } if (i < argc) { restart_kom("usage: ramkomd\n"); } signal(SIGHUP, sighandler_hup); signal(SIGQUIT, sighandler_quit); signal(SIGUSR1, sighandler_usr1); signal(SIGUSR2, sighandler_usr2); server_init(ip_client_port, ip_mux_port); init_data_base(dbase_dir); save_pid(); toploop(); logout_all_clients(); isc_shutdown(kom_server_mcb); cache_sync_all(); stat_file = fopen(memusefile, "w"); if ( stat_file == NULL ) restart_kom("Can't open file to save memory usage to.\n"); dump_cache_stats (stat_file); free_all_tmp(); free_all_cache(); dump_smalloc_counts(stat_file); dump_alloc_counts(stat_file); dump_cache_mem_usage(stat_file); fprintf(stat_file, "---s-string.c:\n\tStrings: %d\n", number_of_allocated_strings()); dump_string_alloc_counts(stat_file); dump_allocated_connections(stat_file); fclose (stat_file); log("ramkomd terminated normally.\n"); return 0; } void restart_kom(const char * format, ...) { va_list AP; va_start(AP, format); logv(format, AP); va_end(AP); log("Previous message is fatal. Will dump core now.\n"); abort(); }