summaryrefslogtreecommitdiff
path: root/src/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event.c')
-rw-r--r--src/event.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..2ddc75d
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,292 @@
+/*
+ * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ * event.c: Event functions.
+ *
+ * Copyright (C) 1998-2000 Regents of the University of California
+ * Copyright (C) 2001-2002 Hybrid Development Team
+ *
+ * Code borrowed from the squid web cache by Adrian Chadd.
+ * Original header:
+ *
+ * DEBUG: section 41 Event Processing
+ * AUTHOR: Henrik Nordstrom
+ *
+ * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from the
+ * Internet community. Development is led by Duane Wessels of the
+ * National Laboratory for Applied Network Research and funded by the
+ * National Science Foundation. Squid is Copyrighted (C) 1998 by
+ * the Regents of the University of California. Please see the
+ * COPYRIGHT file for full details. Squid incorporates software
+ * developed and/or copyrighted by other sources. Please see the
+ * CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * $Id$
+ */
+
+/*
+ * How it's used:
+ *
+ * Should be pretty self-explanatory. Events are added to the static
+ * array event_table with a frequency time telling eventRun how often
+ * to execute it.
+ */
+
+#include "stdinc.h"
+#include "list.h"
+#include "ircd.h"
+#include "event.h"
+#include "client.h"
+#include "send.h"
+#include "memory.h"
+#include "log.h"
+#include "numeric.h"
+
+static const char *last_event_ran = NULL;
+static struct ev_entry event_table[MAX_EVENTS];
+static time_t event_time_min = -1;
+static int eventFind(EVH *func, void *arg);
+
+/*
+ * void eventAdd(const char *name, EVH *func, void *arg, time_t when)
+ *
+ * Input: Name of event, function to call, arguments to pass, and frequency
+ * of the event.
+ * Output: None
+ * Side Effects: Adds the event to the event list.
+ */
+void
+eventAdd(const char *name, EVH *func, void *arg, time_t when)
+{
+ int i;
+
+ /* find first inactive index, or use next index */
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if (event_table[i].active == 0)
+ {
+ event_table[i].func = func;
+ event_table[i].name = name;
+ event_table[i].arg = arg;
+ event_table[i].when = CurrentTime + when;
+ event_table[i].frequency = when;
+ event_table[i].active = 1;
+
+ if ((event_table[i].when < event_time_min) || (event_time_min == -1))
+ event_time_min = event_table[i].when;
+
+ return;
+ }
+ }
+ /* XXX if reach here, its an error */
+ ilog(LOG_TYPE_IRCD, "Event table is full! (%d)", i);
+}
+
+/*
+ * void eventDelete(EVH *func, void *arg)
+ *
+ * Input: Function handler, argument that was passed.
+ * Output: None
+ * Side Effects: Removes the event from the event list
+ */
+void
+eventDelete(EVH *func, void *arg)
+{
+ int i = eventFind(func, arg);
+
+ if (i == -1)
+ return;
+
+ event_table[i].name = NULL;
+ event_table[i].func = NULL;
+ event_table[i].arg = NULL;
+ event_table[i].active = 0;
+}
+
+/*
+ * void eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_isa)
+ *
+ * Input: Name of event, function to call, arguments to pass, and frequency
+ * of the event.
+ * Output: None
+ * Side Effects: Adds the event to the event list within +- 1/3 of the
+ * specified frequency.
+ */
+void
+eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_ish)
+{
+ if (delta_ish >= 3.0)
+ {
+ const time_t two_third = (2 * delta_ish) / 3;
+ delta_ish = two_third + ((rand() % 1000) * two_third) / 1000;
+ /*
+ * XXX I hate the above magic, I don't even know if its right.
+ * Grr. -- adrian
+ */
+ }
+
+ eventAdd(name, func, arg, delta_ish);
+}
+
+/*
+ * void eventRun(void)
+ *
+ * Input: None
+ * Output: None
+ * Side Effects: Runs pending events in the event list
+ */
+void
+eventRun(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if (event_table[i].active && (event_table[i].when <= CurrentTime))
+ {
+ last_event_ran = event_table[i].name;
+ event_table[i].func(event_table[i].arg);
+ event_table[i].when = CurrentTime + event_table[i].frequency;
+ event_time_min = -1;
+ }
+ }
+}
+
+/*
+ * time_t eventNextTime(void)
+ *
+ * Input: None
+ * Output: Specifies the next time eventRun() should be run
+ * Side Effects: None
+ */
+time_t
+eventNextTime(void)
+{
+ int i;
+
+ if (event_time_min == -1)
+ {
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if (event_table[i].active && ((event_table[i].when < event_time_min) || (event_time_min == -1)))
+ event_time_min = event_table[i].when;
+ }
+ }
+
+ return(event_time_min);
+}
+
+/*
+ * void eventInit(void)
+ *
+ * Input: None
+ * Output: None
+ * Side Effects: Initializes the event system.
+ */
+void
+eventInit(void)
+{
+ last_event_ran = NULL;
+ memset(event_table, 0, sizeof(event_table));
+}
+
+/*
+ * int eventFind(EVH *func, void *arg)
+ *
+ * Input: Event function and the argument passed to it
+ * Output: Index to the slow in the event_table
+ * Side Effects: None
+ */
+static int
+eventFind(EVH *func, void *arg)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if ((event_table[i].func == func) &&
+ (event_table[i].arg == arg) &&
+ event_table[i].active)
+ return(i);
+ }
+
+ return(-1);
+}
+
+/*
+ * void show_events(struct Client *source_p)
+ *
+ * Input: Client requesting the event
+ * Output: List of events
+ * Side Effects: None
+ */
+void
+show_events(struct Client *source_p)
+{
+ int i;
+
+ if (last_event_ran)
+ {
+ sendto_one(source_p, ":%s %d %s :Last event to run: %s",
+ me.name, RPL_STATSDEBUG, source_p->name, last_event_ran);
+ sendto_one(source_p, ":%s %d %s : ",
+ me.name, RPL_STATSDEBUG, source_p->name);
+ }
+
+ sendto_one(source_p,
+ ":%s %d %s : Operation Next Execution",
+ me.name, RPL_STATSDEBUG, source_p->name);
+ sendto_one(source_p,
+ ":%s %d %s : -------------------------------------------",
+ me.name, RPL_STATSDEBUG, source_p->name);
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ if (event_table[i].active)
+ {
+ sendto_one(source_p, ":%s %d %s : %-28s %-4d seconds",
+ me.name, RPL_STATSDEBUG, source_p->name,
+ event_table[i].name,
+ (int)(event_table[i].when - CurrentTime));
+ }
+
+ sendto_one(source_p, ":%s %d %s : ",
+ me.name, RPL_STATSDEBUG, source_p->name);
+}
+
+/*
+ * void set_back_events(time_t by)
+ * Input: Time to set back events by.
+ * Output: None.
+ * Side-effects: Sets back all events by "by" seconds.
+ */
+void
+set_back_events(time_t by)
+{
+ int i;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ if (event_table[i].when > by)
+ event_table[i].when -= by;
+ else
+ event_table[i].when = 0;
+ }
+}
+