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