#include <stdio.h> #include <ctype.h> #include <fcntl.h> #include <signal.h> #include "db.h" #include "config.h" #include "externs.h" #include "mail.h" #include "gametime.h" time_t next_dbck; time_t game_time = 0; static int alarm_triggered = 0; static signal_type alarm_handler(int i) { alarm_triggered = 1; signal(SIGALRM, alarm_handler); #ifdef void_signal_type return; #else return 0; #endif } void init_timer() { signal(SIGALRM, alarm_handler); signal(SIGHUP, alarm_handler); alarm(1); } static void trig_idle_boot() { DDATA *d, *dnext; if(!config.idle_boot_time) return; for(d = descriptor_list;d;d = dnext) { dnext = d->next; if(!check_state(d, STATE_CONNECTED)) { if(now-d->last_time > config.idle_boot_time) { queue_string(d, "You have been idle for too long. Sorry.", 1); process_output(d); log_io(tprintf("Descriptor %d, host %s@%s, was idle booted.", d->descriptor, d->user, d->addr)); shutdownsock(d); } continue; } /* Make sure this part of the loop is here or it will crash because */ /* of d->player */ if(Guest(d->player)) { if(now-d->last_time > config.idle_boot_time) { notify(d->player, "You have been idle for too long. Sorry."); process_output(d); log_io(tprintf("Descriptor %d (%s) was idle booted.", d->descriptor, name(d->player))); shutdownsock(d); } } } } static time_t get_next_midnight() { struct tm *t; unsigned long num_seconds = 0; t = localtime(&now); num_seconds += t->tm_sec; num_seconds += t->tm_min*SEC_PER_MINUTE; num_seconds += t->tm_hour*SEC_PER_HOUR; return((time_t)(now+(SEC_PER_DAY-num_seconds))); } static int check_new_day() { static time_t next_midnight = 0; if(!next_midnight) { next_midnight = get_next_midnight(); return(0); } if(now < next_midnight) return(0); next_midnight = get_next_midnight(); return(1); } static void do_new_day() { } void dispatch() { extern struct timed_reboot_struct timed_reboot; extern time_t next_dump; now = time(NULL); if(!alarm_triggered) return; alarm_triggered = 0; /* Check for timed reboot */ if(timed_reboot.when) if(now >= timed_reboot.when) { if(timed_reboot.reboot) do_reboot(root_obj, timed_reboot.arg, ""); else do_shutdown(root_obj, config.maze_name, ""); } if(now >= next_dbck) { log_command("dbcking started..."); next_dbck = now+config.dbck_interval; do_dbck(root_obj); log_command("dbcking done"); } /* Database dump routines */ if(now >= next_dump) { log_command("Dumping db"); notify_except_flag("|+W|** Saving **", NULL, QUIET); flush_all_output(); fork_and_dump(); next_dump = now+config.dump_interval; } /* Stale mail deletion. */ if(now >= next_mail_clear) { log_command("Deleting old mail.\n"); clear_old_mail(); next_mail_clear = now+config.old_mail_interval; } /* Boot unidle guests and unconnected descriptors */ trig_idle_boot(); chk_hostname_update(); poll_pending_email(); if(check_new_day()) do_new_day(); plugin_timed(); /* We have to unallocate the stack here, because if everyone in the game is idle, all these timed processes will continuously make the stack grow */ stack_unalloc(); alarm(1); }