]>
Commit | Line | Data |
---|---|---|
212380e3 AC |
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 |