/[cvs]/eggdrop1.9/src/modules.c
ViewVC logotype

Contents of /eggdrop1.9/src/modules.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.137 - (show annotations) (download) (as text)
Tue May 13 07:16:18 2003 UTC (16 years, 4 months ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.136: +1 -1 lines
File MIME type: text/x-chdr
FILE REMOVED
* Added help to error message if tcl isn't found
* Remove some stray files

1 /*
2 * modules.c --
3 *
4 * support for modules in eggdrop
5 *
6 * by Darrin Smith (beldin@light.iinet.net.au)
7 */
8 /*
9 * Copyright (C) 1997 Robey Pointer
10 * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 #ifndef lint
28 static const char rcsid[] = "$Id: modules.c,v 1.136 2003/05/12 14:11:42 wingman Exp $";
29 #endif
30
31 #include <eggdrop/eggdrop.h>
32 #include "main.h" /* NOTE: when removing this, include config.h */
33 #include "modules.h"
34 #include "core_binds.h"
35 #include "logfile.h"
36 #include "misc.h"
37 #include "cmdt.h" /* cmd_t */
38 #include "core_binds.h"
39 /*#include "cmds.h"*/ /* check_dcc_attrs, check_dcc_chanattrs */
40 #include <ctype.h>
41 #include <ltdl.h>
42
43 extern struct dcc_t *dcc;
44
45 extern struct userrec *userlist, *lastuser;
46 extern char myname[], *botname, natip[], origbotname[], botuser[],
47 admin[], userfile[], ver[], notify_new[], helpdir[], version[],
48 quit_msg[];
49 extern int dcc_total, egg_numver, userfile_perm, ignore_time, learn_users,
50 raw_log, make_userfile, default_flags, max_dcc, password_timeout,
51 use_invites, use_exempts, force_expire, do_restart,
52 protect_readonly, reserved_port_min, reserved_port_max, copy_to_tmp,
53 quiet_reject;
54 extern time_t now, online_since;
55 extern egg_timeval_t egg_timeval_now;
56 extern struct chanset_t *chanset;
57 extern sock_list *socklist;
58
59 #ifndef MAKING_MODS
60 extern struct dcc_table DCC_CHAT_PASS, DCC_LOST, DCC_DNSWAIT,
61 DCC_CHAT;
62 #endif /* MAKING_MODS */
63
64 int xtra_kill();
65 int xtra_unpack();
66 static int module_rename(char *name, char *newname);
67
68
69 /* Directory to look for modules */
70 /* FIXME: the default should be the value of $pkglibdir in configure. */
71 /* FIXME: support multiple entries. */
72 char moddir[121] = "modules/";
73
74
75 /* The null functions */
76 void null_func()
77 {
78 }
79 char *charp_func()
80 {
81 return NULL;
82 }
83 int minus_func()
84 {
85 return -1;
86 }
87 int false_func()
88 {
89 return 0;
90 }
91
92
93 /*
94 * Various hooks & things
95 */
96
97 /* The REAL hooks, when these are called, a return of 0 indicates unhandled
98 * 1 is handled
99 */
100 struct hook_entry *hook_list[REAL_HOOKS];
101
102 void (*encrypt_pass) (char *, char *) = 0;
103 char *(*encrypt_string) (char *, char *) = 0;
104 char *(*decrypt_string) (char *, char *) = 0;
105 void (*qserver) (int, char *, int) = (void (*)(int, char *, int)) null_func;
106 void (*add_mode) () = null_func;
107 int (*match_noterej) (struct userrec *, char *) = (int (*)(struct userrec *, char *)) false_func;
108 int (*storenote)(char *from, char *to, char *msg, int idx, char *who) = (int (*)(char *from, char *to, char *msg, int idx, char *who)) minus_func;
109
110 module_entry *module_list;
111 dependancy *dependancy_list = NULL;
112
113 /* The horrible global lookup table for functions
114 * BUT it makes the whole thing *much* more portable than letting each
115 * OS screw up the symbols their own special way :/
116 */
117
118 Function global_table[] =
119 {
120 (Function) module_rename,
121 (Function) module_register,
122 (Function) module_find,
123 (Function) module_depend,
124 (Function) module_undepend,
125 (Function) &egg_timeval_now,
126 owner_check
127 };
128
129 static bind_table_t *BT_load, *BT_unload;
130
131 void modules_init()
132 {
133 int i;
134 char wbuf[1024];
135
136 /* FIXME: keep this hack until the global table mess is gone */
137 egg->global = global_table;
138
139 BT_load = bind_table_add("load", 1, "s", MATCH_MASK, 0);
140 BT_unload = bind_table_add("unload", 1, "s", MATCH_MASK, 0);
141
142 module_list = malloc(sizeof(module_entry));
143 module_list->name = strdup("eggdrop");
144 module_list->major = (egg_numver) / 10000;
145 module_list->minor = ((egg_numver) / 100) % 100;
146 module_list->hand = NULL;
147 module_list->next = NULL;
148 module_list->funcs = NULL;
149
150 LTDL_SET_PRELOADED_SYMBOLS();
151 if (lt_dlinit() != 0) {
152 snprintf(wbuf, sizeof(wbuf),
153 _("error during libtdl initialization: %s\n"),
154 lt_dlerror());
155 fatal(wbuf, 0);
156 }
157
158 if (moddir[0] != '/') {
159 if (getcwd(wbuf, sizeof(wbuf)) == NULL)
160 fatal(_("Cant determine current directory."), 0);
161 sprintf(&(wbuf[strlen(wbuf)]), "/%s", moddir);
162 if (lt_dladdsearchdir(wbuf)) fatal(_("Invalid module's search path."), 0);
163 } else
164 if (lt_dladdsearchdir(moddir)) fatal(_("Invalid module's search path."), 0);
165
166 for (i = 0; i < REAL_HOOKS; i++)
167 hook_list[i] = NULL;
168 }
169
170 int module_register(char *name, Function * funcs,
171 int major, int minor)
172 {
173 module_entry *p;
174
175 for (p = module_list; p && p->name; p = p->next)
176 if (!strcasecmp(name, p->name)) {
177 p->major = major;
178 p->minor = minor;
179 p->funcs = funcs;
180 return 1;
181 }
182 return 0;
183 }
184
185 const char *module_load(char *name)
186 {
187 module_entry *p;
188 char *e;
189 Function f;
190 lt_dlhandle hand;
191
192 if (module_find(name, 0, 0) != NULL)
193 return _("Already loaded.");
194 hand = lt_dlopenext(name);
195 if (!hand) {
196 const char *err = lt_dlerror();
197 putlog(LOG_MISC, "*", "Error loading module %s: %s", name, err);
198 return err;
199 }
200
201 f = (Function) lt_dlsym(hand, "start");
202 if (f == NULL) {
203 lt_dlclose(hand);
204 return _("No start function defined.");
205 }
206 p = malloc(sizeof(module_entry));
207 if (p == NULL)
208 return _("Malloc error");
209 p->name = strdup(name);
210 p->major = 0;
211 p->minor = 0;
212 p->hand = hand;
213 p->funcs = 0;
214 p->next = module_list;
215 module_list = p;
216 e = (((char *(*)()) f) (egg));
217 if (e) {
218 module_list = module_list->next;
219 free(p->name);
220 free(p);
221 return e;
222 }
223 bind_check(BT_load, name, name);
224 putlog(LOG_MISC, "*", _("Module loaded: %-16s"), name);
225 return NULL;
226 }
227
228 char *module_unload(char *name, char *user)
229 {
230 module_entry *p = module_list, *o = NULL;
231 char *e;
232 Function *f;
233
234 while (p) {
235 if ((p->name != NULL) && (!strcmp(name, p->name))) {
236 dependancy *d;
237
238 for (d = dependancy_list; d; d = d->next)
239 if (d->needed == p)
240 return _("Needed by another module");
241
242 f = p->funcs;
243 if (f && !f[MODCALL_CLOSE])
244 return _("No close function");
245 if (f) {
246 bind_check(BT_unload, name, name);
247 e = (((char *(*)()) f[MODCALL_CLOSE]) (user));
248 if (e != NULL)
249 return e;
250 lt_dlclose(p->hand);
251 }
252 free(p->name);
253 if (o == NULL) {
254 module_list = p->next;
255 } else {
256 o->next = p->next;
257 }
258 free(p);
259 putlog(LOG_MISC, "*", _("Module unloaded: %s"), name);
260 return NULL;
261 }
262 o = p;
263 p = p->next;
264 }
265 return _("No such module");
266 }
267
268 module_entry *module_find(char *name, int major, int minor)
269 {
270 module_entry *p;
271
272 for (p = module_list; p && p->name; p = p->next)
273 if ((major == p->major || !major) && minor <= p->minor &&
274 !strcasecmp(name, p->name))
275 return p;
276 return NULL;
277 }
278
279 static int module_rename(char *name, char *newname)
280 {
281 module_entry *p;
282
283 for (p = module_list; p; p = p->next)
284 if (!strcasecmp(newname, p->name))
285 return 0;
286
287 for (p = module_list; p && p->name; p = p->next)
288 if (!strcasecmp(name, p->name)) {
289 free(p->name);
290 p->name = strdup(newname);
291 return 1;
292 }
293 return 0;
294 }
295
296 Function *module_depend(char *name1, char *name2, int major, int minor)
297 {
298 module_entry *p = module_find(name2, major, minor);
299 module_entry *o = module_find(name1, 0, 0);
300 dependancy *d;
301
302 if (!p) {
303 if (module_load(name2))
304 return 0;
305 p = module_find(name2, major, minor);
306 }
307 if (!p || !o)
308 return 0;
309 d = malloc(sizeof(dependancy));
310
311 d->needed = p;
312 d->needing = o;
313 d->next = dependancy_list;
314 d->major = major;
315 d->minor = minor;
316 dependancy_list = d;
317 return p->funcs ? p->funcs : (Function *) 1;
318 }
319
320 int module_undepend(char *name1)
321 {
322 int ok = 0;
323 module_entry *p = module_find(name1, 0, 0);
324 dependancy *d = dependancy_list, *o = NULL;
325
326 if (p == NULL)
327 return 0;
328 while (d != NULL) {
329 if (d->needing == p) {
330 if (o == NULL) {
331 dependancy_list = d->next;
332 } else {
333 o->next = d->next;
334 }
335 free(d);
336 if (o == NULL)
337 d = dependancy_list;
338 else
339 d = o->next;
340 ok++;
341 } else {
342 o = d;
343 d = d->next;
344 }
345 }
346 return ok;
347 }
348
349 /* Hooks, various tables of functions to call on ceratin events
350 */
351 void add_hook(int hook_num, Function func)
352 {
353 if (hook_num < REAL_HOOKS) {
354 struct hook_entry *p;
355
356 for (p = hook_list[hook_num]; p; p = p->next)
357 if (p->func == func)
358 return; /* Don't add it if it's already there */
359 p = malloc(sizeof(struct hook_entry));
360
361 p->next = hook_list[hook_num];
362 hook_list[hook_num] = p;
363 p->func = func;
364 } else
365 switch (hook_num) {
366 case HOOK_ENCRYPT_PASS:
367 encrypt_pass = (void (*)(char *, char *)) func;
368 break;
369 case HOOK_ENCRYPT_STRING:
370 encrypt_string = (char *(*)(char *, char *)) func;
371 break;
372 case HOOK_DECRYPT_STRING:
373 decrypt_string = (char *(*)(char *, char *)) func;
374 break;
375 case HOOK_QSERV:
376 if (qserver == (void (*)(int, char *, int)) null_func)
377 qserver = (void (*)(int, char *, int)) func;
378 break;
379 case HOOK_ADD_MODE:
380 if (add_mode == (void (*)()) null_func)
381 add_mode = (void (*)()) func;
382 break;
383 case HOOK_MATCH_NOTEREJ:
384 if (match_noterej == (int (*)(struct userrec *, char *))false_func)
385 match_noterej = func;
386 break;
387 case HOOK_STORENOTE:
388 if (func == NULL) storenote = (int (*)(char *from, char *to, char *msg, int idx, char *who)) minus_func;
389 else storenote = func;
390 break;
391 }
392 }
393
394 void del_hook(int hook_num, Function func)
395 {
396 if (hook_num < REAL_HOOKS) {
397 struct hook_entry *p = hook_list[hook_num], *o = NULL;
398
399 while (p) {
400 if (p->func == func) {
401 if (o == NULL)
402 hook_list[hook_num] = p->next;
403 else
404 o->next = p->next;
405 free(p);
406 break;
407 }
408 o = p;
409 p = p->next;
410 }
411 } else
412 switch (hook_num) {
413 case HOOK_ENCRYPT_PASS:
414 if (encrypt_pass == (void (*)(char *, char *)) func)
415 encrypt_pass = (void (*)(char *, char *)) null_func;
416 break;
417 case HOOK_ENCRYPT_STRING:
418 if (encrypt_string == (char *(*)(char *, char *)) func)
419 encrypt_string = (char *(*)(char *, char *)) null_func;
420 break;
421 case HOOK_DECRYPT_STRING:
422 if (decrypt_string == (char *(*)(char *, char *)) func)
423 decrypt_string = (char *(*)(char *, char *)) null_func;
424 break;
425 case HOOK_QSERV:
426 if (qserver == (void (*)(int, char *, int)) func)
427 qserver = null_func;
428 break;
429 case HOOK_ADD_MODE:
430 if (add_mode == (void (*)()) func)
431 add_mode = null_func;
432 break;
433 case HOOK_MATCH_NOTEREJ:
434 if (match_noterej == (int (*)(struct userrec *, char *))func)
435 match_noterej = false_func;
436 break;
437 case HOOK_STORENOTE:
438 if (storenote == func) storenote = (int (*)(char *from, char *to, char *msg, int idx, char *who)) minus_func;
439 break;
440 }
441 }
442
443 int call_hook_cccc(int hooknum, char *a, char *b, char *c, char *d)
444 {
445 struct hook_entry *p, *pn;
446 int f = 0;
447
448 if (hooknum >= REAL_HOOKS)
449 return 0;
450 p = hook_list[hooknum];
451 for (p = hook_list[hooknum]; p && !f; p = pn) {
452 pn = p->next;
453 f = p->func(a, b, c, d);
454 }
455 return f;
456 }
457
458 void do_module_report(int idx, int details, char *which)
459 {
460 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23