00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <ctype.h>
00029 #include "main.h"
00030 #include "modules.h"
00031 #include "tandem.h"
00032 #include "md5/md5.h"
00033 #include "users.h"
00034
00035 #ifndef STATIC
00036 # ifdef MOD_USE_SHL
00037 # include <dl.h>
00038 # endif
00039 # ifdef MOD_USE_DYLD
00040 # include <mach-o/dyld.h>
00041 # define DYLDFLAGS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_PRIVATE|NSLINKMODULE_OPTION_RETURN_ON_ERROR
00042 # endif
00043 # ifdef MOD_USE_RLD
00044 # ifdef HAVE_MACH_O_RLD_H
00045 # include <mach-o/rld.h>
00046 # else
00047 # ifdef HAVE_RLD_H
00048 # indluce <rld.h>
00049 # endif
00050 # endif
00051 # endif
00052 # ifdef MOD_USE_LOADER
00053 # include <loader.h>
00054 # endif
00055
00056 # ifdef MOD_USE_DL
00057 # ifdef DLOPEN_1
00058 char *dlerror();
00059 void *dlopen(const char *, int);
00060 int dlclose(void *);
00061 void *dlsym(void *, char *);
00062 # define DLFLAGS 1
00063 # else
00064 # include <dlfcn.h>
00065
00066 # ifndef RTLD_GLOBAL
00067 # define RTLD_GLOBAL 0
00068 # endif
00069 # ifndef RTLD_NOW
00070 # define RTLD_NOW 1
00071 # endif
00072 # ifdef RTLD_LAZY
00073 # define DLFLAGS RTLD_LAZY|RTLD_GLOBAL
00074 # else
00075 # define DLFLAGS RTLD_NOW|RTLD_GLOBAL
00076 # endif
00077 # endif
00078 # endif
00079 #endif
00080
00081
00082
00083 extern struct dcc_t *dcc;
00084 extern struct userrec *userlist, *lastuser;
00085 extern struct chanset_t *chanset;
00086
00087 extern char tempdir[], botnetnick[], botname[], natip[], hostname[],
00088 origbotname[], botuser[], admin[], userfile[], ver[], notify_new[],
00089 helpdir[], version[], quit_msg[], log_ts[];
00090
00091 extern int parties, noshare, dcc_total, egg_numver, userfile_perm, do_restart,
00092 ignore_time, must_be_owner, raw_log, max_dcc, make_userfile,
00093 default_flags, require_p, share_greet, use_invites, use_exempts,
00094 password_timeout, force_expire, protect_readonly, reserved_port_min,
00095 reserved_port_max, copy_to_tmp, quiet_reject;
00096
00097 extern party_t *party;
00098 extern time_t now, online_since;
00099 extern tand_t *tandbot;
00100 extern Tcl_Interp *interp;
00101 extern sock_list *socklist;
00102
00103 int cmd_die();
00104 int xtra_kill();
00105 int xtra_unpack();
00106 static int module_rename(char *name, char *newname);
00107
00108 #ifndef STATIC
00109 char moddir[121] = "modules/";
00110 #endif
00111
00112 #ifdef STATIC
00113 struct static_list {
00114 struct static_list *next;
00115 char *name;
00116 char *(*func) ();
00117 } *static_modules = NULL;
00118
00119 void check_static(char *name, char *(*func) ())
00120 {
00121 struct static_list *p = nmalloc(sizeof(struct static_list));
00122
00123 p->name = nmalloc(strlen(name) + 1);
00124 strcpy(p->name, name);
00125 p->func = func;
00126 p->next = static_modules;
00127 static_modules = p;
00128 }
00129 #endif
00130
00131
00132
00133 void null_func()
00134 {
00135 }
00136
00137 char *charp_func()
00138 {
00139 return NULL;
00140 }
00141
00142 int minus_func()
00143 {
00144 return -1;
00145 }
00146
00147 int false_func()
00148 {
00149 return 0;
00150 }
00151
00152
00153
00154
00155 struct hook_entry *hook_list[REAL_HOOKS];
00156
00157 static void null_share(int idx, char *x)
00158 {
00159 if ((x[0] == 'u') && (x[1] == 'n')) {
00160 putlog(LOG_BOTS, "*", "User file rejected by %s: %s", dcc[idx].nick, x + 3);
00161 dcc[idx].status &= ~STAT_OFFERED;
00162 if (!(dcc[idx].status & STAT_GETTING)) {
00163 dcc[idx].status &= ~STAT_SHARE;
00164 }
00165 } else if ((x[0] != 'v') && (x[0] != 'e')) {
00166 dprintf(idx, "s un Not sharing userfile.\n");
00167 }
00168 }
00169
00170 void (*encrypt_pass) (char *, char *) = 0;
00171 char *(*encrypt_string) (char *, char *) = 0;
00172 char *(*decrypt_string) (char *, char *) = 0;
00173 void (*shareout) () = null_func;
00174 void (*sharein) (int, char *) = null_share;
00175 void (*qserver) (int, char *, int) = (void (*)(int, char *, int)) null_func;
00176 void (*add_mode) () = null_func;
00177 int (*match_noterej) (struct userrec *, char *) =
00178 (int (*)(struct userrec *, char *)) false_func;
00179 int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
00180 int (*rfc_ncasecmp) (const char *, const char *, int) = _rfc_ncasecmp;
00181 int (*rfc_toupper) (int) = _rfc_toupper;
00182 int (*rfc_tolower) (int) = _rfc_tolower;
00183 void (*dns_hostbyip) (IP) = block_dns_hostbyip;
00184 void (*dns_ipbyhost) (char *) = block_dns_ipbyhost;
00185
00186 module_entry *module_list;
00187 dependancy *dependancy_list = NULL;
00188
00189
00190
00191
00192
00193 Function global_table[] = {
00194
00195 (Function) mod_malloc,
00196 (Function) mod_free,
00197 #ifdef DEBUG_CONTEXT
00198 (Function) eggContext,
00199 #else
00200 (Function) 0,
00201 #endif
00202 (Function) module_rename,
00203
00204 (Function) module_register,
00205 (Function) module_find,
00206 (Function) module_depend,
00207 (Function) module_undepend,
00208
00209 (Function) add_bind_table,
00210 (Function) del_bind_table,
00211 (Function) find_bind_table,
00212 (Function) check_tcl_bind,
00213
00214 (Function) add_builtins,
00215 (Function) rem_builtins,
00216 (Function) add_tcl_commands,
00217 (Function) rem_tcl_commands,
00218
00219 (Function) add_tcl_ints,
00220 (Function) rem_tcl_ints,
00221 (Function) add_tcl_strings,
00222 (Function) rem_tcl_strings,
00223
00224 (Function) base64_to_int,
00225 (Function) int_to_base64,
00226 (Function) int_to_base10,
00227 (Function) simple_sprintf,
00228
00229 (Function) botnet_send_zapf,
00230 (Function) botnet_send_zapf_broad,
00231 (Function) botnet_send_unlinked,
00232 (Function) botnet_send_bye,
00233
00234 (Function) botnet_send_chat,
00235 (Function) botnet_send_filereject,
00236 (Function) botnet_send_filesend,
00237 (Function) botnet_send_filereq,
00238
00239 (Function) botnet_send_join_idx,
00240 (Function) botnet_send_part_idx,
00241 (Function) updatebot,
00242 (Function) nextbot,
00243
00244 (Function) zapfbot,
00245 (Function) n_free,
00246 (Function) u_pass_match,
00247 (Function) _user_malloc,
00248
00249 (Function) get_user,
00250 (Function) set_user,
00251 (Function) add_entry_type,
00252 (Function) del_entry_type,
00253
00254 (Function) get_user_flagrec,
00255 (Function) set_user_flagrec,
00256 (Function) get_user_by_host,
00257 (Function) get_user_by_handle,
00258
00259 (Function) find_entry_type,
00260 (Function) find_user_entry,
00261 (Function) adduser,
00262 (Function) deluser,
00263
00264 (Function) addhost_by_handle,
00265 (Function) delhost_by_handle,
00266 (Function) readuserfile,
00267 (Function) write_userfile,
00268
00269 (Function) geticon,
00270 (Function) clear_chanlist,
00271 (Function) reaffirm_owners,
00272 (Function) change_handle,
00273
00274 (Function) write_user,
00275 (Function) clear_userlist,
00276 (Function) count_users,
00277 (Function) sanity_check,
00278
00279 (Function) break_down_flags,
00280 (Function) build_flags,
00281 (Function) flagrec_eq,
00282 (Function) flagrec_ok,
00283
00284 (Function) & shareout,
00285 (Function) dprintf,
00286 (Function) chatout,
00287 (Function) chanout_but,
00288
00289 (Function) check_validity,
00290 (Function) egg_list_delete,
00291 (Function) egg_list_append,
00292 (Function) egg_list_contains,
00293
00294 (Function) answer,
00295 (Function) getmyip,
00296 (Function) neterror,
00297 (Function) tputs,
00298
00299 (Function) new_dcc,
00300 (Function) lostdcc,
00301 (Function) getsock,
00302 (Function) killsock,
00303
00304 (Function) open_listen,
00305 (Function) open_telnet_dcc,
00306 (Function) _get_data_ptr,
00307 (Function) open_telnet,
00308
00309 (Function) check_tcl_event,
00310 (Function) egg_memcpy,
00311 (Function) my_atoul,
00312 (Function) my_strcpy,
00313
00314 (Function) & dcc,
00315 (Function) & chanset,
00316 (Function) & userlist,
00317 (Function) & lastuser,
00318
00319 (Function) & global_bans,
00320 (Function) & global_ign,
00321 (Function) & password_timeout,
00322 (Function) & share_greet,
00323
00324 (Function) & max_dcc,
00325 (Function) & require_p,
00326 (Function) & ignore_time,
00327 (Function) 0,
00328
00329 (Function) & reserved_port_min,
00330 (Function) & reserved_port_max,
00331 (Function) & raw_log,
00332 (Function) & noshare,
00333
00334 (Function) 0,
00335 (Function) & make_userfile,
00336 (Function) & default_flags,
00337 (Function) & dcc_total,
00338
00339 (Function) tempdir,
00340 (Function) natip,
00341 (Function) hostname,
00342 (Function) origbotname,
00343
00344 (Function) botuser,
00345 (Function) admin,
00346 (Function) userfile,
00347 (Function) ver,
00348
00349 (Function) notify_new,
00350 (Function) helpdir,
00351 (Function) version,
00352 (Function) botnetnick,
00353
00354 (Function) & DCC_CHAT_PASS,
00355 (Function) & DCC_BOT,
00356 (Function) & DCC_LOST,
00357 (Function) & DCC_CHAT,
00358
00359 (Function) & interp,
00360 (Function) & now,
00361 (Function) findanyidx,
00362 (Function) findchan,
00363
00364 (Function) cmd_die,
00365 (Function) days,
00366 (Function) daysago,
00367 (Function) daysdur,
00368
00369 (Function) ismember,
00370 (Function) newsplit,
00371 (Function) splitnick,
00372 (Function) splitc,
00373
00374 (Function) addignore,
00375 (Function) match_ignore,
00376 (Function) delignore,
00377 (Function) fatal,
00378
00379 (Function) xtra_kill,
00380 (Function) xtra_unpack,
00381 (Function) movefile,
00382 (Function) copyfile,
00383
00384 (Function) do_tcl,
00385 (Function) readtclprog,
00386 (Function) get_language,
00387 (Function) def_get,
00388
00389 (Function) makepass,
00390 (Function) _wild_match,
00391 (Function) maskaddr,
00392 (Function) show_motd,
00393
00394 (Function) tellhelp,
00395 (Function) showhelp,
00396 (Function) add_help_reference,
00397 (Function) rem_help_reference,
00398
00399 (Function) touch_laston,
00400 (Function) & add_mode,
00401 (Function) rmspace,
00402 (Function) in_chain,
00403
00404 (Function) add_note,
00405 (Function) del_lang_section,
00406 (Function) detect_dcc_flood,
00407 (Function) flush_lines,
00408
00409 (Function) expected_memory,
00410 (Function) tell_mem_status,
00411 (Function) & do_restart,
00412 (Function) check_tcl_filt,
00413
00414 (Function) add_hook,
00415 (Function) del_hook,
00416 (Function) & H_dcc,
00417 (Function) & H_filt,
00418
00419 (Function) & H_chon,
00420 (Function) & H_chof,
00421 (Function) & H_load,
00422 (Function) & H_unld,
00423
00424 (Function) & H_chat,
00425 (Function) & H_act,
00426 (Function) & H_bcst,
00427 (Function) & H_bot,
00428
00429 (Function) & H_link,
00430 (Function) & H_disc,
00431 (Function) & H_away,
00432 (Function) & H_nkch,
00433
00434 (Function) & USERENTRY_BOTADDR,
00435 (Function) & USERENTRY_BOTFL,
00436 (Function) & USERENTRY_HOSTS,
00437 (Function) & USERENTRY_PASS,
00438
00439 (Function) & USERENTRY_XTRA,
00440 (Function) user_del_chan,
00441 (Function) & USERENTRY_INFO,
00442 (Function) & USERENTRY_COMMENT,
00443
00444 (Function) & USERENTRY_LASTON,
00445 (Function) putlog,
00446 (Function) botnet_send_chan,
00447 (Function) list_type_kill,
00448
00449 (Function) logmodes,
00450 (Function) masktype,
00451 (Function) stripmodes,
00452 (Function) stripmasktype,
00453
00454 (Function) sub_lang,
00455 (Function) & online_since,
00456 (Function) cmd_loadlanguage,
00457 (Function) check_dcc_attrs,
00458
00459 (Function) check_dcc_chanattrs,
00460 (Function) add_tcl_coups,
00461 (Function) rem_tcl_coups,
00462 (Function) botname,
00463
00464 (Function) 0,
00465 (Function) check_tcl_chjn,
00466 (Function) sanitycheck_dcc,
00467 (Function) isowner,
00468
00469 (Function) 0,
00470 (Function) 0,
00471 (Function) & rfc_casecmp,
00472 (Function) & rfc_ncasecmp,
00473
00474 (Function) & global_exempts,
00475 (Function) & global_invites,
00476 (Function) 0,
00477 (Function) 0,
00478
00479 (Function) & H_event,
00480 (Function) & use_exempts,
00481 (Function) & use_invites,
00482 (Function) & force_expire,
00483
00484 (Function) add_lang_section,
00485 (Function) _user_realloc,
00486 (Function) mod_realloc,
00487 (Function) xtra_set,
00488
00489 #ifdef DEBUG_CONTEXT
00490 (Function) eggContextNote,
00491 #else
00492 (Function) 0,
00493 #endif
00494 #ifdef DEBUG_ASSERT
00495 (Function) eggAssert,
00496 #else
00497 (Function) 0,
00498 #endif
00499 (Function) allocsock,
00500 (Function) call_hostbyip,
00501
00502 (Function) call_ipbyhost,
00503 (Function) iptostr,
00504 (Function) & DCC_DNSWAIT,
00505 (Function) hostsanitycheck_dcc,
00506
00507 (Function) dcc_dnsipbyhost,
00508 (Function) dcc_dnshostbyip,
00509 (Function) changeover_dcc,
00510 (Function) make_rand_str,
00511
00512 (Function) & protect_readonly,
00513 (Function) findchan_by_dname,
00514 (Function) removedcc,
00515 (Function) & userfile_perm,
00516
00517 (Function) sock_has_data,
00518 (Function) bots_in_subtree,
00519 (Function) users_in_subtree,
00520 (Function) egg_inet_aton,
00521
00522 (Function) egg_snprintf,
00523 (Function) egg_vsnprintf,
00524 (Function) egg_memset,
00525 (Function) egg_strcasecmp,
00526
00527 (Function) egg_strncasecmp,
00528 (Function) is_file,
00529 (Function) & must_be_owner,
00530 (Function) & tandbot,
00531
00532 (Function) & party,
00533 (Function) open_address_listen,
00534 (Function) str_escape,
00535 (Function) strchr_unescape,
00536
00537 (Function) str_unescape,
00538 (Function) egg_strcatn,
00539 (Function) clear_chanlist_member,
00540 (Function) fixfrom,
00541
00542 (Function) & socklist,
00543 (Function) sockoptions,
00544 (Function) flush_inbuf,
00545 (Function) kill_bot,
00546
00547 (Function) quit_msg,
00548 (Function) module_load,
00549 (Function) module_unload,
00550 (Function) & parties,
00551
00552 (Function) tell_bottree,
00553 (Function) MD5_Init,
00554 (Function) MD5_Update,
00555 (Function) MD5_Final,
00556
00557 (Function) _wild_match_per,
00558 (Function) killtransfer,
00559 (Function) write_ignores,
00560 (Function) & copy_to_tmp,
00561
00562 (Function) & quiet_reject,
00563 (Function) file_readable,
00564 (Function) 0,
00565 (Function) 0,
00566
00567 (Function) 0,
00568 (Function) strip_mirc_codes,
00569 (Function) check_ansi,
00570 (Function) oatoi,
00571
00572 (Function) str_isdigit,
00573 (Function) remove_crlf,
00574 (Function) addr_match,
00575 (Function) mask_match,
00576
00577 (Function) check_conflags,
00578 (Function) increase_socks_max,
00579 (Function) log_ts,
00580 (Function) mod_strdup
00581 };
00582
00583 void init_modules(void)
00584 {
00585 int i;
00586
00587 module_list = nmalloc(sizeof(module_entry));
00588 module_list->name = nmalloc(8);
00589 strcpy(module_list->name, "eggdrop");
00590 module_list->major = (egg_numver) / 10000;
00591 module_list->minor = (egg_numver / 100) % 100;
00592 #ifndef STATIC
00593 module_list->hand = NULL;
00594 #endif
00595 module_list->next = NULL;
00596 module_list->funcs = NULL;
00597 for (i = 0; i < REAL_HOOKS; i++)
00598 hook_list[i] = NULL;
00599 }
00600
00601 int expmem_modules(int y)
00602 {
00603 int c = 0, i;
00604 module_entry *p;
00605 dependancy *d;
00606 struct hook_entry *q;
00607 Function *f;
00608 #ifdef STATIC
00609 struct static_list *s;
00610
00611 for (s = static_modules; s; s = s->next)
00612 c += sizeof(struct static_list) + strlen(s->name) + 1;
00613 #endif
00614
00615 for (i = 0; i < REAL_HOOKS; i++)
00616 for (q = hook_list[i]; q; q = q->next)
00617 c += sizeof(struct hook_entry);
00618
00619 for (d = dependancy_list; d; d = d->next)
00620 c += sizeof(dependancy);
00621
00622 for (p = module_list; p; p = p->next) {
00623 c += sizeof(module_entry);
00624 c += strlen(p->name) + 1;
00625 f = p->funcs;
00626 if (f && f[MODCALL_EXPMEM] && !y)
00627 c += (int) (f[MODCALL_EXPMEM] ());
00628 }
00629 return c;
00630 }
00631
00632 int module_register(char *name, Function *funcs, int major, int minor)
00633 {
00634 module_entry *p;
00635
00636 for (p = module_list; p && p->name; p = p->next) {
00637 if (!egg_strcasecmp(name, p->name)) {
00638 p->major = major;
00639 p->minor = minor;
00640 p->funcs = funcs;
00641 return 1;
00642 }
00643 }
00644
00645 return 0;
00646 }
00647
00648 const char *module_load(char *name)
00649 {
00650 module_entry *p;
00651 char *e;
00652 Function f;
00653 #ifdef STATIC
00654 struct static_list *sl;
00655 #endif
00656
00657 #ifndef STATIC
00658 char workbuf[1024];
00659 # ifdef MOD_USE_SHL
00660 shl_t hand;
00661 # endif
00662 # ifdef MOD_USE_DYLD
00663 NSObjectFileImage file;
00664 NSObjectFileImageReturnCode ret;
00665 NSModule hand;
00666 NSSymbol sym;
00667 # endif
00668 # ifdef MOD_USE_RLD
00669 long ret;
00670 # endif
00671 # ifdef MOD_USE_LOADER
00672 ldr_module_t hand;
00673 # endif
00674 # ifdef MOD_USE_DL
00675 void *hand;
00676 # endif
00677 #endif
00678
00679 if (module_find(name, 0, 0) != NULL)
00680 return MOD_ALREADYLOAD;
00681
00682 #ifndef STATIC
00683 if (moddir[0] != '/') {
00684 if (getcwd(workbuf, 1024) == NULL)
00685 return MOD_BADCWD;
00686 sprintf(&(workbuf[strlen(workbuf)]), "/%s%s." EGG_MOD_EXT, moddir, name);
00687 } else {
00688 sprintf(workbuf, "%s%s." EGG_MOD_EXT, moddir, name);
00689 }
00690
00691 # ifdef MOD_USE_SHL
00692 hand = shl_load(workbuf, BIND_IMMEDIATE, 0L);
00693 if (!hand)
00694 return "Can't load module.";
00695 sprintf(workbuf, "%s_start", name);
00696 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
00697 f = NULL;
00698 if (f == NULL) {
00699
00700 sprintf(workbuf, "_%s_start", name);
00701 if (shl_findsym(&hand, workbuf, (short) TYPE_PROCEDURE, (void *) &f))
00702 f = NULL;
00703 }
00704 if (f == NULL) {
00705 shl_unload(hand);
00706 return MOD_NOSTARTDEF;
00707 }
00708 # endif
00709
00710 # ifdef MOD_USE_DYLD
00711 ret = NSCreateObjectFileImageFromFile(workbuf, &file);
00712 if (ret != NSObjectFileImageSuccess)
00713 return "Can't load module.";
00714 hand = NSLinkModule(file, workbuf, DYLDFLAGS);
00715 sprintf(workbuf, "_%s_start", name);
00716 sym = NSLookupSymbolInModule(hand, workbuf);
00717 if (sym)
00718 f = (Function) NSAddressOfSymbol(sym);
00719 else
00720 f = NULL;
00721 if (f == NULL) {
00722 NSUnLinkModule(hand, NSUNLINKMODULE_OPTION_NONE);
00723 return MOD_NOSTARTDEF;
00724 }
00725 # endif
00726
00727 # ifdef MOD_USE_RLD
00728 ret = rld_load(NULL, (struct mach_header **) 0, workbuf, (const char *) 0);
00729 if (!ret)
00730 return "Can't load module.";
00731 sprintf(workbuf, "_%s_start", name);
00732 ret = rld_lookup(NULL, workbuf, &f)
00733 if (!ret || f == NULL)
00734 return MOD_NOSTARTDEF;
00735
00736 # endif
00737
00738 # ifdef MOD_USE_LOADER
00739 hand = load(workbuf, LDR_NOFLAGS);
00740 if (hand == LDR_NULL_MODULE)
00741 return "Can't load module.";
00742 sprintf(workbuf, "%s_start", name);
00743 f = (Function) ldr_lookup_package(hand, workbuf);
00744 if (f == NULL) {
00745 sprintf(workbuf, "_%s_start", name);
00746 f = (Function) ldr_lookup_package(hand, workbuf);
00747 }
00748 if (f == NULL) {
00749 unload(hand);
00750 return MOD_NOSTARTDEF;
00751 }
00752 # endif
00753
00754 # ifdef MOD_USE_DL
00755 hand = dlopen(workbuf, DLFLAGS);
00756 if (!hand)
00757 return dlerror();
00758 sprintf(workbuf, "%s_start", name);
00759 f = (Function) dlsym(hand, workbuf);
00760 if (f == NULL) {
00761 sprintf(workbuf, "_%s_start", name);
00762 f = (Function) dlsym(hand, workbuf);
00763 }
00764 if (f == NULL) {
00765 dlclose(hand);
00766 return MOD_NOSTARTDEF;
00767 }
00768 # endif
00769 #endif
00770
00771 #ifdef STATIC
00772 for (sl = static_modules; sl && egg_strcasecmp(sl->name, name); sl = sl->next);
00773 if (!sl)
00774 return "Unknown module.";
00775 f = (Function) sl->func;
00776 #endif
00777
00778 p = nmalloc(sizeof(module_entry));
00779 if (p == NULL)
00780 return "Malloc error";
00781 p->name = nmalloc(strlen(name) + 1);
00782 strcpy(p->name, name);
00783 p->major = 0;
00784 p->minor = 0;
00785 #ifndef STATIC
00786 p->hand = hand;
00787 #endif
00788 p->funcs = 0;
00789 p->next = module_list;
00790 module_list = p;
00791 e = (((char *(*)()) f) (global_table));
00792 if (e) {
00793 module_list = module_list->next;
00794 nfree(p->name);
00795 nfree(p);
00796 return e;
00797 }
00798 check_tcl_load(name);
00799
00800 if (exist_lang_section(name))
00801 putlog(LOG_MISC, "*", MOD_LOADED_WITH_LANG, name);
00802 else
00803 putlog(LOG_MISC, "*", MOD_LOADED, name);
00804
00805 return NULL;
00806 }
00807
00808 char *module_unload(char *name, char *user)
00809 {
00810 module_entry *p = module_list, *o = NULL;
00811 char *e;
00812 Function *f;
00813
00814 while (p) {
00815 if ((p->name != NULL) && !strcmp(name, p->name)) {
00816 dependancy *d;
00817
00818 for (d = dependancy_list; d; d = d->next)
00819 if (d->needed == p)
00820 return MOD_NEEDED;
00821
00822 f = p->funcs;
00823 if (f && !f[MODCALL_CLOSE])
00824 return MOD_NOCLOSEDEF;
00825 if (f) {
00826 check_tcl_unld(name);
00827 e = (((char *(*)()) f[MODCALL_CLOSE]) (user));
00828 if (e != NULL)
00829 return e;
00830 #ifndef STATIC
00831 # ifdef MOD_USE_SHL
00832 shl_unload(p->hand);
00833 # endif
00834 # ifdef MOD_USE_DYLD
00835 NSUnLinkModule(p->hand, NSUNLINKMODULE_OPTION_NONE);
00836 # endif
00837 # ifdef MOD_USE_LOADER
00838 unload(p->hand);
00839 # endif
00840 # ifdef MOD_USE_DL
00841 dlclose(p->hand);
00842 # endif
00843 #endif
00844 }
00845 nfree(p->name);
00846 if (o == NULL)
00847 module_list = p->next;
00848 else
00849 o->next = p->next;
00850 nfree(p);
00851 putlog(LOG_MISC, "*", "%s %s", MOD_UNLOADED, name);
00852 return NULL;
00853 }
00854 o = p;
00855 p = p->next;
00856 }
00857
00858 return MOD_NOSUCH;
00859 }
00860
00861 module_entry *module_find(char *name, int major, int minor)
00862 {
00863 module_entry *p;
00864
00865 for (p = module_list; p && p->name; p = p->next) {
00866 if ((major == p->major || !major) && minor <= p->minor &&
00867 !egg_strcasecmp(name, p->name))
00868 return p;
00869 }
00870 return NULL;
00871 }
00872
00873 static int module_rename(char *name, char *newname)
00874 {
00875 module_entry *p;
00876
00877 for (p = module_list; p; p = p->next)
00878 if (!egg_strcasecmp(newname, p->name))
00879 return 0;
00880
00881 for (p = module_list; p && p->name; p = p->next) {
00882 if (!egg_strcasecmp(name, p->name)) {
00883 nfree(p->name);
00884 p->name = nmalloc(strlen(newname) + 1);
00885 strcpy(p->name, newname);
00886 return 1;
00887 }
00888 }
00889 return 0;
00890 }
00891
00892 Function *module_depend(char *name1, char *name2, int major, int minor)
00893 {
00894 module_entry *p = module_find(name2, major, minor);
00895 module_entry *o = module_find(name1, 0, 0);
00896 dependancy *d;
00897
00898 if (!p) {
00899 if (module_load(name2))
00900 return 0;
00901 p = module_find(name2, major, minor);
00902 }
00903 if (!p || !o)
00904 return 0;
00905 d = nmalloc(sizeof(dependancy));
00906
00907 d->needed = p;
00908 d->needing = o;
00909 d->next = dependancy_list;
00910 d->major = major;
00911 d->minor = minor;
00912 dependancy_list = d;
00913 return p->funcs ? p->funcs : (Function *) 1;
00914 }
00915
00916 int module_undepend(char *name1)
00917 {
00918 int ok = 0;
00919 module_entry *p = module_find(name1, 0, 0);
00920 dependancy *d = dependancy_list, *o = NULL;
00921
00922 if (p == NULL)
00923 return 0;
00924 while (d != NULL) {
00925 if (d->needing == p) {
00926 if (o == NULL) {
00927 dependancy_list = d->next;
00928 } else {
00929 o->next = d->next;
00930 }
00931 nfree(d);
00932 if (o == NULL)
00933 d = dependancy_list;
00934 else
00935 d = o->next;
00936 ok++;
00937 } else {
00938 o = d;
00939 d = d->next;
00940 }
00941 }
00942 return ok;
00943 }
00944
00945 char *mod_strdup(const char *s, const char *modname, const char *filename, int line)
00946 {
00947 #ifdef DEBUG_MEM
00948 char x[100], *p;
00949
00950 p = strrchr(filename, '/');
00951 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
00952 x[19] = 0;
00953 return n_strdup(s, x, line);
00954 #else
00955 return nstrdup(s);
00956 #endif
00957 }
00958
00959 void *mod_malloc(int size, const char *modname, const char *filename, int line)
00960 {
00961 #ifdef DEBUG_MEM
00962 char x[100], *p;
00963
00964 p = strrchr(filename, '/');
00965 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
00966 x[19] = 0;
00967 return n_malloc(size, x, line);
00968 #else
00969 return nmalloc(size);
00970 #endif
00971 }
00972
00973 void *mod_realloc(void *ptr, int size, const char *modname,
00974 const char *filename, int line)
00975 {
00976 #ifdef DEBUG_MEM
00977 char x[100], *p;
00978
00979 p = strrchr(filename, '/');
00980 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
00981 x[19] = 0;
00982 return n_realloc(ptr, size, x, line);
00983 #else
00984 return nrealloc(ptr, size);
00985 #endif
00986 }
00987
00988 void mod_free(void *ptr, const char *modname, const char *filename, int line)
00989 {
00990 char x[100], *p;
00991
00992 p = strrchr(filename, '/');
00993 egg_snprintf(x, sizeof x, "%s:%s", modname, p ? p + 1 : filename);
00994 x[19] = 0;
00995 n_free(ptr, x, line);
00996 }
00997
00998
00999
01000 void add_hook(int hook_num, Function func)
01001 {
01002 if (hook_num < REAL_HOOKS) {
01003 struct hook_entry *p;
01004
01005 for (p = hook_list[hook_num]; p; p = p->next)
01006 if (p->func == func)
01007 return;
01008 p = nmalloc(sizeof(struct hook_entry));
01009
01010 p->next = hook_list[hook_num];
01011 hook_list[hook_num] = p;
01012 p->func = func;
01013 } else
01014 switch (hook_num) {
01015 case HOOK_ENCRYPT_PASS:
01016 encrypt_pass = (void (*)(char *, char *)) func;
01017 break;
01018 case HOOK_ENCRYPT_STRING:
01019 encrypt_string = (char *(*)(char *, char *)) func;
01020 break;
01021 case HOOK_DECRYPT_STRING:
01022 decrypt_string = (char *(*)(char *, char *)) func;
01023 break;
01024 case HOOK_SHAREOUT:
01025 shareout = (void (*)()) func;
01026 break;
01027 case HOOK_SHAREIN:
01028 sharein = (void (*)(int, char *)) func;
01029 break;
01030 case HOOK_QSERV:
01031 if (qserver == (void (*)(int, char *, int)) null_func)
01032 qserver = (void (*)(int, char *, int)) func;
01033 break;
01034 case HOOK_ADD_MODE:
01035 if (add_mode == (void (*)()) null_func)
01036 add_mode = (void (*)()) func;
01037 break;
01038
01039 case HOOK_RFC_CASECMP:
01040 if (func == NULL) {
01041 rfc_casecmp = egg_strcasecmp;
01042 rfc_ncasecmp =
01043 (int (*)(const char *, const char *, int)) egg_strncasecmp;
01044 rfc_tolower = tolower;
01045 rfc_toupper = toupper;
01046 } else {
01047 rfc_casecmp = _rfc_casecmp;
01048 rfc_ncasecmp = _rfc_ncasecmp;
01049 rfc_tolower = _rfc_tolower;
01050 rfc_toupper = _rfc_toupper;
01051 }
01052 break;
01053 case HOOK_MATCH_NOTEREJ:
01054 if (match_noterej == false_func)
01055 match_noterej = (int (*)(struct userrec *, char *)) func;
01056 break;
01057 case HOOK_DNS_HOSTBYIP:
01058 if (dns_hostbyip == block_dns_hostbyip)
01059 dns_hostbyip = (void (*)(IP)) func;
01060 break;
01061 case HOOK_DNS_IPBYHOST:
01062 if (dns_ipbyhost == block_dns_ipbyhost)
01063 dns_ipbyhost = (void (*)(char *)) func;
01064 break;
01065 }
01066 }
01067
01068 void del_hook(int hook_num, Function func)
01069 {
01070 if (hook_num < REAL_HOOKS) {
01071 struct hook_entry *p = hook_list[hook_num], *o = NULL;
01072
01073 while (p) {
01074 if (p->func == func) {
01075 if (o == NULL)
01076 hook_list[hook_num] = p->next;
01077 else
01078 o->next = p->next;
01079 nfree(p);
01080 break;
01081 }
01082 o = p;
01083 p = p->next;
01084 }
01085 } else
01086 switch (hook_num) {
01087 case HOOK_ENCRYPT_PASS:
01088 if (encrypt_pass == (void (*)(char *, char *)) func)
01089 encrypt_pass = (void (*)(char *, char *)) null_func;
01090 break;
01091 case HOOK_ENCRYPT_STRING:
01092 if (encrypt_string == (char *(*)(char *, char *)) func)
01093 encrypt_string = (char *(*)(char *, char *)) null_func;
01094 break;
01095 case HOOK_DECRYPT_STRING:
01096 if (decrypt_string == (char *(*)(char *, char *)) func)
01097 decrypt_string = (char *(*)(char *, char *)) null_func;
01098 break;
01099 case HOOK_SHAREOUT:
01100 if (shareout == (void (*)()) func)
01101 shareout = null_func;
01102 break;
01103 case HOOK_SHAREIN:
01104 if (sharein == (void (*)(int, char *)) func)
01105 sharein = null_share;
01106 break;
01107 case HOOK_QSERV:
01108 if (qserver == (void (*)(int, char *, int)) func)
01109 qserver = null_func;
01110 break;
01111 case HOOK_ADD_MODE:
01112 if (add_mode == (void (*)()) func)
01113 add_mode = null_func;
01114 break;
01115 case HOOK_MATCH_NOTEREJ:
01116 if (match_noterej == (int (*)(struct userrec *, char *)) func)
01117 match_noterej = false_func;
01118 break;
01119 case HOOK_DNS_HOSTBYIP:
01120 if (dns_hostbyip == (void (*)(IP)) func)
01121 dns_hostbyip = block_dns_hostbyip;
01122 break;
01123 case HOOK_DNS_IPBYHOST:
01124 if (dns_ipbyhost == (void (*)(char *)) func)
01125 dns_ipbyhost = block_dns_ipbyhost;
01126 break;
01127 }
01128 }
01129
01130 int call_hook_cccc(int hooknum, char *a, char *b, char *c, char *d)
01131 {
01132 struct hook_entry *p, *pn;
01133 int f = 0;
01134
01135 if (hooknum >= REAL_HOOKS)
01136 return 0;
01137 p = hook_list[hooknum];
01138 for (p = hook_list[hooknum]; p && !f; p = pn) {
01139 pn = p->next;
01140 f = p->func(a, b, c, d);
01141 }
01142 return f;
01143 }
01144
01145 void do_module_report(int idx, int details, char *which)
01146 {
01147 module_entry *p = module_list;
01148
01149 if (p && !which)
01150 dprintf(idx, "Loaded module information:\n");
01151 for (; p; p = p->next) {
01152 if (!which || !egg_strcasecmp(which, p->name)) {
01153 dependancy *d;
01154
01155 if (details)
01156 dprintf(idx, " Module: %s, v %d.%d\n", p->name ? p->name : "CORE",
01157 p->major, p->minor);
01158 if (details > 1) {
01159 for (d = dependancy_list; d; d = d->next)
01160 if (d->needing == p)
01161 dprintf(idx, " requires: %s, v %d.%d\n", d->needed->name,
01162 d->major, d->minor);
01163 }
01164 if (p->funcs) {
01165 Function f = p->funcs[MODCALL_REPORT];
01166
01167 if (f != NULL)
01168 f(idx, details);
01169 }
01170 if (which)
01171 return;
01172 }
01173 }
01174 if (which)
01175 dprintf(idx, "No such module.\n");
01176 }