1 /************************************************************************
2 * IRC - Internet Relay Chat, events.c
3 * (C) 2001 Carsten Munk (Techie/Stskeeps) <stskeeps@tspre.org>
4 *
5 * See file AUTHORS in IRC package for additional names of
6 * the programmers.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 1, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "struct.h"
24 #include "common.h"
25 #include "sys.h"
26 #include "numeric.h"
27 #include "msg.h"
28 #include "channel.h"
29 #include "version.h"
30 #include "proto.h"
31 #include <time.h>
32 #include <sys/stat.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #ifdef _WIN32
37 #include <io.h>
38 #endif
39 #include <fcntl.h>
40 #include "h.h"
41 #include "modules.h"
42
43 ID_Copyright("(C) Carsten Munk 2001");
44
45
46 MODVAR Event *events = NULL;
47
48 #ifdef JOINTHROTTLE
49 extern EVENT(cmodej_cleanup_structs);
50 #endif
51 extern EVENT(unrealdns_removeoldrecords);
52
LockEventSystem(void)53 void LockEventSystem(void)
54 {
55 }
56
UnlockEventSystem(void)57 void UnlockEventSystem(void)
58 {
59 }
60
61
EventAddEx(Module * module,char * name,long every,long howmany,vFP event,void * data)62 Event *EventAddEx(Module *module, char *name, long every, long howmany,
63 vFP event, void *data)
64 {
65 Event *newevent;
66 if (!name || (every < 0) || (howmany < 0) || !event)
67 {
68 if (module)
69 module->errorcode = MODERR_INVALID;
70 return NULL;
71 }
72 newevent = (Event *) MyMallocEx(sizeof(Event));
73 newevent->name = strdup(name);
74 newevent->howmany = howmany;
75 newevent->every = every;
76 newevent->event = event;
77 newevent->data = data;
78 /* We don't want a quick execution */
79 newevent->last = TStime();
80 newevent->owner = module;
81 AddListItem(newevent,events);
82 if (module) {
83 ModuleObject *eventobj = (ModuleObject *)MyMallocEx(sizeof(ModuleObject));
84 eventobj->object.event = newevent;
85 eventobj->type = MOBJ_EVENT;
86 AddListItem(eventobj, module->objects);
87 module->errorcode = MODERR_NOERROR;
88 }
89 return newevent;
90
91 }
92
EventMarkDel(Event * event)93 Event *EventMarkDel(Event *event)
94 {
95 event->howmany = -1;
96 return event;
97 }
98
EventDel(Event * event)99 Event *EventDel(Event *event)
100 {
101 Event *p, *q;
102 for (p = events; p; p = p->next) {
103 if (p == event) {
104 q = p->next;
105 MyFree(p->name);
106 DelListItem(p, events);
107 if (p->owner) {
108 ModuleObject *eventobjs;
109 for (eventobjs = p->owner->objects; eventobjs; eventobjs = eventobjs->next) {
110 if (eventobjs->type == MOBJ_EVENT && eventobjs->object.event == p) {
111 DelListItem(eventobjs, p->owner->objects);
112 MyFree(eventobjs);
113 break;
114 }
115 }
116 }
117 MyFree(p);
118 return q;
119 }
120 }
121 return NULL;
122 }
123
EventFind(char * name)124 Event *EventFind(char *name)
125 {
126 Event *eventptr;
127
128 for (eventptr = events; eventptr; eventptr = eventptr->next)
129 if (!strcmp(eventptr->name, name))
130 return (eventptr);
131 return NULL;
132 }
133
EventMod(Event * event,EventInfo * mods)134 int EventMod(Event *event, EventInfo *mods) {
135 if (!event || !mods)
136 {
137 if (event && event->owner)
138 event->owner->errorcode = MODERR_INVALID;
139 return -1;
140 }
141
142 if (mods->flags & EMOD_EVERY)
143 event->every = mods->every;
144 if (mods->flags & EMOD_HOWMANY)
145 event->howmany = mods->howmany;
146 if (mods->flags & EMOD_NAME) {
147 free(event->name);
148 event->name = strdup(mods->name);
149 }
150 if (mods->flags & EMOD_EVENT)
151 event->event = mods->event;
152 if (mods->flags & EMOD_DATA)
153 event->data = mods->data;
154 if (event->owner)
155 event->owner->errorcode = MODERR_NOERROR;
156 return 0;
157 }
158
159 #ifndef _WIN32
DoEvents(void)160 inline void DoEvents(void)
161 #else
162 void DoEvents(void)
163 #endif
164 {
165 Event *eventptr;
166 Event temp;
167
168 for (eventptr = events; eventptr; eventptr = eventptr->next)
169 {
170 if (eventptr->howmany == -1)
171 goto freeit;
172 if ((eventptr->every == 0) || ((TStime() - eventptr->last) >= eventptr->every))
173 {
174 eventptr->last = TStime();
175 (*eventptr->event)(eventptr->data);
176 if (eventptr->howmany > 0)
177 {
178 eventptr->howmany--;
179 if (eventptr->howmany == 0)
180 {
181 freeit:
182 temp.next = EventDel(eventptr);
183 eventptr = &temp;
184 continue;
185 }
186 }
187 }
188 }
189 }
190
EventStatus(aClient * sptr)191 void EventStatus(aClient *sptr)
192 {
193 Event *eventptr;
194 time_t now = TStime();
195
196 if (!events)
197 {
198 sendto_one(sptr, ":%s NOTICE %s :*** No events",
199 me.name, sptr->name);
200 return;
201 }
202 for (eventptr = events; eventptr; eventptr = eventptr->next)
203 {
204 sendto_one(sptr, ":%s NOTICE %s :*** Event %s: e/%ld h/%ld n/%ld l/%ld", me.name,
205 sptr->name, eventptr->name, eventptr->every, eventptr->howmany,
206 now - eventptr->last, (eventptr->last + eventptr->every) - now);
207 }
208 }
209
SetupEvents(void)210 void SetupEvents(void)
211 {
212 LockEventSystem();
213
214 /* Start events */
215 EventAddEx(NULL, "tunefile", 300, 0, save_tunefile, NULL);
216 EventAddEx(NULL, "garbage", GARBAGE_COLLECT_EVERY, 0, garbage_collect, NULL);
217 EventAddEx(NULL, "loop", 0, 0, loop_event, NULL);
218 #ifndef NO_FDLIST
219 EventAddEx(NULL, "fdlistcheck", 1, 0, e_check_fdlists, NULL);
220 #endif
221 #ifdef JOINTHROTTLE
222 EventAddEx(NULL, "cmodej_cleanup_structs", 60, 0, cmodej_cleanup_structs, NULL);
223 #endif
224 EventAddEx(NULL, "unrealdns_removeoldrecords", 15, 0, unrealdns_removeoldrecords, NULL);
225 EventAddEx(NULL, "deprecated_notice", (86400*7)-(3600*8), 0, deprecated_notice, NULL);
226 UnlockEventSystem();
227 }
228