/[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.2 - (show annotations) (download) (as text)
Thu Aug 5 18:12:05 2010 UTC (9 years, 3 months ago) by pseudo
Branch: MAIN
Changes since 1.1: +22 -14 lines
File MIME type: text/x-chdr
Added new, full IPv6 support to eggdrop.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23