char *wire_start(Function *global_funcs) { p_tcl_bind_list H_temp; global = global_funcs; module_register(MODULE_NAME, wire_table, 2, 0); if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.0 or later."; } if (!(encryption_funcs = module_depend(MODULE_NAME, "encryption", 2, 1))) { module_undepend(MODULE_NAME); return "This module requires an encryption module."; } add_help_reference("wire.help"); add_builtins(H_dcc, wire_dcc); H_temp = find_bind_table("filt"); add_builtins(H_filt, wire_filt); H_temp = find_bind_table("chof"); add_builtins(H_chof, wire_chof); wirelist = NULL; add_lang_section("wire"); return NULL; }
char *notes_start(Function *global_funcs) { global = global_funcs; notefile[0] = 0; module_register(MODULE_NAME, notes_table, 2, 1); if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.0 or later."; } add_hook(HOOK_HOURLY, (Function) notes_hourly); add_hook(HOOK_MATCH_NOTEREJ, (Function) match_note_ignore); add_tcl_ints(notes_ints); add_tcl_strings(notes_strings); add_tcl_commands(notes_tcls); add_builtins(H_dcc, notes_cmds); add_builtins(H_chon, notes_chon); add_builtins(H_away, notes_away); add_builtins(H_nkch, notes_nkch); add_builtins(H_load, notes_load); add_help_reference("notes.help"); add_lang_section("notes"); notes_server_setup(0); notes_irc_setup(0); my_memcpy(&USERENTRY_FWD, &USERENTRY_INFO, sizeof(void *) * 12); add_entry_type(&USERENTRY_FWD); return NULL; }
char *ctcp_start(Function *global_funcs) { global = global_funcs; module_register(MODULE_NAME, ctcp_table, 1, 1); if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.8.0 or later."; } if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) { module_undepend(MODULE_NAME); return "This module requires server module 1.0 or later."; } add_tcl_strings(mystrings); add_tcl_ints(myints); add_builtins(H_ctcp, myctcp); add_help_reference("ctcp.help"); if (!ctcp_version[0]) { strncpy(ctcp_version, ver, 120); ctcp_version[120] = 0; } if (!ctcp_finger[0]) { strncpy(ctcp_finger, ver, 120); ctcp_finger[120] = 0; } if (!ctcp_userinfo[0]) { strncpy(ctcp_userinfo, ver, 120); ctcp_userinfo[120] = 0; } return NULL; }
char *filesys_start(Function *global_funcs) { global = global_funcs; module_register(MODULE_NAME, filesys_table, 2, 0); if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.0 or later."; } if (!(transfer_funcs = module_depend(MODULE_NAME, "transfer", 2, 0))) { module_undepend(MODULE_NAME); return "This module requires transfer module 2.0 or later."; } add_tcl_commands(mytcls); add_tcl_strings(mystrings); add_tcl_ints(myints); H_fil = add_bind_table("fil", 0, builtin_fil); add_builtins(H_dcc, mydcc); add_builtins(H_fil, myfiles); add_builtins(H_load, myload); add_help_reference("filesys.help"); init_server_ctcps(0); my_memcpy(&USERENTRY_DCCDIR, &USERENTRY_INFO, sizeof(struct user_entry_type) - sizeof(char *)); USERENTRY_DCCDIR.got_share = 0; /* We dont want it shared tho */ add_entry_type(&USERENTRY_DCCDIR); DCC_FILES_PASS.timeout_val = &password_timeout; add_lang_section("filesys"); return NULL; }
char *channels_start(Function * global_funcs) { global = global_funcs; gfld_chan_thr = 10; gfld_chan_time = 60; gfld_deop_thr = 3; gfld_deop_time = 10; gfld_kick_thr = 3; gfld_kick_time = 10; gfld_join_thr = 5; gfld_join_time = 60; gfld_ctcp_thr = 5; gfld_ctcp_time = 60; global_idle_kick = 0; Context; module_register(MODULE_NAME, channels_table, 1, 0); if (!module_depend(MODULE_NAME, "eggdrop", 105, 3)) { module_undepend(MODULE_NAME); return "This module needs eggdrop1.5.3 or later"; } add_hook(HOOK_MINUTELY, (Function) check_expired_bans); add_hook(HOOK_MINUTELY, (Function) check_expired_exempts); add_hook(HOOK_MINUTELY, (Function) check_expired_invites); add_hook(HOOK_USERFILE, (Function) channels_writeuserfile); add_hook(HOOK_REHASH, (Function) channels_rehash); add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash); Tcl_TraceVar(interp, "global-chanset", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, traced_globchanset, NULL); add_builtins(H_chon, my_chon); add_builtins(H_dcc, C_dcc_irc); add_tcl_commands(channels_cmds); add_tcl_strings(my_tcl_strings); add_help_reference("channels.help"); add_help_reference("chaninfo.help"); my_tcl_ints[0].val = &share_greet; add_tcl_ints(my_tcl_ints); add_tcl_coups(mychan_tcl_coups); read_channels(0); setstatic = 1; return NULL; }
char *seen_start(Function * egg_func_table) { global = egg_func_table; Context; module_register(MODULE_NAME, seen_table, 2, 0); if (!module_depend(MODULE_NAME, "eggdrop", 104, 0)) return "This module needs eggdrop1.4.0 or later"; add_builtins(H_load, seen_load); add_builtins(H_dcc, seen_dcc); add_help_reference("seen.help"); server_seen_setup(0); irc_seen_setup(0); trigdata[4].key = botnetnick; return NULL; }
char *seen_start(Function *egg_func_table) { global = egg_func_table; module_register(MODULE_NAME, seen_table, 2, 0); if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.0 or later."; } add_builtins(H_load, seen_load); add_builtins(H_dcc, seen_dcc); add_help_reference("seen.help"); server_seen_setup(NULL); irc_seen_setup(NULL); trigdata[4].key = botnetnick; return NULL; }
char *uptime_start(Function *global_funcs) { if (global_funcs) { global = global_funcs; module_register(MODULE_NAME, uptime_table, 1, 3); if (!module_depend(MODULE_NAME, "eggdrop", 106, 11)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.11 or later."; } add_help_reference("uptime.help"); add_hook(HOOK_MINUTELY, (Function) check_minutely); init_uptime(); } return NULL; }
char *assoc_start(Function *global_funcs) { global = global_funcs; module_register(MODULE_NAME, assoc_table, 2, 0); if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.0 or later."; } assoc = NULL; add_builtins(H_dcc, mydcc); add_builtins(H_bot, mybot); add_builtins(H_link, mylink); add_lang_section("assoc"); add_tcl_commands(mytcl); add_help_reference("assoc.help"); return NULL; }
int main(int arg_c, char **arg_v) { int i, xx; char s[25]; FILE *f; struct sigaction sv; struct chanset_t *chan; #ifdef DEBUG struct rlimit cdlim; #endif #ifdef STOP_UAC int nvpair[2]; #endif /* Make sure it can write core, if you make debug. Else it's pretty * useless (dw) * * Only allow unlimited size core files when compiled with DEBUG defined. * This is not a good idea for normal builds -- in these cases, use the * default system resource limits instead. */ #ifdef DEBUG cdlim.rlim_cur = RLIM_INFINITY; cdlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &cdlim); #endif #ifdef DEBUG_CONTEXT /* Initialise context list */ for (i = 0; i < 16; i++) Context; #endif /* Include patch.h header for patch("...") */ #include "patch.h" argc = arg_c; argv = arg_v; /* Version info! */ egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version); egg_snprintf(version, sizeof version, "Eggdrop v%s (C) 1997 Robey Pointer (C) 2010 Eggheads", egg_version); /* Now add on the patchlevel (for Tcl) */ sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver); strcat(egg_version, egg_xtra); /* For OSF/1 */ #ifdef STOP_UAC /* Don't print "unaligned access fixup" warning to the user */ nvpair[0] = SSIN_UACPROC; nvpair[1] = UAC_NOPRINT; setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0); #endif /* Set up error traps: */ sv.sa_handler = got_bus; sigemptyset(&sv.sa_mask); #ifdef SA_RESETHAND sv.sa_flags = SA_RESETHAND; #else sv.sa_flags = 0; #endif sigaction(SIGBUS, &sv, NULL); sv.sa_handler = got_segv; sigaction(SIGSEGV, &sv, NULL); #ifdef SA_RESETHAND sv.sa_flags = 0; #endif sv.sa_handler = got_fpe; sigaction(SIGFPE, &sv, NULL); sv.sa_handler = got_term; sigaction(SIGTERM, &sv, NULL); sv.sa_handler = got_hup; sigaction(SIGHUP, &sv, NULL); sv.sa_handler = got_quit; sigaction(SIGQUIT, &sv, NULL); sv.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sv, NULL); sv.sa_handler = got_ill; sigaction(SIGILL, &sv, NULL); sv.sa_handler = got_alarm; sigaction(SIGALRM, &sv, NULL); /* Initialize variables and stuff */ now = time(NULL); chanset = NULL; egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm)); lastmin = nowtm.tm_min; srandom((unsigned int) (now % (getpid() + getppid()))); init_mem(); init_language(1); if (argc > 1) for (i = 1; i < argc; i++) do_arg(argv[i]); printf("\n%s\n", version); #ifndef CYGWIN_HACKS /* Don't allow eggdrop to run as root * This check isn't useful under cygwin and has been * reported to cause trouble in some situations. */ if (((int) getuid() == 0) || ((int) geteuid() == 0)) fatal("ERROR: Eggdrop will not run as root!", 0); #endif #ifndef REPLACE_NOTIFIER init_threaddata(1); #endif init_userent(); init_misc(); init_bots(); init_modules(); if (backgrd) bg_prepare_split(); init_tcl(argc, argv); init_language(0); #ifdef STATIC link_statics(); #endif strncpyz(s, ctime(&now), sizeof s); strcpy(&s[11], &s[20]); putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s); chanprog(); if (!encrypt_pass) { printf(MOD_NOCRYPT); bg_send_quit(BG_ABORT); exit(1); } i = 0; for (chan = chanset; chan; chan = chan->next) i++; putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick, i, count_users(userlist)); #ifdef TLS ssl_init(); #endif cache_miss = 0; cache_hit = 0; if (!pid_file[0]) egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick); /* Check for pre-existing eggdrop! */ f = fopen(pid_file, "r"); if (f != NULL) { fgets(s, 10, f); xx = atoi(s); i = kill(xx, SIGCHLD); /* Meaningless kill to determine if pid * is used */ if (i == 0 || errno != ESRCH) { printf(EGG_RUNNING1, botnetnick); printf(EGG_RUNNING2, pid_file); bg_send_quit(BG_ABORT); exit(1); } } /* Move into background? */ if (backgrd) { bg_do_split(); } else { /* !backgrd */ xx = getpid(); if (xx != 0) { FILE *fp; /* Write pid to file */ unlink(pid_file); fp = fopen(pid_file, "w"); if (fp != NULL) { fprintf(fp, "%u\n", xx); if (fflush(fp)) { /* Let the bot live since this doesn't appear to be a botchk */ printf(EGG_NOWRITE, pid_file); fclose(fp); unlink(pid_file); } else fclose(fp); } else printf(EGG_NOWRITE, pid_file); } } use_stderr = 0; /* Stop writing to stderr now */ if (backgrd) { /* Ok, try to disassociate from controlling terminal (finger cross) */ #ifdef HAVE_SETPGID setpgid(0, 0); #endif /* Tcl wants the stdin, stdout and stderr file handles kept open. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); #ifdef CYGWIN_HACKS FreeConsole(); #endif } /* Terminal emulating dcc chat */ if (!backgrd && term_z) { int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info)); getvhost(&dcc[n].sockname, AF_INET); dcc[n].sock = STDOUT; dcc[n].timeval = now; dcc[n].u.chat->con_flags = conmask; dcc[n].u.chat->strip_flags = STRIP_ALL; dcc[n].status = STAT_ECHO; strcpy(dcc[n].nick, "HQ"); strcpy(dcc[n].host, "llama@console"); /* HACK: Workaround not to pass literal "HQ" as a non-const arg */ dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); /* Make sure there's an innocuous HQ user if needed */ if (!dcc[n].user) { userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); } setsock(STDOUT, 0); /* Entry in net table */ dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n"); dcc_chatter(n); } then = now; online_since = now; autolink_cycle(NULL); /* Hurry and connect to tandem bots */ add_help_reference("cmds1.help"); add_help_reference("cmds2.help"); add_help_reference("core.help"); add_hook(HOOK_SECONDLY, (Function) core_secondly); add_hook(HOOK_MINUTELY, (Function) core_minutely); add_hook(HOOK_HOURLY, (Function) core_hourly); add_hook(HOOK_REHASH, (Function) event_rehash); add_hook(HOOK_PRE_REHASH, (Function) event_prerehash); add_hook(HOOK_USERFILE, (Function) event_save); add_hook(HOOK_BACKUP, (Function) backup_userfile); add_hook(HOOK_DAILY, (Function) event_logfile); add_hook(HOOK_DAILY, (Function) event_resettraffic); add_hook(HOOK_LOADED, (Function) event_loaded); call_hook(HOOK_LOADED); debug0("main: entering loop"); while (1) { mainloop(1); } }
char *irc_start(Function *global_funcs) { struct chanset_t *chan; global = global_funcs; module_register(MODULE_NAME, irc_table, 1, 5); if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.8.0 or later."; } if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) { module_undepend(MODULE_NAME); return "This module requires server module 1.0 or later."; } if (!(channels_funcs = module_depend(MODULE_NAME, "channels", 1, 1))) { module_undepend(MODULE_NAME); return "This module requires channels module 1.1 or later."; } for (chan = chanset; chan; chan = chan->next) { if (!channel_inactive(chan)) { if (chan->key_prot[0]) dprintf(DP_SERVER, "JOIN %s %s\n", chan->name[0] ? chan->name : chan->dname, chan->key_prot); else dprintf(DP_SERVER, "JOIN %s\n", chan->name[0] ? chan->name : chan->dname); } chan->status &= ~(CHAN_ACTIVE | CHAN_PEND | CHAN_ASKEDBANS); chan->ircnet_status &= ~(CHAN_ASKED_INVITED | CHAN_ASKED_EXEMPTS); } add_hook(HOOK_MINUTELY, (Function) check_expired_chanstuff); add_hook(HOOK_5MINUTELY, (Function) status_log); add_hook(HOOK_ADD_MODE, (Function) real_add_mode); add_hook(HOOK_IDLE, (Function) flush_modes); Tcl_TraceVar(interp, "net-type", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, traced_nettype, NULL); Tcl_TraceVar(interp, "rfc-compliant", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, traced_rfccompliant, NULL); strcpy(opchars, "@"); add_tcl_strings(mystrings); add_tcl_ints(myints); add_builtins(H_dcc, irc_dcc); add_builtins(H_msg, C_msg); add_builtins(H_raw, irc_raw); add_tcl_commands(tclchan_cmds); add_help_reference("irc.help"); H_topc = add_bind_table("topc", HT_STACKABLE, channels_5char); H_splt = add_bind_table("splt", HT_STACKABLE, channels_4char); H_sign = add_bind_table("sign", HT_STACKABLE, channels_5char); H_rejn = add_bind_table("rejn", HT_STACKABLE, channels_4char); H_part = add_bind_table("part", HT_STACKABLE, channels_5char); H_nick = add_bind_table("nick", HT_STACKABLE, channels_5char); H_mode = add_bind_table("mode", HT_STACKABLE, channels_6char); H_kick = add_bind_table("kick", HT_STACKABLE, channels_6char); H_join = add_bind_table("join", HT_STACKABLE, channels_4char); H_pubm = add_bind_table("pubm", HT_STACKABLE, channels_5char); H_pub = add_bind_table("pub", 0, channels_5char); H_need = add_bind_table("need", HT_STACKABLE, channels_2char); do_nettype(); return NULL; }
char *channels_start(Function *global_funcs) { global = global_funcs; gfld_chan_thr = 10; gfld_chan_time = 60; gfld_deop_thr = 3; gfld_deop_time = 10; gfld_kick_thr = 3; gfld_kick_time = 10; gfld_join_thr = 5; gfld_join_time = 60; gfld_ctcp_thr = 5; gfld_ctcp_time = 60; global_idle_kick = 0; global_aop_min = 5; global_aop_max = 30; allow_ps = 0; lastdeletedmask = 0; use_info = 1; strcpy(chanfile, "chanfile"); chan_hack = 0; quiet_save = 0; strcpy(glob_chanmode, "nt"); udef = NULL; global_stopnethack_mode = 0; global_revenge_mode = 0; global_ban_type = 3; global_ban_time = 120; global_exempt_time = 60; global_invite_time = 60; strcpy(glob_chanset, "-enforcebans " "+dynamicbans " "+userbans " "-autoop " "-bitch " "+greet " "+protectops " "+statuslog " "-revenge " "-secret " "-autovoice " "+cycle " "+dontkickops " "-inactive " "-protectfriends " "+shared " "-seen " "+userexempts " "+dynamicexempts " "+userinvites " "+dynamicinvites " "-revengebot " "-protecthalfops " "-autohalfop " "-nodesynch " "-static "); module_register(MODULE_NAME, channels_table, 1, 1); if (!module_depend(MODULE_NAME, "eggdrop", 106, 20)) { module_undepend(MODULE_NAME); return "This module requires Eggdrop 1.6.20 or later."; } add_hook(HOOK_MINUTELY, (Function) check_expired_bans); add_hook(HOOK_MINUTELY, (Function) check_expired_exempts); add_hook(HOOK_MINUTELY, (Function) check_expired_invites); add_hook(HOOK_USERFILE, (Function) channels_writeuserfile); add_hook(HOOK_BACKUP, (Function) backup_chanfile); add_hook(HOOK_REHASH, (Function) channels_rehash); add_hook(HOOK_PRE_REHASH, (Function) channels_prerehash); Tcl_TraceVar(interp, "global-chanset", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, traced_globchanset, NULL); add_builtins(H_chon, my_chon); add_builtins(H_dcc, C_dcc_irc); add_tcl_commands(channels_cmds); add_tcl_strings(my_tcl_strings); add_help_reference("channels.help"); add_help_reference("chaninfo.help"); my_tcl_ints[0].val = &share_greet; add_tcl_ints(my_tcl_ints); add_tcl_coups(mychan_tcl_coups); read_channels(0, 1); return NULL; }
int main(int argc, char **argv) { int xx, i; #ifdef STOP_UAC int nvpair[2]; #endif char buf[520], s[25]; FILE *f; #ifndef ENABLE_STRIP struct rlimit cdlim; #endif /* Don't allow Eggdrop to run as root. */ if (((int) getuid() == 0) || ((int) geteuid() == 0)) fatal("ERROR: Eggdrop will not run as root!", 0); #ifndef ENABLE_STRIP cdlim.rlim_cur = RLIM_INFINITY; cdlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &cdlim); #endif #include "patch.h" /* Version info! */ egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version); egg_snprintf(version, sizeof version, "Eggdrop v%s (C) 1997 Robey Pointer (C) 2005 Eggheads", egg_version); /* Now add on the patchlevel (for Tcl) */ sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver); strcat(egg_version, egg_xtra); #ifdef STOP_UAC nvpair[0] = SSIN_UACPROC; nvpair[1] = UAC_NOPRINT; setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0); #endif /* Set up error / signal traps. */ setup_signal_traps(); /* Initialize a few variables before main loop. */ cache_miss = 0; cache_hit = 0; chanset = NULL; now = time(NULL); egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm)); lastmin = nowtm.tm_min; /* Initialize random number generator. */ srandom((unsigned int) (now % (getpid() + getppid()))); init_mem(); init_language(1); /* Process command line arguments. */ process_args(argc, argv); printf("\n%s\n", version); init_dcc_max(); init_userent(); logfile_init(0); init_bots(); init_net(); init_modules(); if (backgrd) bg_prepare_split(); init_tcl(argc, argv); init_language(0); help_init(); traffic_init(); logfile_init(1); #ifdef STATIC link_statics(); #endif strncpyz(s, ctime(&now), sizeof s); strcpy(&s[11], &s[20]); putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s); /* Read configuration data. */ readconfig(); /* Check for encryption module. */ if (!encrypt_pass) { printf(MOD_NOCRYPT); bg_send_quit(BG_ABORT); exit(1); } putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick, count_channels(), count_users(userlist)); if (!pid_file[0]) egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick); /* Check for pre-existing eggdrop! */ f = fopen(pid_file, "r"); if (f != NULL) { fgets(s, 10, f); xx = atoi(s); kill(xx, SIGCHLD); /* Meaningless kill to determine if PID is used. */ if (errno != ESRCH) { printf(EGG_RUNNING1, botnetnick); printf(EGG_RUNNING2, pid_file); bg_send_quit(BG_ABORT); exit(1); } } /* Move into background? */ if (backgrd) { #ifndef CYGWIN_HACKS bg_do_split(); } else { #endif xx = getpid(); if (xx != 0) { FILE *fp; /* Write PID to file. */ unlink(pid_file); fp = fopen(pid_file, "w"); if (fp != NULL) { fprintf(fp, "%u\n", xx); if (fflush(fp)) { /* Let the bot live since this doesn't appear to be a botchk. */ printf("Cannot not write to '%s' (PID file).\n", pid_file); fclose(fp); unlink(pid_file); } else fclose(fp); } else printf("Cannot not write to '%s' (PID file).\n", pid_file); #ifdef CYGWIN_HACKS printf("Launched into the background (PID: %d)\n\n", xx); #endif } } use_stderr = 0; /* Stop writing to stderr now */ if (backgrd) { /* Ok, try to disassociate from controlling terminal (finger cross) */ #if defined(HAVE_SETPGID) && !defined(CYGWIN_HACKS) setpgid(0, 0); #endif /* Tcl wants the stdin, stdout and stderr file handles kept open. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); #ifdef CYGWIN_HACKS FreeConsole(); #endif } /* Terminal emulating dcc chat */ if (!backgrd && term_z) { int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info)); dcc[n].addr = iptolong(getmyip()); dcc[n].sock = STDOUT; dcc[n].timeval = now; dcc[n].u.chat->con_flags = conmask; dcc[n].u.chat->strip_flags = STRIP_ALL; dcc[n].status = STAT_ECHO; strcpy(dcc[n].nick, "HQ"); strcpy(dcc[n].host, "llama@console"); /* HACK: Workaround not to pass literal "HQ" as a non-const arg */ dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); /* Make sure there's an innocuous HQ user if needed */ if (!dcc[n].user) { userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); } setsock(STDOUT, 0); /* Entry in net table */ dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n"); dcc_chatter(n); } then = now; online_since = now; autolink_cycle(NULL); /* Hurry and connect to tandem bots. */ add_help_reference("cmds1.help"); add_help_reference("cmds2.help"); add_help_reference("core.help"); /* Create hooks. */ add_hook(HOOK_SECONDLY, (Function) core_secondly); add_hook(HOOK_MINUTELY, (Function) core_minutely); add_hook(HOOK_HOURLY, (Function) core_hourly); add_hook(HOOK_REHASH, (Function) event_rehash); add_hook(HOOK_PRE_REHASH, (Function) event_prerehash); add_hook(HOOK_USERFILE, (Function) event_save); add_hook(HOOK_BACKUP, (Function) backupuserfile); add_hook(HOOK_DAILY, (Function) event_logfile); add_hook(HOOK_DAILY, (Function) traffic_reset); add_hook(HOOK_LOADED, (Function) event_loaded); call_hook(HOOK_LOADED); debug0("main: entering loop"); while (1) { int socket_cleanup = 0; #ifdef USE_TCL_EVENTS /* Process a single Tcl event. */ Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); #endif now = time(NULL); random(); /* Every second... */ if (now != then) { call_hook(HOOK_SECONDLY); then = now; } /* Only do this every so often. */ if (!socket_cleanup) { socket_cleanup = 5; /* Remove dead dcc entries. */ dcc_remove_lost(); /* Check for server or dcc activity. */ dequeue_sockets(); } else { socket_cleanup--; } /* Free unused structures. */ garbage_collect(); xx = sockgets(buf, &i); if (xx >= 0) { /* Non-error */ int idx; for (idx = 0; idx < dcc_total; idx++) { if (dcc[idx].sock != xx) continue; if (dcc[idx].type && dcc[idx].type->activity) { traffic_update_in(dcc[idx].type, (strlen(buf) + 1)); /* Traffic stats. */ dcc[idx].type->activity(idx, buf, i); } else { putlog(LOG_MISC, "*", "!!! untrapped dcc activity: type %s, sock %d", dcc[idx].type->name, dcc[idx].sock); } break; } } else if (xx == -1) { /* EOF */ int idx; if (i == STDOUT && !backgrd) fatal("END OF FILE ON TERMINAL", 0); for (idx = 0; idx < dcc_total; idx++) { if (dcc[idx].sock != i) continue; if (dcc[idx].type && dcc[idx].type->eof) { dcc[idx].type->eof(idx); } else { putlog(LOG_MISC, "*", "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED", i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*"); killsock(i); lostdcc(idx); } idx = dcc_total + 1; } if (idx == dcc_total) { putlog(LOG_MISC, "*", "(@) EOF socket %d, not a dcc socket, not anything.", i); close(i); killsock(i); } } else if (xx == -2 && errno != EINTR) { /* select() error */ putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno); for (i = 0; i < dcc_total; i++) { if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) { putlog(LOG_MISC, "*", "DCC socket %d (type %d, name '%s') expired -- pfft", dcc[i].sock, dcc[i].type, dcc[i].nick); killsock(dcc[i].sock); lostdcc(i); i--; } } } else if (xx == -3) { call_hook(HOOK_IDLE); socket_cleanup = 0; /* If we've been idle, cleanup & flush */ } if (do_restart) { if (do_restart == -2) { rehash(); } else { int f = 1; module_entry *p; Function startfunc; char name[256]; check_tcl_event("prerestart"); /* Unload as many modules as possible */ while (f) { f = 0; for (p = module_list; p != NULL; p = p->next) { dependancy *d = dependancy_list; int ok = 1; while (ok && d) { if (d->needed == p) ok = 0; d = d->next; } if (ok) { strcpy(name, p->name); if (module_unload(name, botnetnick) == NULL) { f = 1; break; } } } } /* Make sure we don't have any modules left hanging around other than * "eggdrop" and the two that are supposed to be. */ for (f = 0, p = module_list; p; p = p->next) { if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") && strcmp(p->name, "uptime")) { f++; } } if (f != 0) { putlog(LOG_MISC, "*", MOD_STAGNANT); } /* Flush log files to disk. */ flushlogs(); /* Clean up Tcl stuff. */ kill_tcl(); /* Initialize stuff again. */ init_tcl(argc, argv); init_language(0); help_init(); traffic_init(); logfile_init(1); /* This resets our modules which we didn't unload (encryption and uptime). */ for (p = module_list; p; p = p->next) { if (p->funcs) { startfunc = p->funcs[MODCALL_START]; startfunc(NULL); } } rehash(); restart_chons(); call_hook(HOOK_LOADED); } do_restart = 0; } } }