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

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

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


Revision 1.4 - (show annotations) (download) (as text)
Tue Sep 25 17:24:41 2012 UTC (6 years, 7 months ago) by thommey
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +6 -2 lines
File MIME type: text/x-chdr
Export the tcl_result* functions to modules

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.3 2010/10/19 12:13:33 pseudo Exp $
8 */
9 /*
10 * Copyright (C) 1997 Robey Pointer
11 * Copyright (C) 1999 - 2010 Eggheads Development Team
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 <ctype.h>
29 #include "main.h"
30 #include "modules.h"
31 #include "tandem.h"
32 #include "md5/md5.h"
33 #include "users.h"
34
35 #ifndef STATIC
36 # ifdef MOD_USE_SHL
37 # include <dl.h>
38 # endif
39 # ifdef MOD_USE_DYLD
40 # include <mach-o/dyld.h>
41 # define DYLDFLAGS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_PRIVATE|NSLINKMODULE_OPTION_RETURN_ON_ERROR
42 # endif
43 # ifdef MOD_USE_RLD
44 # ifdef HAVE_MACH_O_RLD_H
45 # include <mach-o/rld.h>
46 # else
47 # ifdef HAVE_RLD_H
48 # indluce <rld.h>
49 # endif
50 # endif
51 # endif
52 # ifdef MOD_USE_LOADER
53 # include <loader.h>
54 # endif
55
56 # ifdef MOD_USE_DL
57 # ifdef DLOPEN_1
58 char *dlerror();
59 void *dlopen(const char *, int);
60 int dlclose(void *);
61 void *dlsym(void *, char *);
62 # define DLFLAGS 1
63 # else /* DLOPEN_1 */
64 # include <dlfcn.h>
65
66 # ifndef RTLD_GLOBAL
67 # define RTLD_GLOBAL 0
68 # endif
69 # ifndef RTLD_NOW
70 # define RTLD_NOW 1
71 # endif
72 # ifdef RTLD_LAZY
73 # define DLFLAGS RTLD_LAZY|RTLD_GLOBAL
74 # else
75 # define DLFLAGS RTLD_NOW|RTLD_GLOBAL
76 # endif
77 # endif /* DLOPEN_1 */
78 # endif /* MOD_USE_DL */
79 #endif /* !STATIC */
80
81
82
83 extern struct dcc_t *dcc;
84 extern struct userrec *userlist, *lastuser;
85 extern struct chanset_t *chanset;
86
87 extern char tempdir[], botnetnick[], botname[], origbotname[], botuser[],
88 admin[], userfile[], ver[], notify_new[], helpdir[], version[],
89 quit_msg[], log_ts[];
90
91 extern int parties, noshare, dcc_total, egg_numver, userfile_perm, do_restart,
92 ignore_time, must_be_owner, raw_log, max_dcc, make_userfile,
93 default_flags, require_p, share_greet, use_invites, use_exempts,
94 password_timeout, force_expire, protect_readonly, reserved_port_min,
95 reserved_port_max, copy_to_tmp, quiet_reject;
96
97 #ifdef IPV6
98 extern int pref_af;
99 #endif
100
101 #ifdef TLS
102 extern int tls_vfyclients, tls_vfydcc, tls_vfybots;
103 #endif
104
105 extern party_t *party;
106 extern time_t now, online_since;
107 extern tand_t *tandbot;
108 extern Tcl_Interp *interp;
109 extern sock_list *socklist;
110
111 int cmd_die();
112 int xtra_kill();
113 int xtra_unpack();
114 static int module_rename(char *name, char *newname);
115
116 #ifndef STATIC
117 char moddir[121] = "modules/";
118 #endif
119
120 #ifdef STATIC
121 struct static_list {
122 struct static_list *next;
123 char *name;
124 char *(*func) ();
125 } *static_modules = NULL;
126
127 void check_static(char *name, char *(*func) ())
128 {
129 struct static_list *p = nmalloc(sizeof(struct static_list));
130
131 p->name = nmalloc(strlen(name) + 1);
132 strcpy(p->name, name);
133 p->func = func;
134 p->next = static_modules;
135 static_modules = p;
136 }
137 #endif /* STATIC */
138
139
140 /* The null functions */
141 void null_func()
142 {
143 }
144
145 char *charp_func()
146 {
147 return NULL;
148 }
149
150 int minus_func()
151 {
152 return -1;
153 }
154
155 int false_func()
156 {
157 return 0;
158 }
159
160
161 /* The REAL hooks. When these are called, a return of 0 indicates unhandled;
162 * 1 indicates handled. */
163 struct hook_entry *hook_list[REAL_HOOKS];
164
165 static void null_share(int idx, char *x)
166 {
167 if ((x[0] == 'u') && (x[1] == 'n')) {
168 putlog(LOG_BOTS, "*", "User file rejected by %s: %s", dcc[idx].nick, x + 3);
169 dcc[idx].status &= ~STAT_OFFERED;
170 if (!(dcc[idx].status & STAT_GETTING)) {
171 dcc[idx].status &= ~STAT_SHARE;
172 }
173 } else if ((x[0] != 'v') && (x[0] != 'e')) {
174 dprintf(idx, "s un Not sharing userfile.\n");
175 }
176 }
177
178 void (*encrypt_pass) (char *, char *) = 0;
179 char *(*encrypt_string) (char *, char *) = 0;
180 char *(*decrypt_string) (char *, char *) = 0;
181 void (*shareout) () = null_func;
182 void (*sharein) (int, char *) = null_share;
183 void (*qserver) (int, char *, int) = (void (*)(int, char *, int)) null_func;
184 void (*add_mode) () = null_func;
185 int (*match_noterej) (struct userrec *, char *) =
186 (int (*)(struct userrec *, char *)) false_func;
187 int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
188 int (*rfc_ncasecmp) (const char *, const char *, int) = _rfc_ncasecmp;
189 int (*rfc_toupper) (int) = _rfc_toupper;
190 int (*rfc_tolower) (int) = _rfc_tolower;
191 void (*dns_hostbyip) (sockname_t *) = block_dns_hostbyip;
192 void (*dns_ipbyhost) (char *) = block_dns_ipbyhost;
193
194 module_entry *module_list;
195 dependancy *dependancy_list = NULL;
196
197 /* The horrible global lookup table for functions
198 * BUT it makes the whole thing *much* more portable than letting each
199 * OS screw up the symbols their own special way :/
200 */
201 Function global_table[] = {
202 /* 0 - 3 */
203 (Function) mod_malloc,
204 (Function) mod_free,
205 #ifdef DEBUG_CONTEXT
206 (Function) eggContext,
207 #else
208 (Function) 0,
209 #endif
210 (Function) module_rename,
211 /* 4 - 7 */
212 (Function) module_register,
213 (Function) module_find,
214 (Function) module_depend,
215 (Function) module_undepend,
216 /* 8 - 11 */
217 (Function) add_bind_table,
218 (Function) del_bind_table,
219 (Function) find_bind_table,
220 (Function) check_tcl_bind,
221 /* 12 - 15 */
222 (Function) add_builtins,
223 (Function) rem_builtins,
224 (Function) add_tcl_commands,
225 (Function) rem_tcl_commands,
226 /* 16 - 19 */
227 (Function) add_tcl_ints,
228 (Function) rem_tcl_ints,
229 (Function) add_tcl_strings,
230 (Function) rem_tcl_strings,
231 /* 20 - 23 */
232 (Function) base64_to_int,
233 (Function) int_to_base64,
234 (Function) int_to_base10,
235 (Function) simple_sprintf,
236 /* 24 - 27 */
237 (Function) botnet_send_zapf,
238 (Function) botnet_send_zapf_broad,
239 (Function) botnet_send_unlinked,
240 (Function) botnet_send_bye,
241 /* 28 - 31 */
242 (Function) botnet_send_chat,
243 (Function) botnet_send_filereject,
244 (Function) botnet_send_filesend,
245 (Function) botnet_send_filereq,
246 /* 32 - 35 */
247 (Function) botnet_send_join_idx,
248 (Function) botnet_send_part_idx,
249 (Function) updatebot,
250 (Function) nextbot,
251 /* 36 - 39 */
252 (Function) zapfbot,
253 (Function) n_free,
254 (Function) u_pass_match,
255 (Function) _user_malloc,
256 /* 40 - 43 */
257 (Function) get_user,
258 (Function) set_user,
259 (Function) add_entry_type,
260 (Function) del_entry_type,
261 /* 44 - 47 */
262 (Function) get_user_flagrec,
263 (Function) set_user_flagrec,
264 (Function) get_user_by_host,
265 (Function) get_user_by_handle,
266 /* 48 - 51 */
267 (Function) find_entry_type,
268 (Function) find_user_entry,
269 (Function) adduser,
270 (Function) deluser,
271 /* 52 - 55 */
272 (Function) addhost_by_handle,
273 (Function) delhost_by_handle,
274 (Function) readuserfile,
275 (Function) write_userfile,
276 /* 56 - 59 */
277 (Function) geticon,
278 (Function) clear_chanlist,
279 (Function) reaffirm_owners,
280 (Function) change_handle,
281 /* 60 - 63 */
282 (Function) write_user,
283 (Function) clear_userlist,
284 (Function) count_users,
285 (Function) sanity_check,
286 /* 64 - 67 */
287 (Function) break_down_flags,
288 (Function) build_flags,
289 (Function) flagrec_eq,
290 (Function) flagrec_ok,
291 /* 68 - 71 */
292 (Function) & shareout,
293 (Function) dprintf,
294 (Function) chatout,
295 (Function) chanout_but,
296 /* 72 - 75 */
297 (Function) check_validity,
298 (Function) egg_list_delete,
299 (Function) egg_list_append,
300 (Function) egg_list_contains,
301 /* 76 - 79 */
302 (Function) answer,
303 (Function) getvhost,
304 #ifdef TLS
305 (Function) ssl_handshake,
306 #else
307 (Function) 0,
308 #endif
309 (Function) tputs,
310 /* 80 - 83 */
311 (Function) new_dcc,
312 (Function) lostdcc,
313 (Function) getsock,
314 (Function) killsock,
315 /* 84 - 87 */
316 (Function) open_listen,
317 (Function) getdccaddr,
318 (Function) _get_data_ptr,
319 (Function) open_telnet,
320 /* 88 - 91 */
321 (Function) check_tcl_event,
322 (Function) egg_memcpy,
323 (Function) my_atoul,
324 (Function) my_strcpy,
325 /* 92 - 95 */
326 (Function) & dcc, /* struct dcc_t * */
327 (Function) & chanset, /* struct chanset_t * */
328 (Function) & userlist, /* struct userrec * */
329 (Function) & lastuser, /* struct userrec * */
330 /* 96 - 99 */
331 (Function) & global_bans, /* struct banrec * */
332 (Function) & global_ign, /* struct igrec * */
333 (Function) & password_timeout, /* int */
334 (Function) & share_greet, /* int */
335 /* 100 - 103 */
336 (Function) & max_dcc, /* int */
337 (Function) & require_p, /* int */
338 (Function) & ignore_time, /* int */
339 #ifdef TLS
340 (Function) dcc_fingerprint,
341 #else
342 (Function) 0, /* was use_console_r <Wcc[02/02/03]> */
343 #endif
344 /* 104 - 107 */
345 (Function) & reserved_port_min,
346 (Function) & reserved_port_max,
347 (Function) & raw_log, /* int */
348 (Function) & noshare, /* int */
349 /* 108 - 111 */
350 #ifdef TLS
351 (Function) & tls_vfybots, /* int */
352 #else
353 (Function) 0, /* gban_total -- UNUSED! (Eule) */
354 #endif
355 (Function) & make_userfile, /* int */
356 (Function) & default_flags, /* int */
357 (Function) & dcc_total, /* int */
358 /* 112 - 115 */
359 (Function) tempdir, /* char * */
360 #ifdef TLS
361 (Function) & tls_vfyclients, /* int */
362 (Function) & tls_vfydcc, /* int */
363 #else
364 (Function) 0, /* was natip -- use getmyip() instead */
365 (Function) 0, /* was myip -- use getvhost() instead */
366 #endif
367 (Function) origbotname, /* char * */
368 /* 116 - 119 */
369 (Function) botuser, /* char * */
370 (Function) admin, /* char * */
371 (Function) userfile, /* char * */
372 (Function) ver, /* char * */
373 /* 120 - 123 */
374 (Function) notify_new, /* char * */
375 (Function) helpdir, /* char * */
376 (Function) version, /* char * */
377 (Function) botnetnick, /* char * */
378 /* 124 - 127 */
379 (Function) & DCC_CHAT_PASS, /* struct dcc_table * */
380 (Function) & DCC_BOT, /* struct dcc_table * */
381 (Function) & DCC_LOST, /* struct dcc_table * */
382 (Function) & DCC_CHAT, /* struct dcc_table * */
383 /* 128 - 131 */
384 (Function) & interp, /* Tcl_Interp * */
385 (Function) & now, /* time_t */
386 (Function) findanyidx,
387 (Function) findchan,
388 /* 132 - 135 */
389 (Function) cmd_die,
390 (Function) days,
391 (Function) daysago,
392 (Function) daysdur,
393 /* 136 - 139 */
394 (Function) ismember,
395 (Function) newsplit,
396 (Function) splitnick,
397 (Function) splitc,
398 /* 140 - 143 */
399 (Function) addignore,
400 (Function) match_ignore,
401 (Function) delignore,
402 (Function) fatal,
403 /* 144 - 147 */
404 (Function) xtra_kill,
405 (Function) xtra_unpack,
406 (Function) movefile,
407 (Function) copyfile,
408 /* 148 - 151 */
409 (Function) do_tcl,
410 (Function) readtclprog,
411 (Function) get_language,
412 (Function) def_get,
413 /* 152 - 155 */
414 (Function) makepass,
415 (Function) _wild_match,
416 (Function) maskaddr,
417 (Function) show_motd,
418 /* 156 - 159 */
419 (Function) tellhelp,
420 (Function) showhelp,
421 (Function) add_help_reference,
422 (Function) rem_help_reference,
423 /* 160 - 163 */
424 (Function) touch_laston,
425 (Function) & add_mode, /* Function * */
426 (Function) rmspace,
427 (Function) in_chain,
428 /* 164 - 167 */
429 (Function) add_note,
430 (Function) del_lang_section,
431 (Function) detect_dcc_flood,
432 (Function) flush_lines,
433 /* 168 - 171 */
434 (Function) expected_memory,
435 (Function) tell_mem_status,
436 (Function) & do_restart, /* int */
437 (Function) check_tcl_filt,
438 /* 172 - 175 */
439 (Function) add_hook,
440 (Function) del_hook,
441 (Function) & H_dcc, /* p_tcl_bind_list * */
442 (Function) & H_filt, /* p_tcl_bind_list * */
443 /* 176 - 179 */
444 (Function) & H_chon, /* p_tcl_bind_list * */
445 (Function) & H_chof, /* p_tcl_bind_list * */
446 (Function) & H_load, /* p_tcl_bind_list * */
447 (Function) & H_unld, /* p_tcl_bind_list * */
448 /* 180 - 183 */
449 (Function) & H_chat, /* p_tcl_bind_list * */
450 (Function) & H_act, /* p_tcl_bind_list * */
451 (Function) & H_bcst, /* p_tcl_bind_list * */
452 (Function) & H_bot, /* p_tcl_bind_list * */
453 /* 184 - 187 */
454 (Function) & H_link, /* p_tcl_bind_list * */
455 (Function) & H_disc, /* p_tcl_bind_list * */
456 (Function) & H_away, /* p_tcl_bind_list * */
457 (Function) & H_nkch, /* p_tcl_bind_list * */
458 /* 188 - 191 */
459 (Function) & USERENTRY_BOTADDR, /* struct user_entry_type * */
460 (Function) & USERENTRY_BOTFL, /* struct user_entry_type * */
461 (Function) & USERENTRY_HOSTS, /* struct user_entry_type * */
462 (Function) & USERENTRY_PASS, /* struct user_entry_type * */
463 /* 192 - 195 */
464 (Function) & USERENTRY_XTRA, /* struct user_entry_type * */
465 (Function) user_del_chan,
466 (Function) & USERENTRY_INFO, /* struct user_entry_type * */
467 (Function) & USERENTRY_COMMENT, /* struct user_entry_type * */
468 /* 196 - 199 */
469 (Function) & USERENTRY_LASTON, /* struct user_entry_type * */
470 (Function) putlog,
471 (Function) botnet_send_chan,
472 (Function) list_type_kill,
473 /* 200 - 203 */
474 (Function) logmodes,
475 (Function) masktype,
476 (Function) stripmodes,
477 (Function) stripmasktype,
478 /* 204 - 207 */
479 (Function) sub_lang,
480 (Function) & online_since, /* time_t * */
481 (Function) cmd_loadlanguage,
482 (Function) check_dcc_attrs,
483 /* 208 - 211 */
484 (Function) check_dcc_chanattrs,
485 (Function) add_tcl_coups,
486 (Function) rem_tcl_coups,
487 (Function) botname,
488 /* 212 - 215 */
489 (Function) 0, /* remove_gunk() -- UNUSED! (drummer) */
490 (Function) check_tcl_chjn,
491 (Function) sanitycheck_dcc,
492 (Function) isowner,
493 /* 216 - 219 */
494 (Function) 0, /* min_dcc_port -- UNUSED! (guppy) */
495 (Function) 0, /* max_dcc_port -- UNUSED! (guppy) */
496 (Function) & rfc_casecmp, /* Function * */
497 (Function) & rfc_ncasecmp, /* Function * */
498 /* 220 - 223 */
499 (Function) & global_exempts, /* struct exemptrec * */
500 (Function) & global_invites, /* struct inviterec * */
501 (Function) 0, /* ginvite_total -- UNUSED! (Eule) */
502 (Function) 0, /* gexempt_total -- UNUSED! (Eule) */
503 /* 224 - 227 */
504 (Function) & H_event, /* p_tcl_bind_list * */
505 (Function) & use_exempts, /* int */
506 (Function) & use_invites, /* int */
507 (Function) & force_expire, /* int */
508 /* 228 - 231 */
509 (Function) add_lang_section,
510 (Function) _user_realloc,
511 (Function) mod_realloc,
512 (Function) xtra_set,
513 /* 232 - 235 */
514 #ifdef DEBUG_CONTEXT
515 (Function) eggContextNote,
516 #else
517 (Function) 0,
518 #endif
519 #ifdef DEBUG_ASSERT
520 (Function) eggAssert,
521 #else
522 (Function) 0,
523 #endif
524 (Function) allocsock,
525 (Function) call_hostbyip,
526 /* 236 - 239 */
527 (Function) call_ipbyhost,
528 (Function) iptostr,
529 (Function) & DCC_DNSWAIT, /* struct dcc_table * */
530 (Function) hostsanitycheck_dcc,
531 /* 240 - 243 */
532 (Function) dcc_dnsipbyhost,
533 (Function) dcc_dnshostbyip,
534 (Function) changeover_dcc,
535 (Function) make_rand_str,
536 /* 244 - 247 */
537 (Function) & protect_readonly, /* int */
538 (Function) findchan_by_dname,
539 (Function) removedcc,
540 (Function) & userfile_perm, /* int */
541 /* 248 - 251 */
542 (Function) sock_has_data,
543 (Function) bots_in_subtree,
544 (Function) users_in_subtree,
545 (Function) egg_inet_aton,
546 /* 252 - 255 */
547 (Function) egg_snprintf,
548 (Function) egg_vsnprintf,
549 (Function) egg_memset,
550 (Function) egg_strcasecmp,
551 /* 256 - 259 */
552 (Function) egg_strncasecmp,
553 (Function) is_file,
554 (Function) & must_be_owner, /* int */
555 (Function) & tandbot, /* tand_t * */
556 /* 260 - 263 */
557 (Function) & party, /* party_t * */
558 (Function) open_address_listen,
559 (Function) str_escape,
560 (Function) strchr_unescape,
561 /* 264 - 267 */
562 (Function) str_unescape,
563 (Function) egg_strcatn,
564 (Function) clear_chanlist_member,
565 (Function) fixfrom,
566 /* 268 - 271 */
567 (Function) & socklist, /* sock_list * */
568 (Function) sockoptions,
569 (Function) flush_inbuf,
570 (Function) kill_bot,
571 /* 272 - 275 */
572 (Function) quit_msg, /* char * */
573 (Function) module_load,
574 (Function) module_unload,
575 (Function) & parties, /* int */
576 /* 276 - 279 */
577 (Function) tell_bottree,
578 (Function) MD5_Init,
579 (Function) MD5_Update,
580 (Function) MD5_Final,
581 /* 280 - 283 */
582 (Function) _wild_match_per,
583 (Function) killtransfer,
584 (Function) write_ignores,
585 (Function) & copy_to_tmp, /* int */
586 /* 284 - 287 */
587 (Function) & quiet_reject, /* int */
588 (Function) file_readable,
589 (Function) setsockname,
590 (Function) open_telnet_raw,
591 /* 288 - 291 */
592 #ifdef IPV6
593 (Function) & pref_af, /* int */
594 #else
595 (Function) 0, /* IPv6 leftovers: 288 */
596 #endif
597 (Function) strip_mirc_codes,
598 (Function) check_ansi,
599 (Function) oatoi,
600 /* 292 - 295 */
601 (Function) str_isdigit,
602 (Function) remove_crlf,
603 (Function) addr_match,
604 (Function) mask_match,
605 /* 296 - 299 */
606 (Function) check_conflags,
607 (Function) increase_socks_max,
608 (Function) log_ts,
609 (Function) tcl_resultempty,
610 /* 300 - 304 */
611 (Function) tcl_resultint,
612 (Function) tcl_resultstring
613 };
614
615 void init_modules(void)
616 {
617 int i;
618
619 module_list = nmalloc(sizeof(module_entry));
620 module_list->name = nmalloc(8);
621 strcpy(module_list->name, "eggdrop");
622 module_list->major = (egg_numver) / 10000;
623 module_list->minor = (egg_numver / 100) % 100;
624 #ifndef STATIC
625 module_list->hand = NULL;
626 #endif
627 module_list->next = NULL;
628 module_list->funcs = NULL;
629 for (i = 0; i < REAL_HOOKS; i++)
630 hook_list[i] = NULL;
631 }
632
633 int expmem_modules(int y)
634 {
635 int c = 0, i;
636 module_entry *p;
637 dependancy *d;
638 struct hook_entry *q;
639 Function *f;
640 #ifdef STATIC
641 struct static_list *s;
642
643 for (s = static_modules; s; s = s->next)
644 c += sizeof(struct static_list) + strlen(s->name) + 1;
645 #endif
646
647 for (i = 0; i < REAL_HOOKS; i++)
648 for (q = hook_list[i]; q; q = q->next)
649 c += sizeof(struct hook_entry);
650
651 for (d = dependancy_list; d; d = d->next)
652 c += sizeof(dependancy);
653
654 for (p = module_list; p; p = p->next) {
655 c += sizeof(module_entry);
656 c += strlen(p->name) + 1;
657 f = p->funcs;
658 if (f && f[MODCALL_EXPMEM] && !y)
659 c += (int) (f[MODCALL_EXPMEM] ());
660 }
661 return c;
662 }
663
664 int module_register(char *name, Function *funcs, int major, int minor)
665 {
666 module_entry *p;
667
668 for (p = module_list; p && p->name; p = p->next) {
669 if (!egg_strcasecmp(name, p->name)) {
670 p->major = major;
671 p->minor = minor;
672 p->funcs = funcs;
673 return 1;
674 }
675 }
676
677 return 0;
678 }
679
680 const char *module_load(char *name)
681 {
682 module_entry *p;
683 char *e;
684 Function f;
685 #ifdef STATIC
686 struct static_list *sl;
687 #endif
688
689 #ifndef STATIC
690 char workbuf[1024];
691 # ifdef MOD_USE_SHL
692 shl_t hand;
693 # endif
694 # ifdef MOD_USE_DYLD
695 NSObjectFileImage file;
696 NSObjectFileImageReturnCode ret;
697 NSModule hand;
698 NSSymbol sym;
699 # endif
700 # ifdef MOD_USE_RLD
701 long ret;
702 # endif
703 # ifdef MOD_USE_LOADER
704 ldr_module_t hand;
705 # endif
706 # ifdef MOD_USE_DL
707 void *hand;
708 # endif
709 #endif /* !STATIC */
710
711 if (module_find(name, 0, 0) != NULL)
712 return MOD_ALREADYLOAD;
713
714 #ifndef STATIC
715 if (moddir[0] != '/') {
716 if (getcwd(workbuf, 1024) == NULL)
717 return MOD_BADCWD;
718 sprintf(&(workbuf[strlen(workbuf)]), "/%s%s." EGG_MOD_EXT, moddir, name);
719 } else {
720 sprintf(workbuf, "%s%s." EGG_MOD_EXT, moddir, name);
721 }
722
723 # ifdef MOD_USE_SHL
724 hand = shl_load(workbuf, BIND_IMMEDIATE, 0L);
725 if (!hand)
726 return "Can't load module.";
727 sprintf(workbuf, "%s_start", name);
728 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
729 f = NULL;
730 if (f == NULL) {
731 /* Some OS's require a _ to be prepended to the symbol name (Darwin, etc). */
732 sprintf(workbuf, "_%s_start", name);
733 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
734 f = NULL;
735 }
736 if (f == NULL) {
737 shl_unload(hand);
738 return MOD_NOSTARTDEF;
739 }
740 # endif /* MOD_USE_SHL */
741
742 # ifdef MOD_USE_DYLD
743 ret = NSCreateObjectFileImageFromFile(workbuf, &file);
744 if (ret != NSObjectFileImageSuccess)
745 return "Can't load module.";
746 hand = NSLinkModule(file, workbuf, DYLDFLAGS);
747 sprintf(workbuf, "_%s_start", name);
748 sym = NSLookupSymbolInModule(hand, workbuf);
749 if (sym)
750 f = (Function) NSAddressOfSymbol(sym);
751 else
752 f = NULL;
753 if (f == NULL) {
754 NSUnLinkModule(hand, NSUNLINKMODULE_OPTION_NONE);
755 return MOD_NOSTARTDEF;
756 }
757 # endif /* MOD_USE_DYLD */
758
759 # ifdef MOD_USE_RLD
760 ret = rld_load(NULL, (struct mach_header **) 0, workbuf, (const char *) 0);
761 if (!ret)
762 return "Can't load module.";
763 sprintf(workbuf, "_%s_start", name);
764 ret = rld_lookup(NULL, workbuf, &f)
765 if (!ret || f == NULL)
766 return MOD_NOSTARTDEF;
767 /* There isn't a reliable way to unload at this point... just keep it loaded. */
768 # endif /* MOD_USE_DYLD */
769
770 # ifdef MOD_USE_LOADER
771 hand = load(workbuf, LDR_NOFLAGS);
772 if (hand == LDR_NULL_MODULE)
773 return "Can't load module.";
774 sprintf(workbuf, "%s_start", name);
775 f = (Function) ldr_lookup_package(hand, workbuf);
776 if (f == NULL) {
777 sprintf(workbuf, "_%s_start", name);
778 f = (Function) ldr_lookup_package(hand, workbuf);
779 }
780 if (f == NULL) {
781 unload(hand);
782 return MOD_NOSTARTDEF;
783 }
784 # endif /* MOD_USE_LOADER */
785
786 # ifdef MOD_USE_DL
787 hand = dlopen(workbuf, DLFLAGS);
788 if (!hand)
789 return dlerror();
790 sprintf(workbuf, "%s_start", name);
791 f = (Function) dlsym(hand, workbuf);
792 if (f == NULL) {
793 sprintf(workbuf, "_%s_start", name);
794 f = (Function) dlsym(hand, workbuf);
795 }
796 if (f == NULL) {
797 dlclose(hand);
798 return MOD_NOSTARTDEF;
799 }
800 # endif /* MOD_USE_DL */
801 #endif /* !STATIC */
802
803 #ifdef STATIC
804 for (sl = static_modules; sl && egg_strcasecmp(sl->name, name); sl = sl->next);
805 if (!sl)
806 return "Unknown module.";
807 f = (Function) sl->func;
808 #endif /* STATIC */
809
810 p = nmalloc(sizeof(module_entry));
811 if (p == NULL)
812 return "Malloc error";
813 p->name = nmalloc(strlen(name) + 1);
814 strcpy(p->name, name);
815 p->major = 0;
816 p->minor = 0;
817 #ifndef STATIC
818 p->hand = hand;
819 #endif
820 p->funcs = 0;
821 p->next = module_list;
822 module_list = p;
823 e = (((char *(*)()) f) (global_table));
824 if (e) {
825 module_list = module_list->next;
826 nfree(p->name);
827 nfree(p);
828 return e;
829 }
830 check_tcl_load(name);
831
832 if (exist_lang_section(name))
833 putlog(LOG_MISC, "*", MOD_LOADED_WITH_LANG, name);
834 else
835 putlog(LOG_MISC, "*", MOD_LOADED, name);
836
837 return NULL;
838 }
839
840 char *module_unload(char *name, char *user)
841 {
842 module_entry *p = module_list, *o = NULL;
843 char *e;
844 Function *f;
845
846 while (p) {
847 if ((p->name != NULL) && !strcmp(name, p->name)) {
848 dependancy *d;
849
850 for (d = dependancy_list; d; d = d->next)
851 if (d->needed == p)
852 return MOD_NEEDED;
853
854 f = p->funcs;
855 if (f && !f[MODCALL_CLOSE])
856 return MOD_NOCLOSEDEF;
857 if (f) {
858 check_tcl_unld(name);
859 e = (((char *(*)()) f[MODCALL_CLOSE]) (user));
860 if (e != NULL)
861 return e;
862 #ifndef STATIC
863 # ifdef MOD_USE_SHL
864 shl_unload(p->hand);
865 # endif
866 # ifdef MOD_USE_DYLD
867 NSUnLinkModule(p->hand, NSUNLINKMODULE_OPTION_NONE);
868 # endif
869 # ifdef MOD_USE_LOADER
870 unload(p->hand);
871 # endif
872 # ifdef MOD_USE_DL
873 dlclose(p->hand);
874 # endif
875 #endif /* !STATIC */
876 }
877 nfree(p->name);
878 if (o == NULL)
879 module_list = p->next;
880 else
881 o->next = p->next;
882 nfree(p);
883 putlog(LOG_MISC, "*", "%s %s", MOD_UNLOADED, name);
884 return NULL;
885 }
886 o = p;
887 p = p->next;
888 }
889
890 return MOD_NOSUCH;
891 }
892
893 module_entry *module_find(char *name, int major, int minor)
894 {
895 module_entry *p;
896
897 for (p = module_list; p && p->name; p = p->next) {
898 if ((major == p->major || !major) && minor <= p->minor &&
899 !egg_strcasecmp(name, p->name))
900 return p;
901 }
902 return NULL;
903 }
904
905 static int module_rename(char *name, char *newname)
906 {
907 module_entry *p;
908
909 for (p = module_list; p; p = p->next)
910 if (!egg_strcasecmp(newname, p->name))
911 return 0;
912
913 for (p = module_list; p && p->name; p = p->next) {
914 if (!egg_strcasecmp(name, p->name)) {
915 nfree(p->name);
916 p->name = nmalloc(strlen(newname) + 1);
917 strcpy(p->name, newname);
918 return 1;
919 }
920 }
921 return 0;
922 }
923
924 Function *module_depend(char *name1, char *name2, int major, int minor)
925 {
926 module_entry *p = module_find(name2, major, minor);
927 module_entry *o = module_find(name1, 0, 0);
928 dependancy *d;
929
930 if (!p) {
931 if (module_load(name2))
932 return 0;
933 p = module_find(name2, major, minor);
934 }
935 if (!p || !o)
936 return 0;
937 d = nmalloc(sizeof(dependancy));
938
939 d->needed = p;
940 d->needing = o;
941 d->next = dependancy_list;
942 d->major = major;
943 d->minor = minor;
944 dependancy_list = d;
945 return p->funcs ? p->funcs : (Function *) 1;
946 }
947
948 int module_undepend(char *name1)
949 {
950 int ok = 0;
951 module_entry *p = module_find(name1, 0, 0);
952 dependancy *d = dependancy_list, *o = NULL;
953
954 if (p == NULL)
955 return 0;
956 while (d != NULL) {
957 if (d->needing == p) {
958 if (o == NULL) {
959 dependancy_list = d->next;
960 } else {
961 o->next = d->next;
962 }
963 nfree(d);
964 if (o == NULL)
965 d = dependancy_list;
966 else
967 d = o->next;
968 ok++;
969 } else {
970 o = d;
971 d = d->next;
972 }
973 }
974 return ok;
975 }
976
977 void *mod_malloc(int size, const char *modname, const char *filename, int line)
978 {
979 #ifdef DEBUG_MEM
980 char x[100], *p;
981
982 p = strrchr(filename, '/');
983 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
984 x[19] = 0;
985 return n_malloc(size, x, line);
986 #else
987 return nmalloc(size);
988 #endif
989 }
990
991 void *mod_realloc(void *ptr, int size, const char *modname,
992 const char *filename, int line)
993 {
994 #ifdef DEBUG_MEM
995 char x[100], *p;
996
997 p = strrchr(filename, '/');
998 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
999 x[19] = 0;
1000 return n_realloc(ptr, size, x, line);
1001 #else
1002 return nrealloc(ptr, size);
1003 #endif
1004 }
1005
1006 void mod_free(void *ptr, const char *modname, const char *filename, int line)
1007 {
1008 char x[100], *p;
1009
1010 p = strrchr(filename, '/');
1011 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
1012 x[19] = 0;
1013 n_free(ptr, x, line);
1014 }
1015
1016 /* Hooks, various tables of functions to call on certain events
1017 */
1018 void add_hook(int hook_num, Function func)
1019 {
1020 if (hook_num < REAL_HOOKS) {
1021 struct hook_entry *p;
1022
1023 for (p = hook_list[hook_num]; p; p = p->next)
1024 if (p->func == func)
1025 return; /* Don't add it if it's already there */
1026 p = nmalloc(sizeof(struct hook_entry));
1027
1028 p->next = hook_list[hook_num];
1029 hook_list[hook_num] = p;
1030 p->func = func;
1031 } else
1032 switch (hook_num) {
1033 case HOOK_ENCRYPT_PASS:
1034 encrypt_pass = (void (*)(char *, char *)) func;
1035 break;
1036 case HOOK_ENCRYPT_STRING:
1037 encrypt_string = (char *(*)(char *, char *)) func;
1038 break;
1039 case HOOK_DECRYPT_STRING:
1040 decrypt_string = (char *(*)(char *, char *)) func;
1041 break;
1042 case HOOK_SHAREOUT:
1043 shareout = (void (*)()) func;
1044 break;
1045 case HOOK_SHAREIN:
1046 sharein = (void (*)(int, char *)) func;
1047 break;
1048 case HOOK_QSERV:
1049 if (qserver == (void (*)(int, char *, int)) null_func)
1050 qserver = (void (*)(int, char *, int)) func;
1051 break;
1052 case HOOK_ADD_MODE:
1053 if (add_mode == (void (*)()) null_func)
1054 add_mode = (void (*)()) func;
1055 break;
1056 /* special hook <drummer> */
1057 case HOOK_RFC_CASECMP:
1058 if (func == NULL) {
1059 rfc_casecmp = egg_strcasecmp;
1060 rfc_ncasecmp =
1061 (int (*)(const char *, const char *, int)) egg_strncasecmp;
1062 rfc_tolower = tolower;
1063 rfc_toupper = toupper;
1064 } else {
1065 rfc_casecmp = _rfc_casecmp;
1066 rfc_ncasecmp = _rfc_ncasecmp;
1067 rfc_tolower = _rfc_tolower;
1068 rfc_toupper = _rfc_toupper;
1069 }
1070 break;
1071 case HOOK_MATCH_NOTEREJ:
1072 if (match_noterej == false_func)
1073 match_noterej = (int (*)(struct userrec *, char *)) func;
1074 break;
1075 case HOOK_DNS_HOSTBYIP:
1076 if (dns_hostbyip == block_dns_hostbyip)
1077 dns_hostbyip = (void (*)(sockname_t *)) func;
1078 break;
1079 case HOOK_DNS_IPBYHOST:
1080 if (dns_ipbyhost == block_dns_ipbyhost)
1081 dns_ipbyhost = (void (*)(char *)) func;
1082 break;
1083 }
1084 }
1085
1086 void del_hook(int hook_num, Function func)
1087 {
1088 if (hook_num < REAL_HOOKS) {
1089 struct hook_entry *p = hook_list[hook_num], *o = NULL;
1090
1091 while (p) {
1092 if (p->func == func) {
1093 if (o == NULL)
1094 hook_list[hook_num] = p->next;
1095 else
1096 o->next = p->next;
1097 nfree(p);
1098 break;
1099 }
1100 o = p;
1101 p = p->next;
1102 }
1103 } else
1104 switch (hook_num) {
1105 case HOOK_ENCRYPT_PASS:
1106 if (encrypt_pass == (void (*)(char *, char *)) func)
1107 encrypt_pass = (void (*)(char *, char *)) null_func;
1108 break;
1109 case HOOK_ENCRYPT_STRING:
1110 if (encrypt_string == (char *(*)(char *, char *)) func)
1111 encrypt_string = (char *(*)(char *, char *)) null_func;
1112 break;
1113 case HOOK_DECRYPT_STRING:
1114 if (decrypt_string == (char *(*)(char *, char *)) func)
1115 decrypt_string = (char *(*)(char *, char *)) null_func;
1116 break;
1117 case HOOK_SHAREOUT:
1118 if (shareout == (void (*)()) func)
1119 shareout = null_func;
1120 break;
1121 case HOOK_SHAREIN:
1122 if (sharein == (void (*)(int, char *)) func)
1123 sharein = null_share;
1124 break;
1125 case HOOK_QSERV:
1126 if (qserver == (void (*)(int, char *, int)) func)
1127 qserver = null_func;
1128 break;
1129 case HOOK_ADD_MODE:
1130 if (add_mode == (void (*)()) func)
1131 add_mode = null_func;
1132 break;
1133 case HOOK_MATCH_NOTEREJ:
1134 if (match_noterej == (int (*)(struct userrec *, char *)) func)
1135 match_noterej = false_func;
1136 break;
1137 case HOOK_DNS_HOSTBYIP:
1138 if (dns_hostbyip == (void (*)(sockname_t *)) func)
1139 dns_hostbyip = block_dns_hostbyip;
1140 break;
1141 case HOOK_DNS_IPBYHOST:
1142 if (dns_ipbyhost == (void (*)(char *)) func)
1143 dns_ipbyhost = block_dns_ipbyhost;
1144 break;
1145 }
1146 }
1147
1148 int call_hook_cccc(int hooknum, char *a, char *b, char *c, char *d)
1149 {
1150 struct hook_entry *p, *pn;
1151 int f = 0;
1152
1153 if (hooknum >= REAL_HOOKS)
1154 return 0;
1155 p = hook_list[hooknum];
1156 for (p = hook_list[hooknum]; p && !f; p = pn) {
1157 pn = p->next;
1158 f = p->func(a, b, c, d);
1159 }
1160 return f;
1161 }
1162
1163 void do_module_report(int idx, int details, char *which)
1164 {
1165 module_entry *p = module_list;
1166
1167 if (p && !which)
1168 dprintf(idx, "Loaded module information:\n");
1169 for (; p; p = p->next) {
1170 if (!which || !egg_strcasecmp(which, p->name)) {
1171 dependancy *d;
1172
1173 if (details)
1174 dprintf(idx, " Module: %s, v %d.%d\n", p->name ? p->name : "CORE",
1175 p->major, p->minor);
1176 if (details > 1) {
1177 for (d = dependancy_list; d; d = d->next)
1178 if (d->needing == p)
1179 dprintf(idx, " requires: %s, v %d.%d\n", d->needed->name,
1180 d->major, d->minor);
1181 }
1182 if (p->funcs) {
1183 Function f = p->funcs[MODCALL_REPORT];
1184
1185 if (f != NULL)
1186 f(idx, details);
1187 }
1188 if (which)
1189 return;
1190 }
1191 }
1192 if (which)
1193 dprintf(idx, "No such module.\n");
1194 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23