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

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

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


Revision 1.32 - (show annotations) (download) (as text)
Sat Jul 1 06:28:03 2000 UTC (19 years ago) by guppy
Branch: MAIN
CVS Tags: eggdrop10404, HEAD
Changes since 1.31: +4 -5 lines
File MIME type: text/x-chdr
added patches, 1.4.4?

1 /*
2 * modules.c -- handles:
3 * support for modules in eggdrop
4 *
5 * by Darrin Smith (beldin@light.iinet.net.au)
6 *
7 * $Id: modules.c,v 1.31 2000/06/04 08:26:41 guppy Exp $
8 */
9 /*
10 * Copyright (C) 1997 Robey Pointer
11 * Copyright (C) 1999, 2000 Eggheads
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 #include "main.h"
29 #include "modules.h"
30 #include "tandem.h"
31 #include <ctype.h>
32 #ifndef STATIC
33 #ifdef HPUX_HACKS
34 #include <dl.h>
35 #else
36 #ifdef OSF1_HACKS
37 #include <loader.h>
38 #else
39 #ifdef DLOPEN_1
40 char *dlerror();
41 void *dlopen(const char *, int);
42 int dlclose(void *);
43 void *dlsym(void *, char *);
44
45 #define DLFLAGS 1
46 #else
47 #include <dlfcn.h>
48 #ifndef RTLD_GLOBAL
49 #define RTLD_GLOBAL 0
50 #endif
51 #ifndef RTLD_NOW
52 #define RTLD_NOW 1
53 #endif
54 #ifdef RTLD_LAZY
55 #define DLFLAGS RTLD_LAZY|RTLD_GLOBAL
56 #else
57 #define DLFLAGS RTLD_NOW|RTLD_GLOBAL
58 #endif
59 #endif /* DLOPEN_1 */
60 #endif /* OSF1_HACKS */
61 #endif /* HPUX_HACKS */
62
63 #endif /* STATIC */
64 extern struct dcc_t *dcc;
65
66 #include "users.h"
67
68 /* from other areas */
69 extern Tcl_Interp *interp;
70 extern struct userrec *userlist, *lastuser;
71 extern char tempdir[], botnetnick[], botname[], natip[], hostname[];
72 extern char origbotname[], botuser[], admin[], userfile[], ver[], notify_new[];
73 extern char helpdir[], version[];
74 extern int reserved_port, noshare, dcc_total, egg_numver, use_silence;
75 extern int use_console_r, ignore_time, debug_output, gban_total, make_userfile;
76 extern int gexempt_total, ginvite_total;
77 extern int default_flags, require_p, max_dcc, share_greet, password_timeout;
78 extern int min_dcc_port, max_dcc_port; /* dw */
79 extern int use_invites, use_exempts; /* Jason/drummer */
80 extern int force_expire; /* Rufus */
81 extern int do_restart;
82 extern time_t now, online_since;
83 extern struct chanset_t *chanset;
84 extern int protect_readonly;
85 int cmd_die(), xtra_kill(), xtra_unpack();
86 static int module_rename(char *name, char *newname);
87
88 #ifndef STATIC
89 /* directory to look for modules */
90 char moddir[121] = "modules/";
91
92 #else
93 struct static_list {
94 struct static_list *next;
95 char *name;
96 char *(*func) ();
97 } *static_modules = NULL;
98
99 void check_static(char *name, char *(*func) ())
100 {
101 struct static_list *p = nmalloc(sizeof(struct static_list));
102
103 p->name = nmalloc(strlen(name) + 1);
104 strcpy(p->name, name);
105 p->func = func;
106 p->next = static_modules;
107 static_modules = p;
108 }
109
110 #endif
111
112 /* the null functions */
113 void null_func()
114 {
115 }
116 char *charp_func()
117 {
118 return NULL;
119 }
120 int minus_func()
121 {
122 return -1;
123 }
124 int false_func()
125 {
126 return 0;
127 }
128
129 /* various hooks & things */
130 /* the REAL hooks, when these are called, a return of 0 indicates unhandled
131 * 1 is handled */
132 struct hook_entry *hook_list[REAL_HOOKS];
133
134 static void null_share(int idx, char *x)
135 {
136 if ((x[0] == 'u') && (x[1] == 'n')) {
137 putlog(LOG_BOTS, "*", "User file rejected by %s: %s",
138 dcc[idx].nick, x + 3);
139 dcc[idx].status &= ~STAT_OFFERED;
140 if (!(dcc[idx].status & STAT_GETTING)) {
141 dcc[idx].status &= ~STAT_SHARE;
142 }
143 } else if ((x[0] != 'v') && (x[0] != 'e'))
144 dprintf(idx, "s un Not sharing userfile.\n");
145 }
146
147 void (*encrypt_pass) (char *, char *) = 0;
148 void (*shareout) () = null_func;
149 void (*sharein) (int, char *) = null_share;
150 void (*qserver) (int, char *, int) = (void (*)(int, char *, int)) null_func;
151 void (*add_mode) () = null_func;
152 int (*match_noterej) (struct userrec *, char *) = (int (*)(struct userrec *, char *)) false_func;
153 int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
154 int (*rfc_ncasecmp) (const char *, const char *, int) = _rfc_ncasecmp;
155 int (*rfc_toupper) (int) = _rfc_toupper;
156 int (*rfc_tolower) (int) = _rfc_tolower;
157
158 module_entry *module_list;
159 dependancy *dependancy_list = NULL;
160
161 /* the horrible global lookup table for functions
162 * BUT it makes the whole thing *much* more portable than letting each
163 * OS screw up the symbols their own special way :/
164 */
165
166 Function global_table[] =
167 {
168 /* 0 - 3 */
169 (Function) mod_malloc,
170 (Function) mod_free,
171 #ifdef DEBUG_CONTEXT
172 (Function) eggContext,
173 #else
174 (Function) 0,
175 #endif
176 (Function) module_rename,
177 /* 4 - 7 */
178 (Function) module_register,
179 (Function) module_find,
180 (Function) module_depend,
181 (Function) module_undepend,
182 /* 8 - 11 */
183 (Function) add_bind_table,
184 (Function) del_bind_table,
185 (Function) find_bind_table,
186 (Function) check_tcl_bind,
187 /* 12 - 15 */
188 (Function) add_builtins,
189 (Function) rem_builtins,
190 (Function) add_tcl_commands,
191 (Function) rem_tcl_commands,
192 /* 16 - 19 */
193 (Function) add_tcl_ints,
194 (Function) rem_tcl_ints,
195 (Function) add_tcl_strings,
196 (Function) rem_tcl_strings,
197 /* 20 - 23 */
198 (Function) base64_to_int,
199 (Function) int_to_base64,
200 (Function) int_to_base10,
201 (Function) simple_sprintf,
202 /* 24 - 27 */
203 (Function) botnet_send_zapf,
204 (Function) botnet_send_zapf_broad,
205 (Function) botnet_send_unlinked,
206 (Function) botnet_send_bye,
207 /* 28 - 31 */
208 (Function) botnet_send_chat,
209 (Function) botnet_send_filereject,
210 (Function) botnet_send_filesend,
211 (Function) botnet_send_filereq,
212 /* 32 - 35 */
213 (Function) botnet_send_join_idx,
214 (Function) botnet_send_part_idx,
215 (Function) updatebot,
216 (Function) nextbot,
217 /* 36 - 39 */
218 (Function) zapfbot,
219 (Function) n_free,
220 (Function) u_pass_match,
221 (Function) _user_malloc,
222 /* 40 - 43 */
223 (Function) get_user,
224 (Function) set_user,
225 (Function) add_entry_type,
226 (Function) del_entry_type,
227 /* 44 - 47 */
228 (Function) get_user_flagrec,
229 (Function) set_user_flagrec,
230 (Function) get_user_by_host,
231 (Function) get_user_by_handle,
232 /* 48 - 51 */
233 (Function) find_entry_type,
234 (Function) find_user_entry,
235 (Function) adduser,
236 (Function) deluser,
237 /* 52 - 55 */
238 (Function) addhost_by_handle,
239 (Function) delhost_by_handle,
240 (Function) readuserfile,
241 (Function) write_userfile,
242 /* 56 - 59 */
243 (Function) geticon,
244 (Function) clear_chanlist,
245 (Function) reaffirm_owners,
246 (Function) change_handle,
247 /* 60 - 63 */
248 (Function) write_user,
249 (Function) clear_userlist,
250 (Function) count_users,
251 (Function) sanity_check,
252 /* 64 - 67 */
253 (Function) break_down_flags,
254 (Function) build_flags,
255 (Function) flagrec_eq,
256 (Function) flagrec_ok,
257 /* 68 - 71 */
258 (Function) & shareout,
259 (Function) dprintf,
260 (Function) chatout,
261 (Function) chanout_but,
262 /* 72 - 75 */
263 (Function) check_validity,
264 (Function) list_delete,
265 (Function) list_append,
266 (Function) list_contains,
267 /* 76 - 79 */
268 (Function) answer,
269 (Function) getmyip,
270 (Function) neterror,
271 (Function) tputs,
272 /* 80 - 83 */
273 (Function) new_dcc,
274 (Function) lostdcc,
275 (Function) getsock,
276 (Function) killsock,
277 /* 84 - 87 */
278 (Function) open_listen,
279 (Function) open_telnet_dcc,
280 (Function) _get_data_ptr,
281 (Function) open_telnet,
282 /* 88 - 91 */
283 #ifdef HAVE_BZERO
284 (Function) null_func,
285 #else
286 (Function) bzero,
287 #endif
288 (Function) my_memcpy,
289 (Function) my_atoul,
290 (Function) my_strcpy,
291 /* 92 - 95 */
292 (Function) & dcc, /* struct dcc_t * */
293 (Function) & chanset, /* struct chanset_t * */
294 (Function) & userlist, /* struct userrec * */
295 (Function) & lastuser, /* struct userrec * */
296 /* 96 - 99 */
297 (Function) & global_bans, /* struct banrec * */
298 (Function) & global_ign, /* struct igrec * */
299 (Function) & password_timeout, /* int */
300 (Function) & share_greet, /* int */
301 /* 100 - 103 */
302 (Function) & max_dcc, /* int */
303 (Function) & require_p, /* int */
304 (Function) & use_silence, /* int */
305 (Function) & use_console_r, /* int */
306 /* 104 - 107 */
307 (Function) & ignore_time, /* int */
308 (Function) & reserved_port, /* int */
309 (Function) & debug_output, /* int */
310 (Function) & noshare, /* int */
311 /* 108 - 111 */
312 (Function) & gban_total, /* int */
313 (Function) & make_userfile, /* int */
314 (Function) & default_flags, /* int */
315 (Function) & dcc_total, /* int */
316 /* 112 - 115 */
317 (Function) tempdir, /* char * */
318 (Function) natip, /* char * */
319 (Function) hostname, /* char * */
320 (Function) origbotname, /* char * */
321 /* 116 - 119 */
322 (Function) botuser, /* char * */
323 (Function) admin, /* char * */
324 (Function) userfile, /* char * */
325 (Function) ver, /* char * */
326 /* 120 - 123 */
327 (Function) notify_new, /* char * */
328 (Function) helpdir, /* char * */
329 (Function) version, /* char * */
330 (Function) botnetnick, /* char * */
331 /* 124 - 127 */
332 (Function) & DCC_CHAT_PASS, /* struct dcc_table * */
333 (Function) & DCC_BOT, /* struct dcc_table * */
334 (Function) & DCC_LOST, /* struct dcc_table * */
335 (Function) & DCC_CHAT, /* struct dcc_table * */
336 /* 128 - 131 */
337 (Function) & interp, /* Tcl_Interp * */
338 (Function) & now, /* time_t */
339 (Function) findanyidx,
340 (Function) findchan,
341 /* 132 - 135 */
342 (Function) cmd_die,
343 (Function) days,
344 (Function) daysago,
345 (Function) daysdur,
346 /* 136 - 139 */
347 (Function) ismember,
348 (Function) newsplit,
349 (Function) splitnick,
350 (Function) splitc,
351 /* 140 - 143 */
352 (Function) addignore,
353 (Function) match_ignore,
354 (Function) delignore,
355 (Function) fatal,
356 /* 144 - 147 */
357 (Function) xtra_kill,
358 (Function) xtra_unpack,
359 (Function) movefile,
360 (Function) copyfile,
361 /* 148 - 151 */
362 (Function) do_tcl,
363 (Function) readtclprog,
364 (Function) get_language,
365 (Function) def_get,
366 /* 152 - 155 */
367 (Function) makepass,
368 (Function) _wild_match,
369 (Function) maskhost,
370 (Function) show_motd,
371 /* 156 - 159 */
372 (Function) tellhelp,
373 (Function) showhelp,
374 (Function) add_help_reference,
375 (Function) rem_help_reference,
376 /* 160 - 163 */
377 (Function) touch_laston,
378 (Function) & add_mode,
379 (Function) rmspace,
380 (Function) in_chain,
381 /* 164 - 167 */
382 (Function) add_note,
383 (Function) removedcc,
384 (Function) detect_dcc_flood,
385 (Function) flush_lines,
386 /* 168 - 171 */
387 (Function) expected_memory,
388 (Function) tell_mem_status,
389 (Function) & do_restart,
390 (Function) check_tcl_filt,
391 /* 172 - 175 */
392 (Function) add_hook,
393 (Function) del_hook,
394 (Function) & H_dcc,
395 (Function) & H_filt,
396 /* 176 - 179 */
397 (Function) & H_chon,
398 (Function) & H_chof,
399 (Function) & H_load,
400 (Function) & H_unld,
401 /* 180 - 183 */
402 (Function) & H_chat,
403 (Function) & H_act,
404 (Function) & H_bcst,
405 (Function) & H_bot,
406 /* 184 - 187 */
407 (Function) & H_link,
408 (Function) & H_disc,
409 (Function) & H_away,
410 (Function) & H_nkch,
411 /* 188 - 191 */
412 (Function) & USERENTRY_BOTADDR,
413 (Function) & USERENTRY_BOTFL,
414 (Function) & USERENTRY_HOSTS,
415 (Function) & USERENTRY_PASS,
416 /* 192 - 195 */
417 (Function) & USERENTRY_XTRA,
418 (Function) user_del_chan,
419 (Function) & USERENTRY_INFO,
420 (Function) & USERENTRY_COMMENT,
421 /* 196 - 199 */
422 (Function) & USERENTRY_LASTON,
423 (Function) putlog,
424 (Function) botnet_send_chan,
425 (Function) list_type_kill,
426 /* 200 - 203 */
427 (Function) logmodes,
428 (Function) masktype,
429 (Function) stripmodes,
430 (Function) stripmasktype,
431 /* 204 - 207 */
432 (Function) sub_lang,
433 (Function) & online_since,
434 (Function) cmd_loadlanguage,
435 (Function) check_dcc_attrs,
436 /* 208 - 211 */
437 (Function) check_dcc_chanattrs,
438 (Function) add_tcl_coups,
439 (Function) rem_tcl_coups,
440 (Function) botname,
441 /* 212 - 215 */
442 (Function) remove_gunk,
443 (Function) check_tcl_chjn,
444 (Function) sanitycheck_dcc,
445 (Function) isowner, /* Daemus */
446 /* 216 - 219 */
447 (Function) & min_dcc_port, /* dw */
448 (Function) & max_dcc_port,
449 (Function) & rfc_casecmp, /* Function * */
450 (Function) & rfc_ncasecmp, /* Function * */
451 /* 220 - 223 */
452 (Function) & global_exempts, /* struct exemptrec * */
453 (Function) & global_invites, /* struct inviterec * */
454 (Function) & gexempt_total, /* int */
455 (Function) & ginvite_total, /* int */
456 /* 224 - 227 */
457 (Function) & H_event,
458 (Function) & use_exempts, /* int - drummer/Jason */
459 (Function) & use_invites, /* int - drummer/Jason */
460 (Function) & force_expire, /* int - Rufus */
461 /* 228 - 231 */
462 (Function) add_lang_section,
463 (Function) _user_realloc,
464 (Function) mod_realloc,
465 (Function) xtra_set,
466 /* 232 - 235 */
467 #ifdef DEBUG_CONTEXT
468 (Function) eggContextNote,
469 #else
470 (Function) 0,
471 #endif
472 #ifdef DEBUG_ASSERT
473 (Function) eggAssert,
474 #else
475 (Function) 0,
476 #endif
477 (Function) & protect_readonly, /* int */
478 (Function) del_lang_section,
479 /* 236 - 239 */
480 (Function) check_tcl_event,
481 };
482
483 void init_modules(void)
484 {
485 int i;
486
487 Context;
488 module_list = nmalloc(sizeof(module_entry));
489 module_list->name = nmalloc(8);
490 strcpy(module_list->name, "eggdrop");
491 module_list->major = (egg_numver) / 10000;
492 module_list->minor = ((egg_numver) / 100) % 100;
493 #ifndef STATIC
494 module_list->hand = NULL;
495 #endif
496 module_list->next = NULL;
497 module_list->funcs = NULL;
498 for (i = 0; i < REAL_HOOKS; i++)
499 hook_list[i] = NULL;
500 }
501
502 int expmem_modules(int y)
503 {
504 int c = 0;
505 int i;
506 module_entry *p = module_list;
507 dependancy *d = dependancy_list;
508
509 #ifdef STATIC
510 struct static_list *s;
511
512 #endif
513 Function *f;
514
515 Context;
516 #ifdef STATIC
517 for (s = static_modules; s; s = s->next)
518 c += sizeof(struct static_list) + strlen(s->name) + 1;
519
520 #endif
521 for (i = 0; i < REAL_HOOKS; i++) {
522 struct hook_entry *q = hook_list[i];
523
524 while (q) {
525 c += sizeof(struct hook_entry);
526
527 q = q->next;
528 }
529 }
530 while (d) {
531 c += sizeof(dependancy);
532 d = d->next;
533 }
534 while (p) {
535 c += sizeof(module_entry);
536 c += strlen(p->name) + 1;
537 f = p->funcs;
538 if (f && f[MODCALL_EXPMEM] && !y)
539 c += (int) (f[MODCALL_EXPMEM] ());
540 p = p->next;
541 }
542 return c;
543 }
544
545 int module_register(char *name, Function * funcs,
546 int major, int minor)
547 {
548 module_entry *p = module_list;
549
550 Context;
551 while (p) {
552 if (p->name && !strcasecmp(name, p->name)) {
553 p->major = major;
554 p->minor = minor;
555 p->funcs = funcs;
556 return 1;
557 }
558 p = p->next;
559 }
560 return 0;
561 }
562
563 const char *module_load(char *name)
564 {
565 module_entry *p;
566 char *e;
567 Function f;
568
569 #ifndef STATIC
570 char workbuf[1024];
571
572 #ifdef HPUX_HACKS
573 shl_t hand;
574
575 #else
576 #ifdef OSF1_HACKS
577 ldr_module_t hand;
578
579 #else
580 void *hand;
581
582 #endif
583 #endif
584 #else
585 struct static_list *sl;
586
587 #endif
588
589 Context;
590 if (module_find(name, 0, 0) != NULL)
591 return MOD_ALREADYLOAD;
592 #ifndef STATIC
593 Context;
594 if (moddir[0] != '/') {
595 if (getcwd(workbuf, 1024) == NULL)
596 return MOD_BADCWD;
597 sprintf(&(workbuf[strlen(workbuf)]), "/%s%s.so", moddir, name);
598 } else
599 sprintf(workbuf, "%s%s.so", moddir, name);
600 #ifdef HPUX_HACKS
601 hand = shl_load(workbuf, BIND_IMMEDIATE, 0L);
602 Context;
603 if (!hand)
604 return "Can't load module.";
605 #else
606 #ifdef OSF1_HACKS
607 #ifndef HAVE_PRE7_5_TCL
608 hand = (Tcl_PackageInitProc *) load(workbuf, LDR_NOFLAGS);
609 if (hand == LDR_NULL_MODULE)
610 return "Can't load module.";
611 #endif
612 #else
613 Context;
614 hand = dlopen(workbuf, DLFLAGS);
615 if (!hand)
616 return dlerror();
617 #endif
618 #endif
619
620 sprintf(workbuf, "%s_start", name);
621 #ifdef HPUX_HACKS
622 Context;
623 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
624 f = NULL;
625 #else
626 #ifdef OSF1_HACKS
627 f = (Function) ldr_lookup_package(hand, workbuf);
628 #else
629 f = (Function) dlsym(hand, workbuf);
630 #endif
631 #endif
632 if (f == NULL) { /* some OS's need the _ */
633 sprintf(workbuf, "_%s_start", name);
634 #ifdef HPUX_HACKS
635 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
636 f = NULL;
637 #else
638 #ifdef OSF1_HACKS
639 f = (Function) ldr_lookup_package(hand, workbuf);
640 #else
641 f = (Function) dlsym(hand, workbuf);
642 #endif
643 #endif
644 if (f == NULL) {
645 #ifdef HPUX_HACKS
646 shl_unload(hand);
647 #else
648 #ifdef OSF1_HACKS
649 #else
650 dlclose(hand);
651 #endif
652 #endif
653 return MOD_NOSTARTDEF;
654 }
655 }
656 #else
657 for (sl = static_modules; sl && strcasecmp(sl->name, name); sl = sl->next);
658 Context;
659 if (!sl)
660 return "Unkown module.";
661 f = (Function) sl->func;
662 #endif
663 p = nmalloc(sizeof(module_entry));
664 if (p == NULL)
665 return "Malloc error";
666 p->name = nmalloc(strlen(name) + 1);
667 strcpy(p->name, name);
668 Context;
669 p->major = 0;
670 p->minor = 0;
671 #ifndef STATIC
672 p->hand = hand;
673 #endif
674 p->funcs = 0;
675 p->next = module_list;
676 module_list = p;
677 e = (((char *(*)()) f) (global_table));
678 Context;
679 if (e) {
680 module_list = module_list->next;
681 nfree(p->name);
682 nfree(p);
683 return e;
684 }
685 check_tcl_load(name);
686 if (exist_lang_section(name))
687 putlog(LOG_MISC, "*", MOD_LOADED_WITH_LANG, name);
688 else
689 putlog(LOG_MISC, "*", MOD_LOADED, name);
690 Context;
691 return NULL;
692 }
693
694 char *module_unload(char *name, char *user)
695 {
696 module_entry *p = module_list, *o = NULL;
697 char *e;
698 Function *f;
699
700 Context;
701 while (p) {
702 if ((p->name != NULL) && (!strcmp(name, p->name))) {
703 dependancy *d = dependancy_list;
704
705 while (d != NULL) {
706 if (d->needed == p) {
707 return MOD_NEEDED;
708 }
709 d = d->next;
710 }
711 f = p->funcs;
712 if (f && !f[MODCALL_CLOSE])
713 return MOD_NOCLOSEDEF;
714 if (f) {
715 check_tcl_unld(name);
716 e = (((char *(*)()) f[MODCALL_CLOSE]) (user));
717 if (e != NULL)
718 return e;
719 #ifndef STATIC
720 #ifdef HPUX_HACKS
721 shl_unload(p->hand);
722 #else
723 #ifdef OSF1_HACKS
724 #else
725 dlclose(p->hand);
726 #endif
727 #endif
728 #endif /* STATIC */
729 }
730 nfree(p->name);
731 if (o == NULL) {
732 module_list = p->next;
733 } else {
734 o->next = p->next;
735 }
736 nfree(p);
737 putlog(LOG_MISC, "*", "%s %s", MOD_UNLOADED, name);
738 return NULL;
739 }
740 o = p;
741 p = p->next;
742 }
743 return MOD_NOSUCH;
744 }
745
746 module_entry *module_find(char *name, int major, int minor)
747 {
748 module_entry *p = module_list;
749
750 while (p) {
751 if (p->name && !strcasecmp(name, p->name) &&
752 ((major == p->major) || (major == 0)) &&
753 (minor <= p->minor))
754 return p;
755 p = p->next;
756 }
757 return NULL;
758 }
759
760 static int module_rename(char *name, char *newname)
761 {
762 module_entry *p = module_list;
763
764 while (p) {
765 if (!strcasecmp(newname, p->name))
766 return 0;
767 p = p->next;
768 }
769 p = module_list;
770 while (p) {
771 if (p->name && !strcasecmp(name, p->name)) {
772 nfree(p->name);
773 p->name = nmalloc(strlen(newname) + 1);
774 strcpy(p->name, newname);
775 return 1;
776 }
777 p = p->next;
778 }
779 return 0;
780 }
781
782 Function *module_depend(char *name1, char *name2, int major, int minor)
783 {
784 module_entry *p = module_find(name2, major, minor);
785 module_entry *o = module_find(name1, 0, 0);
786 dependancy *d;
787
788 Context;
789 if (!p) {
790 if (module_load(name2))
791 return 0;
792 p = module_find(name2, major, minor);
793 }
794 if (!p || !o)
795 return 0;
796 d = nmalloc(sizeof(dependancy));
797
798 d->needed = p;
799 d->needing = o;
800 d->next = dependancy_list;
801 d->major = major;
802 d->minor = minor;
803 dependancy_list = d;
804 Context;
805 return p->funcs ? p->funcs : (Function *) 1;
806 }
807
808 int module_undepend(char *name1)
809 {
810 int ok = 0;
811 module_entry *p = module_find(name1, 0, 0);
812 dependancy *d = dependancy_list, *o = NULL;
813
814 Context;
815 if (p == NULL)
816 return 0;
817 while (d != NULL) {
818 if (d->needing == p) {
819 if (o == NULL) {
820 dependancy_list = d->next;
821 } else {
822 o->next = d->next;
823 }
824 nfree(d);
825 if (o == NULL)
826 d = dependancy_list;
827 else
828 d = o->next;
829 ok++;
830 } else {
831 o = d;
832 d = d->next;
833 }
834 }
835 Context;
836 return ok;
837 }
838
839 void *mod_malloc(int size, char *modname, char *filename, int line)
840 {
841 char x[100];
842
843 sprintf(x, "%s:%s", modname, filename);
844 x[19] = 0;
845 return n_malloc(size, x, line);
846 }
847
848 void *mod_realloc(void *ptr, int size, char *modname, char *filename, int line)
849 {
850 char x[100];
851
852 sprintf(x, "%s:%s", modname, filename);
853 x[19] = 0;
854 return n_realloc(ptr, size, x, line);
855 }
856
857 void mod_free(void *ptr, char *modname, char *filename, int line)
858 {
859 char x[100];
860
861 sprintf(x, "%s:%s", modname, filename);
862 x[19] = 0;
863 n_free(ptr, x, line);
864 }
865
866 /* hooks, various tables of functions to call on ceratin events */
867 void add_hook(int hook_num, Function func)
868 {
869 Context;
870 if (hook_num < REAL_HOOKS) {
871 struct hook_entry *p;
872
873 for (p = hook_list[hook_num]; p; p = p->next)
874 if (p->func == func)
875 return; /* dont add it if it's already there */
876 p = nmalloc(sizeof(struct hook_entry));
877
878 p->next = hook_list[hook_num];
879 hook_list[hook_num] = p;
880 p->func = func;
881 } else
882 switch (hook_num) {
883 case HOOK_ENCRYPT_PASS:
884 encrypt_pass = (void (*)(char *, char *)) func;
885 break;
886 case HOOK_SHAREOUT:
887 shareout = (void (*)()) func;
888 break;
889 case HOOK_SHAREIN:
890 sharein = (void (*)(int, char *)) func;
891 break;
892 case HOOK_QSERV:
893 if (qserver == (void (*)(int, char *, int)) null_func)
894 qserver = (void (*)(int, char *, int)) func;
895 break;
896 case HOOK_ADD_MODE:
897 if (add_mode == (void (*)()) null_func)
898 add_mode = (void (*)()) func;
899 break;
900 /* special hook <drummer> */
901 case HOOK_RFC_CASECMP:
902 if (func == NULL) {
903 rfc_casecmp = strcasecmp;
904 rfc_ncasecmp = (int (*)(const char *, const char *, int)) strncasecmp;
905 rfc_tolower = tolower;
906 rfc_toupper = toupper;
907 } else {
908 rfc_casecmp = _rfc_casecmp;
909 rfc_ncasecmp = _rfc_ncasecmp;
910 rfc_tolower = _rfc_tolower;
911 rfc_toupper = _rfc_toupper;
912 }
913 break;
914 case HOOK_MATCH_NOTEREJ:
915 if (match_noterej == (int (*)(struct userrec *, char *))false_func)
916 match_noterej = func;
917 break;
918 }
919 }
920
921 void del_hook(int hook_num, Function func)
922 {
923 Context;
924 if (hook_num < REAL_HOOKS) {
925 struct hook_entry *p = hook_list[hook_num], *o = NULL;
926
927 while (p) {
928 if (p->func == func) {
929 if (o == NULL)
930 hook_list[hook_num] = p->next;
931 else
932 o->next = p->next;
933 nfree(p);
934 break;
935 }
936 o = p;
937 p = p->next;
938 }
939 } else
940 switch (hook_num) {
941 case HOOK_ENCRYPT_PASS:
942 if (encrypt_pass == (void (*)(char *, char *)) func)
943 encrypt_pass = (void (*)(char *, char *)) null_func;
944 break;
945 case HOOK_SHAREOUT:
946 if (shareout == (void (*)()) func)
947 shareout = null_func;
948 break;
949 case HOOK_SHAREIN:
950 if (sharein == (void (*)(int, char *)) func)
951 sharein = null_share;
952 break;
953 case HOOK_QSERV:
954 if (qserver == (void (*)(int, char *, int)) func)
955 qserver = null_func;
956 break;
957 case HOOK_ADD_MODE:
958 if (add_mode == (void (*)()) func)
959 add_mode = null_func;
960 break;
961 case HOOK_MATCH_NOTEREJ:
962 if (match_noterej == (int (*)(struct userrec *, char *))false_func)
963 match_noterej = false_func;
964 break;
965 }
966 }
967
968 int call_hook_cccc(int hooknum, char *a, char *b, char *c, char *d)
969 {
970 struct hook_entry *p, *pn;
971 int f = 0;
972
973 if (hooknum >= REAL_HOOKS)
974 return 0;
975 Context;
976 for (p = hook_list[hooknum]; p && !f; p = pn) {
977 pn = p->next;
978 f = p->func(a, b, c, d);
979 }
980 return f;
981 }
982
983 void do_module_report(int idx, int details, char *which)
984 {
985 module_entry *p = module_list;
986
987 if (p && !which && details)
988 dprintf(idx, "MODULES LOADED:\n");
989 while (p) {
990 if (!which || !strcasecmp(which, p->name)) {
991 dependancy *d = dependancy_list;
992
993 if (details)
994 dprintf(idx, "Module: %s, v %d.%d\n", p->name ? p->name : "CORE",
995 p->major, p->minor);
996 if (details > 1) {
997 while (d != NULL) {
998 if (d->needing == p)
999 dprintf(idx, " requires: %s, v %d.%d\n", d->needed->name,
1000 d->major, d->minor);
1001 d = d->next;
1002 }
1003 }
1004 if (p->funcs) {
1005 Function f = p->funcs[MODCALL_REPORT];
1006
1007 if (f != NULL)
1008 f(idx, details);
1009 }
1010 if (which)
1011 return;
1012 }
1013 p = p->next;
1014 }
1015 if (which)
1016 dprintf(idx, "No such module.\n");
1017 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23