]> jfr.im git - irc/rqf/shadowircd.git/blob - libcharybdis/event.c
[svn] - the new plan:
[irc/rqf/shadowircd.git] / libcharybdis / event.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * event.c: Event functions.
4 *
5 * Copyright (C) 1998-2000 Regents of the University of California
6 * Copyright (C) 2001-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * Code borrowed from the squid web cache by Adrian Chadd.
10 * Original header:
11 *
12 * DEBUG: section 41 Event Processing
13 * AUTHOR: Henrik Nordstrom
14 *
15 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
16 * ----------------------------------------------------------
17 *
18 * Squid is the result of efforts by numerous individuals from the
19 * Internet community. Development is led by Duane Wessels of the
20 * National Laboratory for Applied Network Research and funded by the
21 * National Science Foundation. Squid is Copyrighted (C) 1998 by
22 * the Regents of the University of California. Please see the
23 * COPYRIGHT file for full details. Squid incorporates software
24 * developed and/or copyrighted by other sources. Please see the
25 * CREDITS file for full details.
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
40 * USA
41 *
42 * $Id: event.c 498 2006-01-15 16:40:33Z jilles $
43 */
44
45 /*
46 * How its used:
47 *
48 * Should be pretty self-explanatory. Events are added to the static
49 * array event_table with a frequency time telling eventRun how often
50 * to execute it.
51 */
52
53 #include "stdinc.h"
54 #include "config.h"
55
56 #include "ircd.h"
57 #include "event.h"
58 #include "client.h"
59 #include "send.h"
60 #include "memory.h"
61 #include "s_log.h"
62 #include "numeric.h"
63
64 static const char *last_event_ran = NULL;
65 struct ev_entry event_table[MAX_EVENTS];
66 static time_t event_time_min = -1;
67
68 /*
69 * void eventAdd(const char *name, EVH *func, void *arg, time_t when)
70 *
71 * Input: Name of event, function to call, arguments to pass, and frequency
72 * of the event.
73 * Output: None
74 * Side Effects: Adds the event to the event list.
75 */
76 void
77 eventAdd(const char *name, EVH * func, void *arg, time_t when)
78 {
79 int i;
80
81 /* find first inactive index */
82 for (i = 0; i < MAX_EVENTS; i++)
83 {
84 if(event_table[i].active == 0)
85 {
86 event_table[i].func = func;
87 event_table[i].name = name;
88 event_table[i].arg = arg;
89 event_table[i].when = CurrentTime + when;
90 event_table[i].frequency = when;
91 event_table[i].active = 1;
92
93 if((event_table[i].when < event_time_min) || (event_time_min == -1))
94 event_time_min = event_table[i].when;
95
96 return;
97 }
98 }
99
100 /* erk! couldnt add to event table */
101 sendto_realops_snomask(SNO_DEBUG, L_ALL, "Unable to add event [%s] to event table", name);
102
103 }
104
105 void
106 eventAddOnce(const char *name, EVH *func, void *arg, time_t when)
107 {
108 int i;
109
110 /* find first inactive index */
111 for (i = 0; i < MAX_EVENTS; i++)
112 {
113 if(event_table[i].active == 0)
114 {
115 event_table[i].func = func;
116 event_table[i].name = name;
117 event_table[i].arg = arg;
118 event_table[i].when = CurrentTime + when;
119 event_table[i].frequency = 0;
120 event_table[i].active = 1;
121
122 if ((event_table[i].when < event_time_min) || (event_time_min == -1))
123 event_time_min = event_table[i].when;
124
125 return;
126 }
127 }
128
129 /* erk! couldnt add to event table */
130 sendto_realops_snomask(SNO_DEBUG, L_ALL,
131 "Unable to add event [%s] to event table", name);
132 }
133
134 /*
135 * void eventDelete(EVH *func, void *arg)
136 *
137 * Input: Function handler, argument that was passed.
138 * Output: None
139 * Side Effects: Removes the event from the event list
140 */
141 void
142 eventDelete(EVH * func, void *arg)
143 {
144 int i;
145
146 i = eventFind(func, arg);
147
148 if(i == -1)
149 return;
150
151 event_table[i].name = NULL;
152 event_table[i].func = NULL;
153 event_table[i].arg = NULL;
154 event_table[i].active = 0;
155 }
156
157 /*
158 * void eventAddIsh(const char *name, EVH *func, void *arg, time_t delta_isa)
159 *
160 * Input: Name of event, function to call, arguments to pass, and frequency
161 * of the event.
162 * Output: None
163 * Side Effects: Adds the event to the event list within +- 1/3 of the
164 * specified frequency.
165 */
166 void
167 eventAddIsh(const char *name, EVH * func, void *arg, time_t delta_ish)
168 {
169 if(delta_ish >= 3.0)
170 {
171 const time_t two_third = (2 * delta_ish) / 3;
172 delta_ish = two_third + ((rand() % 1000) * two_third) / 1000;
173 /*
174 * XXX I hate the above magic, I don't even know if its right.
175 * Grr. -- adrian
176 */
177 }
178 eventAdd(name, func, arg, delta_ish);
179 }
180
181 /*
182 * void eventRun(void)
183 *
184 * Input: None
185 * Output: None
186 * Side Effects: Runs pending events in the event list
187 */
188 void
189 eventRun(void)
190 {
191 int i;
192
193 for (i = 0; i < MAX_EVENTS; i++)
194 {
195 if(event_table[i].active && (event_table[i].when <= CurrentTime))
196 {
197 last_event_ran = event_table[i].name;
198 event_table[i].func(event_table[i].arg);
199 event_time_min = -1;
200
201 /* event is scheduled more than once */
202 if(event_table[i].frequency)
203 event_table[i].when = CurrentTime + event_table[i].frequency;
204 else
205 {
206 event_table[i].name = NULL;
207 event_table[i].func = NULL;
208 event_table[i].arg = NULL;
209 event_table[i].active = 0;
210 }
211 }
212 }
213 }
214
215
216 /*
217 * time_t eventNextTime(void)
218 *
219 * Input: None
220 * Output: Specifies the next time eventRun() should be run
221 * Side Effects: None
222 */
223 time_t
224 eventNextTime(void)
225 {
226 int i;
227
228 if(event_time_min == -1)
229 {
230 for (i = 0; i < MAX_EVENTS; i++)
231 {
232 if(event_table[i].active &&
233 ((event_table[i].when < event_time_min) || (event_time_min == -1)))
234 event_time_min = event_table[i].when;
235 }
236 }
237
238 return event_time_min;
239 }
240
241 /*
242 * void eventInit(void)
243 *
244 * Input: None
245 * Output: None
246 * Side Effects: Initializes the event system.
247 */
248 void
249 eventInit(void)
250 {
251 last_event_ran = NULL;
252 memset((void *) event_table, 0, sizeof(event_table));
253 }
254
255 /*
256 * int eventFind(EVH *func, void *arg)
257 *
258 * Input: Event function and the argument passed to it
259 * Output: Index to the slow in the event_table
260 * Side Effects: None
261 */
262 int
263 eventFind(EVH * func, void *arg)
264 {
265 int i;
266
267 for (i = 0; i < MAX_EVENTS; i++)
268 {
269 if((event_table[i].func == func) &&
270 (event_table[i].arg == arg) && event_table[i].active)
271 return i;
272 }
273
274 return -1;
275 }
276
277 /*
278 * void show_events(struct Client *source_p)
279 *
280 * Input: Client requesting the event
281 * Output: List of events
282 * Side Effects: None
283 */
284 void
285 show_events(struct Client *source_p)
286 {
287 int i;
288
289 if(last_event_ran)
290 sendto_one_numeric(source_p, RPL_STATSDEBUG,
291 "E :Last event to run: %s",
292 last_event_ran);
293
294 sendto_one_numeric(source_p, RPL_STATSDEBUG,
295 "E :Operation Next Execution");
296
297 for (i = 0; i < MAX_EVENTS; i++)
298 {
299 if(event_table[i].active)
300 {
301 sendto_one_numeric(source_p, RPL_STATSDEBUG,
302 "E :%-28s %-4d seconds",
303 event_table[i].name,
304 (int)(event_table[i].when - CurrentTime));
305 }
306 }
307 }
308
309 /*
310 * void set_back_events(time_t by)
311 * Input: Time to set back events by.
312 * Output: None.
313 * Side-effects: Sets back all events by "by" seconds.
314 */
315 void
316 set_back_events(time_t by)
317 {
318 int i;
319
320 for (i = 0; i < MAX_EVENTS; i++)
321 {
322 if(event_table[i].when > by)
323 event_table[i].when -= by;
324 else
325 event_table[i].when = 0;
326 }
327 }
328
329 void
330 eventUpdate(const char *name, time_t freq)
331 {
332 int i;
333
334 for(i = 0; i < MAX_EVENTS; i++)
335 {
336 if(event_table[i].active &&
337 !irccmp(event_table[i].name, name))
338 {
339 event_table[i].frequency = freq;
340
341 /* update when its scheduled to run if its higher
342 * than the new frequency
343 */
344 if((CurrentTime + freq) < event_table[i].when)
345 event_table[i].when = CurrentTime + freq;
346
347 return;
348 }
349 }
350 }
351
352