/[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.28 - (show annotations) (download) (as text)
Sat Jan 8 21:23:14 2000 UTC (20 years, 3 months ago) by per
Branch: MAIN
CVS Tags: eggdrop104030RC2, eggdrop10403RC1, eggdrop10402RC1, eggdrop10403, eggdrop10402
Changes since 1.27: +2 -2 lines
File MIME type: text/x-chdr
copyright

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.27 2000/01/08 15:48:20 per 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 };
481
482 void init_modules(void)
483 {
484 int i;
485
486 Context;
487 module_list = nmalloc(sizeof(module_entry));
488 module_list->name = nmalloc(8);
489 strcpy(module_list->name, "eggdrop");
490 module_list->major = (egg_numver) / 10000;
491 module_list->minor = ((egg_numver) / 100) % 100;
492 #ifndef STATIC
493 module_list->hand = NULL;
494 #endif
495 module_list->next = NULL;
496 module_list->funcs = NULL;
497 for (i = 0; i < REAL_HOOKS; i++)
498 hook_list[i] = NULL;
499 }
500
501 int expmem_modules(int y)
502 {
503 int c = 0;
504 int i;
505 module_entry *p = module_list;
506 dependancy *d = dependancy_list;
507
508 #ifdef STATIC
509 struct static_list *s;
510
511 #endif
512 Function *f;
513
514 Context;
515 #ifdef STATIC
516 for (s = static_modules; s; s = s->next)
517 c += sizeof(struct static_list) + strlen(s->name) + 1;
518
519 #endif
520 for (i = 0; i < REAL_HOOKS; i++) {
521 struct hook_entry *q = hook_list[i];
522
523 while (q) {
524 c += sizeof(struct hook_entry);
525
526 q = q->next;
527 }
528 }
529 while (d) {
530 c += sizeof(dependancy);
531 d = d->next;
532 }
533 while (p) {
534 c += sizeof(module_entry);
535 c += strlen(p->name) + 1;
536 f = p->funcs;
537 if (f && f[MODCALL_EXPMEM] && !y)
538 c += (int) (f[MODCALL_EXPMEM] ());
539 p = p->next;
540 }
541 return c;
542 }
543
544 int module_register(char *name, Function * funcs,
545 int major, int minor)
546 {
547 module_entry *p = module_list;
548
549 Context;
550 while (p) {
551 if (p->name && !strcasecmp(name, p->name)) {
552 p->major = major;
553 p->minor = minor;
554 p->funcs = funcs;
555 return 1;
556 }
557 p = p->next;
558 }
559 return 0;
560 }
561
562 const char *module_load(char *name)
563 {
564 module_entry *p;
565 char *e;
566 Function f;
567
568 #ifndef STATIC
569 char workbuf[1024];
570
571 #ifdef HPUX_HACKS
572 shl_t hand;
573
574 #else
575 #ifdef OSF1_HACKS
576 ldr_module_t hand;
577
578 #else
579 void *hand;
580
581 #endif
582 #endif
583 #else
584 struct static_list *sl;
585
586 #endif
587
588 Context;
589 if (module_find(name, 0, 0) != NULL)
590 return MOD_ALREADYLOAD;
591 #ifndef STATIC
592 Context;
593 if (moddir[0] != '/') {
594 if (getcwd(workbuf, 1024) == NULL)
595 return MOD_BADCWD;
596 sprintf(&(workbuf[strlen(workbuf)]), "/%s%s.so", moddir, name);
597 } else
598 sprintf(workbuf, "%s%s.so", moddir, name);
599 #ifdef HPUX_HACKS
600 hand = shl_load(workbuf, BIND_IMMEDIATE, 0L);
601 Context;
602 if (!hand)
603 return "Can't load module.";
604 #else
605 #ifdef OSF1_HACKS
606 #ifndef HAVE_PRE7_5_TCL
607 hand = (Tcl_PackageInitProc *) load(workbuf, LDR_NOFLAGS);
608 if (hand == LDR_NULL_MODULE)
609 return "Can't load module.";
610 #endif
611 #else
612 Context;
613 hand = dlopen(workbuf, DLFLAGS);
614 if (!hand)
615 return dlerror();
616 #endif
617 #endif
618
619 sprintf(workbuf, "%s_start", name);
620 #ifdef HPUX_HACKS
621 Context;
622 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
623 f = NULL;
624 #else
625 #ifdef OSF1_HACKS
626 f = (Function) ldr_lookup_package(hand, workbuf);
627 #else
628 f = (Function) dlsym(hand, workbuf);
629 #endif
630 #endif
631 if (f == NULL) { /* some OS's need the _ */
632 sprintf(workbuf, "_%s_start", name);
633 #ifdef HPUX_HACKS
634 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
635 f = NULL;
636 #else
637 #ifdef OSF1_HACKS
638 f = (Function) ldr_lookup_package(hand, workbuf);
639 #else
640 f = (Function) dlsym(hand, workbuf);
641 #endif
642 #endif
643 if (f == NULL) {
644 #ifdef HPUX_HACKS
645 shl_unload(hand);
646 #else
647 #ifdef OSF1_HACKS
648 #else
649 dlclose(hand);
650 #endif
651 #endif
652 return MOD_NOSTARTDEF;
653 }
654 }
655 #else
656 for (sl = static_modules; sl && strcasecmp(sl->name, name); sl = sl->next);
657 Context;
658 if (!sl)
659 return "Unkown module.";
660 f = (Function) sl->func;
661 #endif
662 p = nmalloc(sizeof(module_entry));
663 if (p == NULL)
664 return "Malloc error";
665 p->name = nmalloc(strlen(name) + 1);
666 strcpy(p->name, name);
667 Context;
668 p->major = 0;
669 p->minor = 0;
670 #ifndef STATIC
671 p->hand = hand;
672 #endif
673 p->funcs = 0;
674 p->next = module_list;
675 module_list = p;
676 e = (((char *(*)()) f) (global_table));
677 Context;
678 if (e) {
679 module_list = module_list->next;
680 nfree(p->name);
681 nfree(p);
682 return e;
683 }
684 check_tcl_load(name);
685 putlog(LOG_MISC, "*", "%s %s", MOD_LOADED, name);
686 Context;
687 return NULL;
688 }
689
690 char *module_unload(char *name, char *user)
691 {
692 module_entry *p = module_list, *o = NULL;
693 char *e;
694 Function *f;
695
696 Context;
697 while (p) {
698 if ((p->name != NULL) && (!strcmp(name, p->name))) {
699 dependancy *d = dependancy_list;
700
701 while (d != NULL) {
702 if (d->needed == p) {
703 return MOD_NEEDED;
704 }
705 d = d->next;
706 }
707 f = p->funcs;
708 if (f && !f[MODCALL_CLOSE])
709 return MOD_NOCLOSEDEF;
710 if (f) {
711 check_tcl_unld(name);
712 e = (((char *(*)()) f[MODCALL_CLOSE]) (user));
713 if (e != NULL)
714 return e;
715 #ifndef STATIC
716 #ifdef HPUX_HACKS
717 shl_unload(p->hand);
718 #else
719 #ifdef OSF1_HACKS
720 #else
721 dlclose(p->hand);
722 #endif
723 #endif
724 #endif /* STATIC */
725 }
726 nfree(p->name);
727 if (o == NULL) {
728 module_list = p->next;
729 } else {
730 o->next = p->next;
731 }
732 nfree(p);
733 putlog(LOG_MISC, "*", "%s %s", MOD_UNLOADED, name);
734 return NULL;
735 }
736 o = p;
737 p = p->next;
738 }
739 return MOD_NOSUCH;
740 }
741
742 module_entry *module_find(char *name, int major, int minor)
743 {
744 module_entry *p = module_list;
745
746 while (p) {
747 if (p->name && !strcasecmp(name, p->name) &&
748 ((major == p->major) || (major == 0)) &&
749 (minor <= p->minor))
750 return p;
751 p = p->next;
752 }
753 return NULL;
754 }
755
756 static int module_rename(char *name, char *newname)
757 {
758 module_entry *p = module_list;
759
760 while (p) {
761 if (!strcasecmp(newname, p->name))
762 return 0;
763 p = p->next;
764 }
765 p = module_list;
766 while (p) {
767 if (p->name && !strcasecmp(name, p->name)) {
768 nfree(p->name);
769 p->name = nmalloc(strlen(newname) + 1);
770 strcpy(p->name, newname);
771 return 1;
772 }
773 p = p->next;
774 }
775 return 0;
776 }
777
778 Function *module_depend(char *name1, char *name2, int major, int minor)
779 {
780 module_entry *p = module_find(name2, major, minor);
781 module_entry *o = module_find(name1, 0, 0);
782 dependancy *d;
783
784 Context;
785 if (!p) {
786 if (module_load(name2))
787 return 0;
788 p = module_find(name2, major, minor);
789 }
790 if (!p || !o)
791 return 0;
792 d = nmalloc(sizeof(dependancy));
793
794 d->needed = p;
795 d->needing = o;
796 d->next = dependancy_list;
797 d->major = major;
798 d->minor = minor;
799 dependancy_list = d;
800 Context;
801 return p->funcs ? p->funcs : (Function *) 1;
802 }
803
804 int module_undepend(char *name1)
805 {
806 int ok = 0;
807 module_entry *p = module_find(name1, 0, 0);
808 dependancy *d = dependancy_list, *o = NULL;
809
810 Context;
811 if (p == NULL)
812 return 0;
813 while (d != NULL) {
814 if (d->needing == p) {
815 if (o == NULL) {
816 dependancy_list = d->next;
817 } else {
818 o->next = d->next;
819 }
820 nfree(d);
821 if (o == NULL)
822 d = dependancy_list;
823 else
824 d = o->next;
825 ok++;
826 } else {
827 o = d;
828 d = d->next;
829 }
830 }
831 Context;
832 return ok;
833 }
834
835 void *mod_malloc(int size, char *modname, char *filename, int line)
836 {
837 char x[100];
838
839 sprintf(x, "%s:%s", modname, filename);
840 x[19] = 0;
841 return n_malloc(size, x, line);
842 }
843
844 void *mod_realloc(void *ptr, int size, char *modname, char *filename, int line)
845 {
846 char x[100];
847
848 sprintf(x, "%s:%s", modname, filename);
849 x[19] = 0;
850 return n_realloc(ptr, size, x, line);
851 }
852
853 void mod_free(void *ptr, char *modname, char *filename, int line)
854 {
855 char x[100];
856
857 sprintf(x, "%s:%s", modname, filename);
858 x[19] = 0;
859 n_free(ptr, x, line);
860 }
861
862 /* hooks, various tables of functions to call on ceratin events */
863 void add_hook(int hook_num, Function func)
864 {
865 Context;
866 if (hook_num < REAL_HOOKS) {
867 struct hook_entry *p;
868
869 for (p = hook_list[hook_num]; p; p = p->next)
870 if (p->func == func)
871 return; /* dont add it if it's already there */
872 p = nmalloc(sizeof(struct hook_entry));
873
874 p->next = hook_list[hook_num];
875 hook_list[hook_num] = p;
876 p->func = func;
877 } else
878 switch (hook_num) {
879 case HOOK_ENCRYPT_PASS:
880 encrypt_pass = (void (*)(char *, char *)) func;
881 break;
882 case HOOK_SHAREOUT:
883 shareout = (void (*)()) func;
884 break;
885 case HOOK_SHAREIN:
886 sharein = (void (*)(int, char *)) func;
887 break;
888 case HOOK_QSERV:
889 if (qserver == (void (*)(int, char *, int)) null_func)
890 qserver = (void (*)(int, char *, int)) func;
891 break;
892 case HOOK_ADD_MODE:
893 if (add_mode == (void (*)()) null_func)
894 add_mode = (void (*)()) func;
895 break;
896 /* special hook <drummer> */
897 case HOOK_RFC_CASECMP:
898 if (func == NULL) {
899 rfc_casecmp = strcasecmp;
900 rfc_ncasecmp = (int (*)(const char *, const char *, int)) strncasecmp;
901 rfc_tolower = tolower;
902 rfc_toupper = toupper;
903 } else {
904 rfc_casecmp = _rfc_casecmp;
905 rfc_ncasecmp = _rfc_ncasecmp;
906 rfc_tolower = _rfc_tolower;
907 rfc_toupper = _rfc_toupper;
908 }
909 break;
910 case HOOK_MATCH_NOTEREJ:
911 if (match_noterej == false_func)
912 match_noterej = func;
913 break;
914 }
915 }
916
917 void del_hook(int hook_num, Function func)
918 {
919 Context;
920 if (hook_num < REAL_HOOKS) {
921 struct hook_entry *p = hook_list[hook_num], *o = NULL;
922
923 while (p) {
924 if (p->func == func) {
925 if (o == NULL)
926 hook_list[hook_num] = p->next;
927 else
928 o->next = p->next;
929 nfree(p);
930 break;
931 }
932 o = p;
933 p = p->next;
934 }
935 } else
936 switch (hook_num) {
937 case HOOK_ENCRYPT_PASS:
938 if (encrypt_pass == (void (*)(char *, char *)) func)
939 encrypt_pass = (void (*)(char *, char *)) null_func;
940 break;
941 case HOOK_SHAREOUT:
942 if (shareout == (void (*)()) func)
943 shareout = null_func;
944 break;
945 case HOOK_SHAREIN:
946 if (sharein == (void (*)(int, char *)) func)
947 sharein = null_share;
948 break;
949 case HOOK_QSERV:
950 if (qserver == (void (*)(int, char *, int)) func)
951 qserver = null_func;
952 break;
953 case HOOK_ADD_MODE:
954 if (add_mode == (void (*)()) func)
955 add_mode = null_func;
956 break;
957 case HOOK_MATCH_NOTEREJ:
958 if (match_noterej == func)
959 match_noterej = false_func;
960 break;
961 }
962 }
963
964 int call_hook_cccc(int hooknum, char *a, char *b, char *c, char *d)
965 {
966 struct hook_entry *p;
967 int f = 0;
968
969 if (hooknum >= REAL_HOOKS)
970 return 0;
971 p = hook_list[hooknum];
972 Context;
973 while ((p != NULL) && !f) {
974 f = p->func(a, b, c, d);
975 p = p->next;
976 }
977 return f;
978 }
979
980 void do_module_report(int idx, int details, char *which)
981 {
982 module_entry *p = module_list;
983
984 if (p && !which && details)
985 dprintf(idx, "MODULES LOADED:\n");
986 while (p) {
987 if (!which || !strcasecmp(which, p->name)) {
988 dependancy *d = dependancy_list;
989
990 if (details)
991 dprintf(idx, "Module: %s, v %d.%d\n", p->name ? p->name : "CORE",
992 p->major, p->minor);
993 if (details > 1) {
994 while (d != NULL) {
995 if (d->needing == p)
996 dprintf(idx, " requires: %s, v %d.%d\n", d->needed->name,
997 d->major, d->minor);
998 d = d->next;
999 }
1000 }
1001 if (p->funcs) {
1002 Function f = p->funcs[MODCALL_REPORT];
1003
1004 if (f != NULL)
1005 f(idx, details);
1006 }
1007 if (which)
1008 return;
1009 }
1010 p = p->next;
1011 }
1012 if (which)
1013 dprintf(idx, "No such module.\n");
1014 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23