/* /secure/daemon/events.c * from the Foundation II LPC Library * an event monitoring daemon, for call outs across time * created by Descartes of Borg 950501 */ #include <lib.h> #include <save.h> #include <config.h> #include <daemons.h> #include <privs.h> #include "events.h" inherit LIB_DAEMON; private int RebootInterval; private mapping Events; private static int InReboot = 0; static void create() { daemon::create(); SetNoClean(1); if( file_exists(SAVE_EVENTS __SAVE_EXTENSION__) ) unguarded((: restore_object, SAVE_EVENTS :)); if( !RebootInterval ) RebootInterval = 170; if( !Events ) Events = ([]); eventSave(); call_out((: eventPollEvents :), 60); } varargs static int eventSave(int ung) { if( ung ) { unguarded( (: save_object, SAVE_EVENTS :) ); return 1; } else return save_object(SAVE_EVENTS); } int GetRebooting(){ return InReboot; } void eventReboot(int x) { if( previous_object() && !((int)master()->valid_apply(({ PRIV_ASSIST }))) ) return; InReboot = 1; if( x < 1 ) x = 1; x *= 60; message("broadcast", mud_name() + " will reboot in " + consolidate(x/60, "a minute") + ".", users()); if( x < 61 ) call_out( (: eventAnnounceReboot, 10 :), x - 10); else { int y; y = x/60; y = ((2*y)/3) * 60; call_out( (: eventAnnounceReboot($(y)) :), x - y); } } static void eventAnnounceReboot(int x) { if( x == 10 ) { message("broadcast", "Last warning: Reboot in 10 seconds.", users()); call_out( (: Shutdown :), 10 ); } else if( x < 61 ) { message("broadcast", mud_name() + " will reboot in a minute.", users()); call_out( (: eventAnnounceReboot, 10 :), 50); } else { int y; message("broadcast", "Reboot in " + (x/60) + " minutes.", users()); y = ((2 * (x/60))/3) * 60; call_out( (: eventAnnounceReboot($(y)) :), x - y); } } void eventShutdown() { if( !((int)master()->valid_apply( ({ PRIV_ASSIST }) )) ) return; Shutdown(); } static void Shutdown() { message("broadcast", "Shutting down " + mud_name() + " immediately!", users()); map(users(), (: catch($1->cmdQuit()) :)); shutdown(); } static void eventPollEvents() { int *events; int i, x; call_out((: eventPollEvents :), 60); x = time(); i = sizeof(events = keys(Events)); while(i--) { if( events[i] <= x ) { object ob; function f; if( !(ob = find_object(Events[events[i]]["creator"]) ) && !(ob = load_object(Events[events[i]]["creator"])) ) { map_delete(Events, events[i]); continue; } f = (: call_other, Events[events[i]]["object"], Events[events[i]]["function"] :); f = bind(f, ob); catch(evaluate(f, Events[events[i]]["args"]...)); if( Events[events[i]]["regular"] > 0 ) Events[x + Events[events[i]]["interval"]] = Events[events[i]]; map_delete(Events, events[i]); } } if( (uptime() > RebootInterval*3600) && !InReboot && !DISABLE_REBOOTS) { InReboot = 1; eventReboot(MINUTES_REBOOT_WARNING); } eventSave(); } int SetRebootInterval(int x) { int y; y = RebootInterval; if( x > 1 ) RebootInterval = x; if( !eventSave() ) RebootInterval = y; return RebootInterval; } int GetRebootInterval() { return RebootInterval; } void AddEvent(string c, string s, string f, mixed *a, int w, int r) { mapping NewEvent; if( file_name(previous_object()) != SEFUN && file_name(previous_object()) != UPDATE_D) { if(EVENTS_LOGGING){ unguarded( (: write_file("/log/secure/events",timestamp()+" "+ identify(previous_object(-1))+" ILLEGALLY tried to add an event.\n") :) ); } return; } NewEvent = ([ "object" : s, "function" : f, "args" : a, "creator" : c, "regular" : (r ? w : 0), "interval" : w ]); if(EVENTS_LOGGING) unguarded( (: write_file("/log/secure/events",timestamp()+ identify(previous_object(-1))+" added this event: "+ identify($(NewEvent))+"\n") :) ); Events[time() + w] = NewEvent; eventSave(1); } void RemoveEvent(int i){ if( file_name(previous_object()) != SEFUN ) return; if(sizeof(Events[i])){ map_delete(Events, i); eventSave(1); } } mapping GetEvents() { return copy(Events); }