tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
#pragma save_binary
 
//	File	:   /adm/daemons/event.c
//	Creator	:   Glenn Ferguson (Watcher@TMI)   12/12/92
//
//	System time manager
//	- Allows events to be triggered at preset time settings
//
// Patched check_* and perform_event to the correct type, Leto 120194
// Patched a bit more and fixed security hole in query_stack, Leto 16121994
// And a bit more. It seems the event cmd needs the original
// array, don't ask me why. So, we give it. Leto 221294

#include <mudlib.h>
#include <uid.h>
#include <commands.h>
#include <logs.h>
#include <driver/origin.h>

inherit DAEMON ;

#define SAVE_FILE	"/data/adm/daemons/event"	// Save data file
 
#define INTERVAL	60			// Time check interval in sec.
#define IGNORE		900			// Remove event after X seconds
#define HOUR_DIFF	3600			// Seconds in an hour
#define DAY_DIFF	(24 * HOUR_DIFF)	// Seconds in a day
#define WEEK_DIFF	(7 * DAY_DIFF)		// Seconds in a week
#define SETUP_ARRAY	({ })			// Base storage array
 
static void load_events();
static void save_events();
static void ERROR(string mesg, string err);
static void check_once();
static void check_hourly();
static void check_daily();
static void check_weekly();
static void perform_event(string access, string file, string func, string arg);
static int sort_stack(mixed *event1, mixed *event2);
 int add_event(string type, mixed *event);
 int remove_event(string type, mixed *event);
static int initiate_sweep();
mixed *query_stack(string type);
 
mixed *HOURLY, *DAILY, *WEEKLY, *ONCE;

create() {

	seteuid(getuid(this_object()));		// Setup save permissions
	
	HOURLY = SETUP_ARRAY;				
	DAILY = SETUP_ARRAY;			// Setup event arrays
	WEEKLY = SETUP_ARRAY;
	ONCE = SETUP_ARRAY;
 
	load_events();				// Load previous saved events
	initiate_sweep();			// Start time check loop
 
}
 
 
// Load preset event stacks from save file
 
static void load_events() {
   string err;
 
   err = catch( restore_object(SAVE_FILE) );
   if(err) {  ERROR("Could not load data file", err);  return;  }
 
}
 
 
// Save present event stacks into save file
 
static void save_events() {
   string err;
 
   err = catch ( save_object(SAVE_FILE) );
   if(err) {  ERROR("Could not save data file", err);  return;  }

}
 
 
// Stack accessing error output to error file with time stamp
 
static void ERROR(string mesg, string err) {
 
   write_file(EVENT_LOG, mesg + "\t[" + extract(ctime(time()),4,15) + "]\n");
   
   if(err && err != "")
   write_file(EVENT_LOG, " " + err + "\n\n");
   else write_file(EVENT_LOG, "\n");

return;  }
 
 
// Cycling stack check function at INTERVAL intervals
 
static int initiate_sweep() {

   remove_call_out("initiate_sweep");
   call_out("initiate_sweep", INTERVAL);	// Set next time check
 
   check_once();				// Perform once stack check
   check_hourly();				// Perform hourly stack check
   check_daily();				// Perform daily stack check
   check_weekly();				// Perform weekly stack check
 
return 1;  }
 
//  Event stack processing functions - Called by initiate_sweep()
 
static void check_daily() {
   mixed *tmp;
   int loop;
 
   if(DAILY == SETUP_ARRAY)  return ;		// No events stored
 
   while( DAILY[loop] ) {
   tmp = DAILY[loop];				// Temp. store event data
 
   if(time() < DAILY[loop][0])  return ;	// Check again next interval
 
   if(time() - DAILY[loop][0] <= IGNORE)
      perform_event(DAILY[loop][4], DAILY[loop][1], DAILY[loop][2],
		    DAILY[loop][3]);

   // Remove present event, then reschedule it in the stack
   // in a day's time with same parameters.
 
   DAILY = exclude_array(DAILY, loop);
if(!add_event("daily", ({ tmp[0]+DAY_DIFF, tmp[1], tmp[2], tmp[3], tmp[4] }) )) write("Event error1\n");
   save_events();
 
   if(DAILY == SETUP_ARRAY) break;
   }
 
return ; }
 
static void check_hourly() {
   mixed *tmp;
   int loop;
 
   if(HOURLY == SETUP_ARRAY)  return ;		// No events stored

   while( HOURLY[loop] ) {
   tmp = HOURLY[loop];
 
   if(time() < HOURLY[loop][0])  return ;	// Check again next interval
 
   if(time() - HOURLY[loop][0] <= IGNORE)
      perform_event(HOURLY[loop][4], HOURLY[loop][1], HOURLY[loop][2],
		    HOURLY[loop][3]);
 
   // Remove present event, then reschedule it in the stack
 
   HOURLY = exclude_array(HOURLY, loop);
catch(add_event("hourly", ({tmp[0]+HOUR_DIFF, tmp[1], tmp[2], tmp[3], tmp[4]})));
   save_events();
 
   if(HOURLY == SETUP_ARRAY) break;
   }
 
return ; }
 
static void check_weekly() {
   mixed *tmp;
   int loop;
 
   if(WEEKLY == SETUP_ARRAY)  return ;		// No events stored
 
   while( WEEKLY[loop] ) {
   tmp = WEEKLY[loop];
 
   if(time() < WEEKLY[loop][0])  return ;	// Check again next interval
 
   if(time() - WEEKLY[loop][0] <= IGNORE)
      perform_event(WEEKLY[loop][4], WEEKLY[loop][1], WEEKLY[loop][2],
		    WEEKLY[loop][3]);
 
   // Remove present event, then reschedule it in the stack
   // in a week's time with same parameters.
 
   WEEKLY = exclude_array(WEEKLY, loop);
if(!add_event("weekly", ({ tmp[0]+WEEK_DIFF, tmp[1], tmp[2], tmp[3], tmp[4] }))) write("Event error3\n");
   save_events();
 
   if(WEEKLY == SETUP_ARRAY) break;
   }
 
return ; }
 
static void check_once() {
   int loop;
 
   if(ONCE == SETUP_ARRAY)  return ;		// No events stored
 
   while( ONCE[loop] ) {
 
   if(time() < ONCE[loop][0])  return ;	// Check again next interval

   if(time() - ONCE[loop][0] <= IGNORE)
     perform_event(ONCE[loop][4], ONCE[loop][1], ONCE[loop][2], ONCE[loop][3]);

   // Remove event from the stack and procede to next event
 
   ONCE = exclude_array(ONCE, loop);
   save_events();
 
   if(ONCE == SETUP_ARRAY) break;
   }
 
return ; }
 
 
// Perform preset event on remote object
 
static void perform_event(string access, string file, string func, string arg) {
   object what;
   string permis, err;
 
   // Attempt to locate requested target file
 
   err = catch( call_other(file, "???") );
 
   if(!err)  what = find_object(file);
 
   if(err || !what) {
   ERROR("Event error:  Could not load " + file, err);
   return ; }
 
   // Get user's command permission string
 
   permis = geteuid(what);
 
   // If attempting to access ROOT object without ROOT permissions,
   // block and log illegal access attempt
 
   if(permis == ROOT_UID && access != ROOT_UID &&
      !adminp(access)) {
   ERROR("Event error:  Illegal root access attempt by " + access,
	 "  " + func + "(" + arg + ")  on  " + file);
   return ; }
 
   // Perform stored function call on specified object
 
   err = catch( call_other(file, func, arg) );

   if(err) ERROR("Event error: " + file + " " + func + "(" + arg + ")", err);

return ; }
 
 
//  Add new event to a specified event stack
 
 int add_event(string type, mixed *event) {
   mixed *tmp;
   int loop, flag;
 
   // Check accessing permissions ... ensure root command
 
  //  if(geteuid(previous_object()) != ROOT_UID &&
  //  previous_object() != this_object())       return 0;
 
    if (previous_object()) {
      if(geteuid(previous_object()) != ROOT_UID) return 0; }
  else if( origin()!=ORIGIN_LOCAL) return 0;
   if(sizeof(event) != 5)  return 0;		// Invalid event array
 
   // Store specific stack into a temporary array
 
   if(type == "once")		tmp = ONCE;
   else if(type == "hourly")	tmp = HOURLY;
   else if(type == "daily")	tmp = DAILY;
   else if(type == "weekly")	tmp = WEEKLY;
   else return 0;				// Invalid type format
 
   //  Add new event to stack, then sort events in increasing time
 
   tmp += ({ event });
   tmp = sort_array(tmp, "sort_stack", this_object());
 
   // Replace updated event arrays from tmp
 
   if(type == "once")		ONCE = tmp;
   else if(type == "hourly")	HOURLY = tmp;
   else if(type == "daily")	DAILY = tmp;
   else if(type == "weekly")	WEEKLY = tmp;
 
   save_events();				// Save updated event stack
 
return 1; }
 
 
//  Event stack sorting routine 
 
static int sort_stack(mixed *event1, mixed *event2) {
  return ( event1[0] - event2[0] );  }
 
 
//  Event removal from specific event stack
 
 int remove_event(string type, mixed *event) {
   mixed *tmp;
   int pos;
 
   // Check accessing permissions ... ensure root command
 
   if(geteuid(previous_object()) != ROOT_UID)	return 0 ;
 
   // Store stack array into temporary array
 
   if(type == "once")		tmp = ONCE;
   else if(type == "hourly")	tmp = HOURLY;
   else if(type == "daily")	tmp = DAILY;
   else if(type == "weekly")	tmp = WEEKLY;
   else return 0 ;
 
   pos = member_array(event, tmp);
   if(pos == -1)  return 0 ;			// No such event found
 
   tmp -= ({ event });
 
   // Replace updated array back into stack
 
   if(type == "once")		ONCE = tmp;
   else if(type == "hourly")	HOURLY = tmp;
   else if(type == "daily")	DAILY = tmp;
   else if(type == "weekly")	WEEKLY = tmp;
 
   save_events();
 
return 1 ; }
 
 
// External stack request query for event command
 
mixed *query_stack(string type) {

if(base_name(previous_object())!=CMD_EVENT) {

    if(type == "once") return copy(ONCE);
    else if(type == "hourly") return copy(HOURLY);
    else if(type == "daily") return copy(DAILY);
    else if(type == "weekly") return copy(WEEKLY);
    else if(type == "all")	
return ({ copy(ONCE), copy(HOURLY), copy(DAILY), copy (WEEKLY) });
		return ({});
     }
else {
    if(type == "once") return ONCE;
    else if(type == "hourly") return HOURLY;
    else if(type == "daily") return DAILY;
    else if(type == "weekly") return WEEKLY;
    else if(type == "all")	
return ({ ONCE, HOURLY, DAILY, WEEKLY });
  return ({});
		 }
}