src/main.c File Reference

#include "main.h"
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <netdb.h>
#include <setjmp.h>
#include <time.h>
#include "chan.h"
#include "modules.h"
#include "tandem.h"
#include "bg.h"
#include "patch.h"
Include dependency graph for main.c:

Go to the source code of this file.

Defines

#define _POSIX_SOURCE   1
#define write_debug()   do {} while (0)

Functions

void fatal (const char *s, int recoverable)
int expmem_chanprog ()
int expmem_users ()
int expmem_misc ()
int expmem_dccutil ()
int expmem_botnet ()
int expmem_tcl ()
int expmem_tclhash ()
int expmem_net ()
int expmem_modules (int)
int expmem_language ()
int expmem_tcldcc ()
int expmem_tclmisc ()
int expected_memory (void)
static void check_expired_dcc ()
static void got_bus (int z)
static void got_segv (int z)
static void got_fpe (int z)
static void got_term (int z)
static void got_quit (int z)
static void got_hup (int z)
static void got_alarm (int z)
static void got_ill (int z)
static void do_arg (char *s)
void backup_userfile (void)
static void core_secondly ()
static void core_minutely ()
static void core_hourly ()
static void event_rehash ()
static void event_prerehash ()
static void event_save ()
static void event_logfile ()
static void event_resettraffic ()
static void event_loaded ()
void kill_tcl ()
void restart_chons ()
int init_threaddata (int)
int init_mem ()
int init_userent ()
int init_misc ()
int init_bots ()
int init_modules ()
int init_tcl (int, char **)
int init_language (int)
static void patch (const char *str)
static void garbage_collect (void)
int mainloop (int toplevel)
 return (eggbusy||tclbusy)
int main (int arg_c, char **arg_v)

Variables

char origbotname []
char userfile []
char botnetnick []
int dcc_total
int conmask
int cache_hit
int cache_miss
int max_logs
int quick_logs
int quiet_save
struct dcc_tdcc
struct userrecuserlist
struct chanset_tchanset
log_tlogs
Tcl_Interpinterp
tcl_timer_ttimer
tcl_timer_tutimer
sigjmp_buf alarmret
time_t now
static int argc
static char ** argv
char egg_version [1024] = "1.6.21"
int egg_numver = 1062100
char notify_new [121] = ""
int default_flags = 0
int default_uflags = 0
int backgrd = 1
int con_chan = 0
int term_z = 0
int use_stderr = 1
char configfile [121] = "eggdrop.conf"
char pid_file [120]
char helpdir [121] = "help/"
char textdir [121] = "text/"
int keep_all_logs = 0
char logfile_suffix [21] = ".%d%b%Y"
int switch_logfiles_at = 300
time_t online_since
int make_userfile = 0
char owner [121] = ""
int save_users_at = 0
int notify_users_at = 0
char version [81]
char ver [41]
char egg_xtra [2048]
int do_restart = 0
int die_on_sighup = 0
int die_on_sigterm = 1
int resolve_timeout = 15
char quit_msg [1024]
unsigned long otraffic_irc = 0
unsigned long otraffic_irc_today = 0
unsigned long otraffic_bn = 0
unsigned long otraffic_bn_today = 0
unsigned long otraffic_dcc = 0
unsigned long otraffic_dcc_today = 0
unsigned long otraffic_filesys = 0
unsigned long otraffic_filesys_today = 0
unsigned long otraffic_trans = 0
unsigned long otraffic_trans_today = 0
unsigned long otraffic_unknown = 0
unsigned long otraffic_unknown_today = 0
unsigned long itraffic_irc = 0
unsigned long itraffic_irc_today = 0
unsigned long itraffic_bn = 0
unsigned long itraffic_bn_today = 0
unsigned long itraffic_dcc = 0
unsigned long itraffic_dcc_today = 0
unsigned long itraffic_trans = 0
unsigned long itraffic_trans_today = 0
unsigned long itraffic_unknown = 0
unsigned long itraffic_unknown_today = 0
static int lastmin = 99
static time_t then
static struct tm nowtm
module_entrymodule_list

Define Documentation

#define _POSIX_SOURCE   1

Definition at line 72 of file main.c.

 
#define write_debug (  )     do {} while (0)

Definition at line 232 of file main.c.

Referenced by got_bus(), got_fpe(), and got_segv().


Function Documentation

void backup_userfile ( void   ) 

Definition at line 509 of file main.c.

References copyfile, egg_snprintf, LOG_MISC, putlog, quiet_save, USERF_BACKUP, and userfile.

Referenced by main().

00510 {
00511   char s[125];
00512 
00513   if (quiet_save < 2)
00514     putlog(LOG_MISC, "*", USERF_BACKUP);
00515   egg_snprintf(s, sizeof s, "%s~bak", userfile);
00516   copyfile(userfile, s);
00517 }

Here is the caller graph for this function:

static void check_expired_dcc (  )  [static]

Definition at line 213 of file main.c.

References dcc_total, dcc_table::eof, now, dcc_table::timeout, dcc_table::timeout_val, dcc_t::timeval, dcc_t::type, and chanset_t::type.

Referenced by core_secondly().

00214 {
00215   int i;
00216 
00217   for (i = 0; i < dcc_total; i++)
00218     if (dcc[i].type && dcc[i].type->timeout_val &&
00219         ((now - dcc[i].timeval) > *(dcc[i].type->timeout_val))) {
00220       if (dcc[i].type->timeout)
00221         dcc[i].type->timeout(i);
00222       else if (dcc[i].type->eof)
00223         dcc[i].type->eof(i);
00224       else
00225         continue;
00226       /* Only timeout 1 socket per cycle, too risky for more */
00227       return;
00228     }
00229 }

Here is the caller graph for this function:

static void core_hourly (  )  [static]

Definition at line 627 of file main.c.

References write_userfile.

Referenced by main().

00628 {
00629   write_userfile(-1);
00630 }

Here is the caller graph for this function:

static void core_minutely (  )  [static]

Definition at line 616 of file main.c.

References check_logsize(), check_tcl_cron(), check_tcl_time(), do_check_timers(), flushlogs(), nowtm, and quick_logs.

Referenced by main().

00617 {
00618   check_tcl_time(&nowtm);
00619   check_tcl_cron(&nowtm);
00620   do_check_timers(&timer);
00621   if (quick_logs != 0) {
00622     flushlogs();
00623     check_logsize();
00624   }
00625 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void core_secondly (  )  [static]

Definition at line 528 of file main.c.

References autolink_cycle(), backgrd, call_hook, check_botnet_pings(), check_expired_dcc(), check_expired_ignores(), check_logsize(), con_chan, debug2, do_check_timers(), do_module_report(), DP_STDOUT, dprintf, egg_memcpy(), egg_snprintf, log_t::f, flushlogs(), HOOK_5MINUTELY, HOOK_BACKUP, HOOK_DAILY, HOOK_HOURLY, HOOK_MINUTELY, keep_all_logs, LOG_ALL, LOG_MISC, max_logs, MISC_LOGSWITCH, movefile, notify_users_at, now, nowtm, NULL, putlog, quick_logs, quiet_save, strncpyz, switch_logfiles_at, tell_mem_status_dcc(), and tell_verbose_status().

Referenced by main().

00529 {
00530   static int cnt = 0;
00531   int miltime;
00532 
00533   do_check_timers(&utimer);     /* Secondly timers */
00534   cnt++;
00535   if (cnt >= 10) {              /* Every 10 seconds */
00536     cnt = 0;
00537     check_expired_dcc();
00538     if (con_chan && !backgrd) {
00539       dprintf(DP_STDOUT, "\033[2J\033[1;1H");
00540       tell_verbose_status(DP_STDOUT);
00541       do_module_report(DP_STDOUT, 0, "server");
00542       do_module_report(DP_STDOUT, 0, "channels");
00543       tell_mem_status_dcc(DP_STDOUT);
00544     }
00545   }
00546   egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
00547   if (nowtm.tm_min != lastmin) {
00548     int i = 0;
00549 
00550     /* Once a minute */
00551     lastmin = (lastmin + 1) % 60;
00552     call_hook(HOOK_MINUTELY);
00553     check_expired_ignores();
00554     autolink_cycle(NULL);       /* Attempt autolinks */
00555     /* In case for some reason more than 1 min has passed: */
00556     while (nowtm.tm_min != lastmin) {
00557       /* Timer drift, dammit */
00558       debug2("timer: drift (lastmin=%d, now=%d)", lastmin, nowtm.tm_min);
00559       i++;
00560       lastmin = (lastmin + 1) % 60;
00561       call_hook(HOOK_MINUTELY);
00562     }
00563     if (i > 1)
00564       putlog(LOG_MISC, "*", "(!) timer drift -- spun %d minutes", i);
00565     miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min);
00566     if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) {     /* 5 min */
00567       call_hook(HOOK_5MINUTELY);
00568       check_botnet_pings();
00569       if (!quick_logs) {
00570         flushlogs();
00571         check_logsize();
00572       }
00573       if (!miltime) {           /* At midnight */
00574         char s[25];
00575         int j;
00576 
00577         strncpyz(s, ctime(&now), sizeof s);
00578         if (quiet_save < 3)
00579           putlog(LOG_ALL, "*", "--- %.11s%s", s, s + 20);
00580         call_hook(HOOK_BACKUP);
00581         for (j = 0; j < max_logs; j++) {
00582           if (logs[j].filename != NULL && logs[j].f != NULL) {
00583             fclose(logs[j].f);
00584             logs[j].f = NULL;
00585           }
00586         }
00587       }
00588     }
00589     if (nowtm.tm_min == notify_users_at)
00590       call_hook(HOOK_HOURLY);
00591     /* These no longer need checking since they are all check vs minutely
00592      * settings and we only get this far on the minute.
00593      */
00594     if (miltime == switch_logfiles_at) {
00595       call_hook(HOOK_DAILY);
00596       if (!keep_all_logs) {
00597         if (quiet_save < 3)
00598           putlog(LOG_MISC, "*", MISC_LOGSWITCH);
00599         for (i = 0; i < max_logs; i++)
00600           if (logs[i].filename) {
00601             char s[1024];
00602 
00603             if (logs[i].f) {
00604               fclose(logs[i].f);
00605               logs[i].f = NULL;
00606             }
00607             egg_snprintf(s, sizeof s, "%s.yesterday", logs[i].filename);
00608             unlink(s);
00609             movefile(logs[i].filename, s);
00610           }
00611       }
00612     }
00613   }
00614 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_arg ( char *  s  )  [static]

Definition at line 463 of file main.c.

References backgrd, BG_ABORT, bg_send_quit(), con_chan, configfile, EGG_USAGE, egg_version, HANDLEN, make_userfile, newsplit, strncpyz, term_z, and version.

Referenced by main().

00464 {
00465   char x[512], *z = x;
00466   int i;
00467 
00468   if (s[0] == '-')
00469     for (i = 1; i < strlen(s); i++) {
00470       switch (s[i]) {
00471       case 'n':
00472         backgrd = 0;
00473         break;
00474       case 'c':
00475         con_chan = 1;
00476         term_z = 0;
00477         break;
00478       case 't':
00479         con_chan = 0;
00480         term_z = 1;
00481         break;
00482       case 'm':
00483         make_userfile = 1;
00484         break;
00485       case 'v':
00486         strncpyz(x, egg_version, sizeof x);
00487         newsplit(&z);
00488         newsplit(&z);
00489         printf("%s\n", version);
00490         if (z[0])
00491           printf("  (patches: %s)\n", z);
00492         printf("Configured with: " EGG_AC_ARGS "\n");
00493         printf("handlen=%d\n", HANDLEN);
00494         bg_send_quit(BG_ABORT);
00495         exit(0);
00496         break;                  /* this should never be reached */
00497       case 'h':
00498         printf("\n%s\n\n", version);
00499         printf(EGG_USAGE);
00500         printf("\n");
00501         bg_send_quit(BG_ABORT);
00502         exit(0);
00503         break;                  /* this should never be reached */
00504       }
00505     } else
00506     strncpyz(configfile, s, sizeof configfile);
00507 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void event_loaded (  )  [static]

Definition at line 671 of file main.c.

References check_tcl_event.

Referenced by main().

00672 {
00673   check_tcl_event("loaded");
00674 }

Here is the caller graph for this function:

static void event_logfile (  )  [static]

Definition at line 647 of file main.c.

References check_tcl_event.

Referenced by main().

00648 {
00649   check_tcl_event("logfile");
00650 }

Here is the caller graph for this function:

static void event_prerehash (  )  [static]

Definition at line 637 of file main.c.

References check_tcl_event.

Referenced by main().

00638 {
00639   check_tcl_event("prerehash");
00640 }

Here is the caller graph for this function:

static void event_rehash (  )  [static]

Definition at line 632 of file main.c.

References check_tcl_event.

Referenced by main().

00633 {
00634   check_tcl_event("rehash");
00635 }

Here is the caller graph for this function:

static void event_resettraffic (  )  [static]
static void event_save (  )  [static]

Definition at line 642 of file main.c.

References check_tcl_event.

Referenced by main().

00643 {
00644   check_tcl_event("save");
00645 }

Here is the caller graph for this function:

int expected_memory ( void   ) 

Definition at line 202 of file main.c.

References expmem_botnet(), expmem_chanprog(), expmem_dccutil(), expmem_language(), expmem_misc(), expmem_modules(), expmem_net(), expmem_tcl(), expmem_tcldcc(), expmem_tclhash(), expmem_tclmisc(), and expmem_users().

00203 {
00204   int tot;
00205 
00206   tot = expmem_chanprog() + expmem_users() + expmem_misc() + expmem_dccutil() +
00207         expmem_botnet() + expmem_tcl() + expmem_tclhash() + expmem_net() +
00208         expmem_modules(0) + expmem_language() + expmem_tcldcc() +
00209         expmem_tclmisc();
00210   return tot;
00211 }

Here is the call graph for this function:

int expmem_botnet (  ) 

Definition at line 49 of file botnet.c.

00050 {
00051   int size = 0, i;
00052   tand_t *bot;
00053 
00054   for (bot = tandbot; bot; bot = bot->next)
00055     size += sizeof(tand_t);
00056   size += (maxparty * sizeof(party_t));
00057   for (i = 0; i < parties; i++) {
00058     if (party[i].away)
00059       size += strlen(party[i].away) + 1;
00060     if (party[i].from)
00061       size += strlen(party[i].from) + 1;
00062   }
00063   return size;
00064 }

int expmem_chanprog (  ) 

Definition at line 216 of file chanprog.c.

00217 {
00218   register int tot = 0;
00219   register tcl_timer_t *t;
00220 
00221   for (t = timer; t; t = t->next)
00222     tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
00223   for (t = utimer; t; t = t->next)
00224     tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
00225   return tot;
00226 }

int expmem_dccutil (  ) 

Definition at line 97 of file dccutil.c.

00098 {
00099   int tot, i;
00100 
00101   tot = sizeof(struct dcc_t) * max_dcc;
00102   tot += sizeof(sock_list) * threaddata()->MAXSOCKS;
00103 
00104   for (i = 0; i < dcc_total; i++) {
00105     if (dcc[i].type && dcc[i].type->expmem)
00106       tot += dcc[i].type->expmem(dcc[i].u.other);
00107   }
00108   return tot;
00109 }

int expmem_language (  ) 

Definition at line 563 of file language.c.

00564 {
00565   lang_tab *l;
00566   lang_sec *ls;
00567   lang_pri *lp;
00568   int i, size = 0;
00569 
00570   for (i = 0; i < 64; i++)
00571     for (l = langtab[i]; l; l = l->next) {
00572       size += sizeof(lang_tab);
00573       size += (strlen(l->text) + 1);
00574     }
00575   for (ls = langsection; ls; ls = ls->next) {
00576     size += sizeof(lang_sec);
00577     if (ls->section)
00578       size += strlen(ls->section) + 1;
00579     if (ls->lang)
00580       size += strlen(ls->lang) + 1;
00581   }
00582   for (lp = langpriority; lp; lp = lp->next) {
00583     size += sizeof(lang_pri);
00584     if (lp->lang)
00585       size += strlen(lp->lang) + 1;
00586   }
00587   return size;
00588 }

int expmem_misc (  ) 

Definition at line 83 of file misc.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00084 {
00085   struct help_ref *current;
00086   struct help_list_t *item;
00087   int tot = 0;
00088 
00089   for (current = help_list; current; current = current->next) {
00090     tot += sizeof(struct help_ref) + strlen(current->name) + 1;
00091 
00092     for (item = current->first; item; item = item->next)
00093       tot += sizeof(struct help_list_t) + strlen(item->name) + 1;
00094   }
00095   return tot + (max_logs * sizeof(log_t));
00096 }

Here is the caller graph for this function:

int expmem_modules ( int   ) 

Definition at line 601 of file modules.c.

References _module_entry::funcs, MODCALL_EXPMEM, _module_entry::name, _module_entry::next, _dependancy::next, hook_entry::next, and REAL_HOOKS.

Referenced by debug_mem_to_dcc(), and expected_memory().

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 }

Here is the caller graph for this function:

int expmem_net (  ) 

Definition at line 90 of file net.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00091 {
00092   int i, tot = 0;
00093   struct threaddata *td = threaddata();
00094 
00095   for (i = 0; i < td->MAXSOCKS; i++) {
00096     if (!(td->socklist[i].flags & (SOCK_UNUSED | SOCK_TCL))) {
00097       if (td->socklist[i].handler.sock.inbuf != NULL)
00098         tot += strlen(td->socklist[i].handler.sock.inbuf) + 1;
00099       if (td->socklist[i].handler.sock.outbuf != NULL)
00100         tot += td->socklist[i].handler.sock.outbuflen;
00101     }
00102   }
00103   return tot;
00104 }

Here is the caller graph for this function:

int expmem_tcl (  ) 

Definition at line 101 of file tcl.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00102 {
00103   return strtot + utftot + clientdata_stuff;
00104 }

Here is the caller graph for this function:

int expmem_tcldcc (  ) 

Definition at line 48 of file tcldcc.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00049 {
00050   int tot = 0;
00051   struct portmap *pmap;
00052 
00053   for (pmap = root; pmap; pmap = pmap->next)
00054     tot += sizeof(struct portmap);
00055 
00056   return tot;
00057 }

Here is the caller graph for this function:

int expmem_tclhash (  ) 

Definition at line 195 of file tclhash.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00196 {
00197   int tot = 0;
00198   tcl_bind_list_t *tl;
00199 
00200   for (tl = bind_table_list; tl; tl = tl->next)
00201     tot += tcl_bind_list_expmem(tl);
00202   return tot;
00203 }

Here is the caller graph for this function:

int expmem_tclmisc (  ) 

Definition at line 59 of file tclmisc.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00060 {
00061   int i, tot = 0;
00062 
00063   for (i = 0; i < max_logs; i++) {
00064     if (logs[i].filename != NULL) {
00065       tot += strlen(logs[i].filename) + 1;
00066       tot += strlen(logs[i].chname) + 1;
00067     }
00068   }
00069 
00070   return tot;
00071 }

Here is the caller graph for this function:

int expmem_users (  ) 

Definition at line 98 of file userrec.c.

Referenced by debug_mem_to_dcc(), and expected_memory().

00099 {
00100   int tot;
00101   struct userrec *u;
00102   struct chanuserrec *ch;
00103   struct chanset_t *chan;
00104   struct user_entry *ue;
00105   struct igrec *i;
00106 
00107   tot = 0;
00108   for (u = userlist; u; u = u->next) {
00109     for (ch = u->chanrec; ch; ch = ch->next) {
00110       tot += sizeof(struct chanuserrec);
00111 
00112       if (ch->info != NULL)
00113         tot += strlen(ch->info) + 1;
00114     }
00115     tot += sizeof(struct userrec);
00116 
00117     for (ue = u->entries; ue; ue = ue->next) {
00118       tot += sizeof(struct user_entry);
00119 
00120       if (ue->name) {
00121         tot += strlen(ue->name) + 1;
00122         tot += list_type_expmem(ue->u.list);
00123       } else
00124         tot += ue->type->expmem(ue);
00125     }
00126   }
00127   /* Account for each channel's masks */
00128   for (chan = chanset; chan; chan = chan->next) {
00129 
00130     /* Account for each channel's ban-list user */
00131     tot += expmem_mask(chan->bans);
00132 
00133     /* Account for each channel's exempt-list user */
00134     tot += expmem_mask(chan->exempts);
00135 
00136     /* Account for each channel's invite-list user */
00137     tot += expmem_mask(chan->invites);
00138   }
00139 
00140   tot += expmem_mask(global_bans);
00141   tot += expmem_mask(global_exempts);
00142   tot += expmem_mask(global_invites);
00143 
00144   for (i = global_ign; i; i = i->next) {
00145     tot += sizeof(struct igrec);
00146 
00147     tot += strlen(i->igmask) + 1;
00148     if (i->user)
00149       tot += strlen(i->user) + 1;
00150     if (i->msg)
00151       tot += strlen(i->msg) + 1;
00152   }
00153   return tot;
00154 }

Here is the caller graph for this function:

void fatal ( const char *  s,
int  recoverable 
)

Definition at line 171 of file main.c.

References BG_ABORT, bg_send_quit(), dcc_total, flushlogs(), killsock, LOG_MISC, pid_file, and putlog.

00172 {
00173   int i;
00174 
00175   putlog(LOG_MISC, "*", "* %s", s);
00176   flushlogs();
00177   for (i = 0; i < dcc_total; i++)
00178     if (dcc[i].sock >= 0)
00179       killsock(dcc[i].sock);
00180   unlink(pid_file);
00181   if (!recoverable) {
00182     bg_send_quit(BG_ABORT);
00183     exit(1);
00184   }
00185 }

Here is the call graph for this function:

static void garbage_collect ( void   )  [inline, static]

Definition at line 705 of file main.c.

References garbage_collect_tclhash().

Referenced by mainloop().

00706 {
00707   static u_8bit_t run_cnt = 0;
00708 
00709   if (run_cnt == 3)
00710     garbage_collect_tclhash();
00711   else
00712     run_cnt++;
00713 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void got_alarm ( int  z  )  [static]

Definition at line 394 of file main.c.

References alarmret.

Referenced by main().

00395 {
00396   siglongjmp(alarmret, 1);
00397 
00398   /* -Never reached- */
00399 }

Here is the caller graph for this function:

static void got_bus ( int  z  )  [static]

Definition at line 332 of file main.c.

References BG_ABORT, bg_send_quit(), fatal, and write_debug.

Referenced by main().

00333 {
00334   write_debug();
00335   fatal("BUS ERROR -- CRASHING!", 1);
00336 #ifdef SA_RESETHAND
00337   kill(getpid(), SIGBUS);
00338 #else
00339   bg_send_quit(BG_ABORT);
00340   exit(1);
00341 #endif
00342 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void got_fpe ( int  z  )  [static]

Definition at line 356 of file main.c.

References fatal, and write_debug.

Referenced by main().

00357 {
00358   write_debug();
00359   fatal("FLOATING POINT ERROR -- CRASHING!", 0);
00360 }

Here is the caller graph for this function:

static void got_hup ( int  z  )  [static]

Definition at line 380 of file main.c.

References check_tcl_event, die_on_sighup, do_restart, fatal, LOG_MISC, putlog, and write_userfile.

Referenced by main().

00381 {
00382   write_userfile(-1);
00383   check_tcl_event("sighup");
00384   if (die_on_sighup) {
00385     fatal("HANGUP SIGNAL -- SIGNING OFF", 0);
00386   } else
00387     putlog(LOG_MISC, "*", "Received HUP signal: rehashing...");
00388   do_restart = -2;
00389   return;
00390 }

Here is the caller graph for this function:

static void got_ill ( int  z  )  [static]

Definition at line 403 of file main.c.

References check_tcl_event, LOG_MISC, and putlog.

Referenced by main().

00404 {
00405   check_tcl_event("sigill");
00406 #ifdef DEBUG_CONTEXT
00407   putlog(LOG_MISC, "*", "* Context: %s/%d [%s]", cx_file[cx_ptr],
00408          cx_line[cx_ptr], (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
00409 #endif
00410 }

Here is the caller graph for this function:

static void got_quit ( int  z  )  [static]

Definition at line 373 of file main.c.

References check_tcl_event, LOG_MISC, and putlog.

Referenced by main().

00374 {
00375   check_tcl_event("sigquit");
00376   putlog(LOG_MISC, "*", "RECEIVED QUIT SIGNAL (IGNORING)");
00377   return;
00378 }

Here is the caller graph for this function:

static void got_segv ( int  z  )  [static]

Definition at line 344 of file main.c.

References BG_ABORT, bg_send_quit(), fatal, and write_debug.

Referenced by main().

00345 {
00346   write_debug();
00347   fatal("SEGMENT VIOLATION -- CRASHING!", 1);
00348 #ifdef SA_RESETHAND
00349   kill(getpid(), SIGSEGV);
00350 #else
00351   bg_send_quit(BG_ABORT);
00352   exit(1);
00353 #endif
00354 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void got_term ( int  z  )  [static]

Definition at line 362 of file main.c.

References botnet_send_chat, botnetnick, check_tcl_event, die_on_sigterm, fatal, LOG_MISC, putlog, and write_userfile.

Referenced by main().

00363 {
00364   write_userfile(-1);
00365   check_tcl_event("sigterm");
00366   if (die_on_sigterm) {
00367     botnet_send_chat(-1, botnetnick, "ACK, I've been terminated!");
00368     fatal("TERMINATE SIGNAL -- SIGNING OFF", 0);
00369   } else
00370     putlog(LOG_MISC, "*", "RECEIVED TERMINATE SIGNAL (IGNORING)");
00371 }

Here is the caller graph for this function:

int init_bots (  ) 

Definition at line 66 of file botnet.c.

References maxparty, nmalloc, and NULL.

Referenced by main().

00067 {
00068   tandbot = NULL;
00069   /* Grab space for 50 bots for now -- expand later as needed */
00070   maxparty = 50;
00071   party = nmalloc(maxparty * sizeof(*party));
00072 }

Here is the caller graph for this function:

int init_language ( int   ) 

Definition at line 734 of file language.c.

References add_builtins, add_lang(), add_lang_section, add_tcl_commands, BASELANG, and H_dcc.

Referenced by main(), and mainloop().

00735 {
00736   int i;
00737   char *deflang;
00738 
00739   if (flag) {
00740     for (i = 0; i < 32; i++)
00741       langtab[i] = 0;
00742     /* The default language is always BASELANG as language files are
00743      * gauranteed to exist in that language.
00744      */
00745     add_lang(BASELANG);
00746     /* Let the user choose a different, preferred language */
00747     deflang = getenv("EGG_LANG");
00748     if (deflang)
00749       add_lang(deflang);
00750     add_lang_section("core");
00751   } else {
00752     add_tcl_commands(langtcls);
00753     add_builtins(H_dcc, langdcc);
00754   }
00755 }

Here is the call graph for this function:

Here is the caller graph for this function:

int init_mem (  ) 

Definition at line 73 of file mem.c.

References MEMTBLSIZE, and NULL.

Referenced by main().

00074 {
00075 #ifdef DEBUG_MEM
00076   int i;
00077 
00078   for (i = 0; i < MEMTBLSIZE; i++)
00079     memtbl[i].ptr = NULL;
00080 #endif
00081 }

Here is the caller graph for this function:

int init_misc (  ) 

Definition at line 98 of file misc.c.

Referenced by main(), and tcl_eggint().

00099 {
00100   static int last = 0;
00101 
00102   if (max_logs < 1)
00103     max_logs = 1;
00104   if (logs)
00105     logs = nrealloc(logs, max_logs * sizeof(log_t));
00106   else
00107     logs = nmalloc(max_logs * sizeof(log_t));
00108   for (; last < max_logs; last++) {
00109     logs[last].filename = logs[last].chname = NULL;
00110     logs[last].mask = 0;
00111     logs[last].f = NULL;
00112     /* Added by cybah  */
00113     logs[last].szlast[0] = 0;
00114     logs[last].repeats = 0;
00115     /* Added by rtc  */
00116     logs[last].flags = 0;
00117   }
00118 }

Here is the caller graph for this function:

int init_modules (  ) 

Definition at line 583 of file modules.c.

References egg_numver, _module_entry::funcs, _module_entry::major, _module_entry::minor, _module_entry::name, _module_entry::next, nmalloc, NULL, and REAL_HOOKS.

Referenced by main().

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 }

Here is the caller graph for this function:

int init_tcl ( int  ,
char **   
)

Definition at line 757 of file tcl.c.

References add_tcl_commands, egg_bzero, egg_version, LocaleTable::encoding, init_bind(), init_traces(), interp, LocaleTable::lang, localeTable, NULL, and Tcl_CreateInterp().

Referenced by main(), and mainloop().

00758 {
00759 #ifdef REPLACE_NOTIFIER
00760   Tcl_NotifierProcs notifierprocs;
00761 #endif /* REPLACE_NOTIFIER */
00762 
00763 #ifdef USE_TCL_ENCODING
00764   const char *encoding;
00765   int i;
00766   char *langEnv;
00767 #endif /* USE_TCL_ENCODING */
00768 #ifdef USE_TCL_PACKAGE
00769   int j;
00770   char pver[1024] = "";
00771 #endif /* USE_TCL_PACKAGE */
00772 
00773 #ifdef REPLACE_NOTIFIER
00774   egg_bzero(&notifierprocs, sizeof(notifierprocs));
00775   notifierprocs.initNotifierProc = tickle_InitNotifier;
00776   notifierprocs.createFileHandlerProc = tickle_CreateFileHandler;
00777   notifierprocs.deleteFileHandlerProc = tickle_DeleteFileHandler;
00778   notifierprocs.setTimerProc = tickle_SetTimer;
00779   notifierprocs.waitForEventProc = tickle_WaitForEvent;
00780   notifierprocs.finalizeNotifierProc = tickle_FinalizeNotifier;
00781 
00782   Tcl_SetNotifier(&notifierprocs);
00783 #endif /* REPLACE_NOTIFIER */
00784 
00785 /* This must be done *BEFORE* Tcl_SetSystemEncoding(),
00786  * or Tcl_SetSystemEncoding() will cause a segfault.
00787  */
00788 #ifdef USE_TCL_FINDEXEC
00789   /* This is used for 'info nameofexecutable'.
00790    * The filename in argv[0] must exist in a directory listed in
00791    * the environment variable PATH for it to register anything.
00792    */
00793   Tcl_FindExecutable(argv[0]);
00794 #endif /* USE_TCL_FINDEXEC */
00795 
00796   /* Initialize the interpreter */
00797   interp = Tcl_CreateInterp();
00798 
00799 #ifdef DEBUG_MEM
00800   /* Initialize Tcl's memory debugging if we want it */
00801   Tcl_InitMemory(interp);
00802 #endif
00803 
00804   /* Set Tcl variable tcl_interactive to 0 */
00805   Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
00806 
00807   /* Setup script library facility */
00808   Tcl_Init(interp);
00809   Tcl_SetServiceMode(TCL_SERVICE_ALL);
00810 
00811 /* Code based on Tcl's TclpSetInitialEncodings() */
00812 #ifdef USE_TCL_ENCODING
00813   /* Determine the current encoding from the LC_* or LANG environment
00814    * variables.
00815    */
00816   langEnv = getenv("LC_ALL");
00817   if (langEnv == NULL || langEnv[0] == '\0') {
00818     langEnv = getenv("LC_CTYPE");
00819   }
00820   if (langEnv == NULL || langEnv[0] == '\0') {
00821     langEnv = getenv("LANG");
00822   }
00823   if (langEnv == NULL || langEnv[0] == '\0') {
00824     langEnv = NULL;
00825   }
00826 
00827   encoding = NULL;
00828   if (langEnv != NULL) {
00829     for (i = 0; localeTable[i].lang != NULL; i++)
00830       if (strcmp(localeTable[i].lang, langEnv) == 0) {
00831         encoding = localeTable[i].encoding;
00832         break;
00833       }
00834 
00835     /* There was no mapping in the locale table.  If there is an
00836      * encoding subfield, we can try to guess from that.
00837      */
00838     if (encoding == NULL) {
00839       char *p;
00840 
00841       for (p = langEnv; *p != '\0'; p++) {
00842         if (*p == '.') {
00843           p++;
00844           break;
00845         }
00846       }
00847       if (*p != '\0') {
00848         Tcl_DString ds;
00849 
00850         Tcl_DStringInit(&ds);
00851         Tcl_DStringAppend(&ds, p, -1);
00852 
00853         encoding = Tcl_DStringValue(&ds);
00854         Tcl_UtfToLower(Tcl_DStringValue(&ds));
00855         if (Tcl_SetSystemEncoding(NULL, encoding) == TCL_OK) {
00856           Tcl_DStringFree(&ds);
00857           goto resetPath;
00858         }
00859         Tcl_DStringFree(&ds);
00860         encoding = NULL;
00861       }
00862     }
00863   }
00864 
00865   if (encoding == NULL) {
00866     //encoding = "iso8859-1";
00867     encoding = "utf-8";
00868   }
00869 
00870   Tcl_SetSystemEncoding(NULL, encoding);
00871 
00872 resetPath:
00873 
00874   /* Initialize the C library's locale subsystem. */
00875   setlocale(LC_CTYPE, "");
00876 
00877   /* In case the initial locale is not "C", ensure that the numeric
00878    * processing is done in "C" locale regardless. */
00879   setlocale(LC_NUMERIC, "C");
00880 
00881   /* Keep the iso8859-1 encoding preloaded.  The IO package uses it for
00882    * gets on a binary channel. */
00883   Tcl_GetEncoding(NULL, "iso8859-1");
00884 #endif /* USE_TCL_ENCODING */
00885 
00886 #ifdef USE_TCL_PACKAGE
00887   /* Add eggdrop to Tcl's package list */
00888   for (j = 0; j <= strlen(egg_version); j++) {
00889     if ((egg_version[j] == ' ') || (egg_version[j] == '+'))
00890       break;
00891     pver[strlen(pver)] = egg_version[j];
00892   }
00893   Tcl_PkgProvide(interp, "eggdrop", pver);
00894 #endif /* USE_TCL_PACKAGE */
00895 
00896   /* Initialize binds and traces */
00897   init_bind();
00898   init_traces();
00899 
00900   /* Add new commands */
00901   add_tcl_commands(tcluser_cmds);
00902   add_tcl_commands(tcldcc_cmds);
00903   add_tcl_commands(tclmisc_cmds);
00904 #ifdef USE_TCL_OBJ
00905   add_tcl_objcommands(tclmisc_objcmds);
00906 #endif
00907   add_tcl_commands(tcldns_cmds);
00908 }

Here is the call graph for this function:

Here is the caller graph for this function:

int init_threaddata ( int   ) 

Definition at line 735 of file tcl.c.

Referenced by main().

00736 {
00737   struct threaddata *td = threaddata();
00738 /* Nested evaluation (vwait/update) of the event loop only
00739  * processes Tcl events (after/fileevent) for now. Using
00740  * eggdrops mainloop() requires caution regarding reentrance.
00741  * (check_tcl_* -> Tcl_Eval() -> mainloop() -> check_tcl_* etc.)
00742  */
00743 /* td->mainloopfunc = mainthread ? mainloop : tclthreadmainloop; */
00744   td->mainloopfunc = tclthreadmainloop;
00745   td->socklist = NULL;
00746   td->mainthread = mainthread;
00747   td->blocktime.tv_sec = 1;
00748   td->blocktime.tv_usec = 0;
00749   td->MAXSOCKS = 0;
00750   increase_socks_max();
00751   return 0;
00752 }

Here is the caller graph for this function:

int init_userent (  ) 
void kill_tcl (  ) 

Definition at line 910 of file tcl.c.

References interp, kill_bind(), nfree, rem_tcl_coups, rem_tcl_ints, and rem_tcl_strings.

Referenced by mainloop().

00911 {
00912 #ifdef REPLACE_NOTIFIER
00913   tclevent_t *ne, *e = tclevents;
00914 
00915   while (e) {
00916     ne = e->next;
00917     e->callback(e->context, e->script, -1, "", 1);
00918     nfree(e);
00919     e = ne;
00920   }
00921 #endif
00922   rem_tcl_coups(def_tcl_coups);
00923   rem_tcl_strings(def_tcl_strings);
00924   rem_tcl_ints(def_tcl_ints);
00925   kill_bind();
00926   Tcl_DeleteInterp(interp);
00927 }

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  arg_c,
char **  arg_v 
)

Definition at line 939 of file main.c.

References add_help_reference, add_hook, dcc_t::addr, adduser, argc, argv, autolink_cycle(), backgrd, backup_userfile(), BG_ABORT, bg_do_split(), bg_prepare_split(), bg_send_quit(), botnetnick, cache_hit, cache_miss, call_hook, chanprog(), dcc_t::chat, chat_info::con_flags, conmask, Context, core_hourly(), core_minutely(), core_secondly(), count_users, DCC_CHAT, dcc_chatter(), debug0, do_arg(), dprintf, egg_memcpy(), EGG_NOWRITE, egg_numver, EGG_RUNNING1, EGG_RUNNING2, egg_snprintf, egg_version, egg_xtra, encrypt_pass, event_loaded(), event_logfile(), event_prerehash(), event_rehash(), event_resettraffic(), event_save(), fatal, get_user_by_handle, getmyip, got_alarm(), got_bus(), got_fpe(), got_hup(), got_ill(), got_quit(), got_segv(), got_term(), HOOK_BACKUP, HOOK_DAILY, HOOK_HOURLY, HOOK_LOADED, HOOK_MINUTELY, HOOK_PRE_REHASH, HOOK_REHASH, HOOK_SECONDLY, HOOK_USERFILE, init_bots(), init_language(), init_mem(), init_misc(), init_modules(), init_tcl(), init_threaddata(), init_userent(), iptolong, LOG_ALL, LOG_MISC, mainloop(), MOD_NOCRYPT, new_dcc, chanset_t::next, now, nowtm, NULL, online_since, pid_file, putlog, setsock(), sigaction, sigemptyset, dcc_t::sock, STAT_ECHO, dcc_t::status, STDOUT, STRIP_ALL, chat_info::strip_flags, strncpyz, term_z, dcc_t::timeval, dcc_t::u, use_stderr, user, dcc_t::user, USER_PARTY, ver, and version.

00940 {
00941   int i, xx;
00942   char s[25];
00943   FILE *f;
00944   struct sigaction sv;
00945   struct chanset_t *chan;
00946 #ifdef DEBUG
00947   struct rlimit cdlim;
00948 #endif
00949 #ifdef STOP_UAC
00950   int nvpair[2];
00951 #endif
00952 
00953 /* Make sure it can write core, if you make debug. Else it's pretty
00954  * useless (dw)
00955  *
00956  * Only allow unlimited size core files when compiled with DEBUG defined.
00957  * This is not a good idea for normal builds -- in these cases, use the
00958  * default system resource limits instead.
00959  */
00960 #ifdef DEBUG
00961   cdlim.rlim_cur = RLIM_INFINITY;
00962   cdlim.rlim_max = RLIM_INFINITY;
00963   setrlimit(RLIMIT_CORE, &cdlim);
00964 #endif
00965 
00966 #ifdef DEBUG_CONTEXT
00967   /* Initialise context list */
00968   for (i = 0; i < 16; i++)
00969     Context;
00970 #endif
00971 
00972 /* Include patch.h header for patch("...") */
00973 #include "patch.h"
00974 
00975   argc = arg_c;
00976   argv = arg_v;
00977 
00978   /* Version info! */
00979   egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version);
00980   egg_snprintf(version, sizeof version,
00981                "Eggdrop v%s (C) 1997 Robey Pointer (C) 2011 Eggheads",
00982                egg_version);
00983   /* Now add on the patchlevel (for Tcl) */
00984   sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
00985   strcat(egg_version, egg_xtra);
00986 
00987 /* For OSF/1 */
00988 #ifdef STOP_UAC
00989   /* Don't print "unaligned access fixup" warning to the user */
00990   nvpair[0] = SSIN_UACPROC;
00991   nvpair[1] = UAC_NOPRINT;
00992   setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
00993 #endif
00994 
00995   /* Set up error traps: */
00996   sv.sa_handler = got_bus;
00997   sigemptyset(&sv.sa_mask);
00998 #ifdef SA_RESETHAND
00999   sv.sa_flags = SA_RESETHAND;
01000 #else
01001   sv.sa_flags = 0;
01002 #endif
01003   sigaction(SIGBUS, &sv, NULL);
01004   sv.sa_handler = got_segv;
01005   sigaction(SIGSEGV, &sv, NULL);
01006 #ifdef SA_RESETHAND
01007   sv.sa_flags = 0;
01008 #endif
01009   sv.sa_handler = got_fpe;
01010   sigaction(SIGFPE, &sv, NULL);
01011   sv.sa_handler = got_term;
01012   sigaction(SIGTERM, &sv, NULL);
01013   sv.sa_handler = got_hup;
01014   sigaction(SIGHUP, &sv, NULL);
01015   sv.sa_handler = got_quit;
01016   sigaction(SIGQUIT, &sv, NULL);
01017   sv.sa_handler = SIG_IGN;
01018   sigaction(SIGPIPE, &sv, NULL);
01019   sv.sa_handler = got_ill;
01020   sigaction(SIGILL, &sv, NULL);
01021   sv.sa_handler = got_alarm;
01022   sigaction(SIGALRM, &sv, NULL);
01023 
01024   /* Initialize variables and stuff */
01025   now = time(NULL);
01026   chanset = NULL;
01027   egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
01028   lastmin = nowtm.tm_min;
01029   srandom((unsigned int) (now % (getpid() + getppid())));
01030   init_mem();
01031   init_language(1);
01032   if (argc > 1)
01033     for (i = 1; i < argc; i++)
01034       do_arg(argv[i]);
01035 
01036   printf("\n%s\n", version);
01037 
01038 #ifndef CYGWIN_HACKS
01039   /* Don't allow eggdrop to run as root
01040    * This check isn't useful under cygwin and has been
01041    * reported to cause trouble in some situations.
01042    */
01043   if (((int) getuid() == 0) || ((int) geteuid() == 0))
01044     fatal("ERROR: Eggdrop will not run as root!", 0);
01045 #endif
01046 
01047 #ifndef REPLACE_NOTIFIER
01048   init_threaddata(1);
01049 #endif
01050   init_userent();
01051   init_misc();
01052   init_bots();
01053   init_modules();
01054   if (backgrd)
01055     bg_prepare_split();
01056   init_tcl(argc, argv);
01057   init_language(0);
01058 #ifdef STATIC
01059   link_statics();
01060 #endif
01061   strncpyz(s, ctime(&now), sizeof s);
01062   strcpy(&s[11], &s[20]);
01063   putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s);
01064   chanprog();
01065   if (!encrypt_pass) {
01066     printf(MOD_NOCRYPT);
01067     bg_send_quit(BG_ABORT);
01068     exit(1);
01069   }
01070   i = 0;
01071   for (chan = chanset; chan; chan = chan->next)
01072     i++;
01073   putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.",
01074          botnetnick, i, count_users(userlist));
01075   cache_miss = 0;
01076   cache_hit = 0;
01077   if (!pid_file[0])
01078     egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick);
01079 
01080   /* Check for pre-existing eggdrop! */
01081   f = fopen(pid_file, "r");
01082   if (f != NULL) {
01083     fgets(s, 10, f);
01084     xx = atoi(s);
01085     i = kill(xx, SIGCHLD);      /* Meaningless kill to determine if pid
01086                                  * is used */
01087     if (i == 0 || errno != ESRCH) {
01088       printf(EGG_RUNNING1, botnetnick);
01089       printf(EGG_RUNNING2, pid_file);
01090       bg_send_quit(BG_ABORT);
01091       exit(1);
01092     }
01093   }
01094 
01095   /* Move into background? */
01096   if (backgrd) {
01097     bg_do_split();
01098   } else {                        /* !backgrd */
01099     xx = getpid();
01100     if (xx != 0) {
01101       FILE *fp;
01102 
01103       /* Write pid to file */
01104       unlink(pid_file);
01105       fp = fopen(pid_file, "w");
01106       if (fp != NULL) {
01107         fprintf(fp, "%u\n", xx);
01108         if (fflush(fp)) {
01109           /* Let the bot live since this doesn't appear to be a botchk */
01110           printf(EGG_NOWRITE, pid_file);
01111           fclose(fp);
01112           unlink(pid_file);
01113         } else
01114           fclose(fp);
01115       } else
01116         printf(EGG_NOWRITE, pid_file);
01117     }
01118   }
01119 
01120   use_stderr = 0;               /* Stop writing to stderr now */
01121   if (backgrd) {
01122     /* Ok, try to disassociate from controlling terminal (finger cross) */
01123 #ifdef HAVE_SETPGID
01124     setpgid(0, 0);
01125 #endif
01126     /* Tcl wants the stdin, stdout and stderr file handles kept open. */
01127     freopen("/dev/null", "r", stdin);
01128     freopen("/dev/null", "w", stdout);
01129     freopen("/dev/null", "w", stderr);
01130 #ifdef CYGWIN_HACKS
01131     FreeConsole();
01132 #endif
01133   }
01134 
01135   /* Terminal emulating dcc chat */
01136   if (!backgrd && term_z) {
01137     int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
01138 
01139     dcc[n].addr = iptolong(getmyip());
01140     dcc[n].sock = STDOUT;
01141     dcc[n].timeval = now;
01142     dcc[n].u.chat->con_flags = conmask;
01143     dcc[n].u.chat->strip_flags = STRIP_ALL;
01144     dcc[n].status = STAT_ECHO;
01145     strcpy(dcc[n].nick, "HQ");
01146     strcpy(dcc[n].host, "llama@console");
01147     /* HACK: Workaround not to pass literal "HQ" as a non-const arg */
01148     dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
01149     /* Make sure there's an innocuous HQ user if needed */
01150     if (!dcc[n].user) {
01151       userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY);
01152       dcc[n].user = get_user_by_handle(userlist, dcc[n].nick);
01153     }
01154     setsock(STDOUT, 0);          /* Entry in net table */
01155     dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
01156     dcc_chatter(n);
01157   }
01158 
01159   then = now;
01160   online_since = now;
01161   autolink_cycle(NULL);         /* Hurry and connect to tandem bots */
01162   add_help_reference("cmds1.help");
01163   add_help_reference("cmds2.help");
01164   add_help_reference("core.help");
01165   add_hook(HOOK_SECONDLY, (Function) core_secondly);
01166   add_hook(HOOK_MINUTELY, (Function) core_minutely);
01167   add_hook(HOOK_HOURLY, (Function) core_hourly);
01168   add_hook(HOOK_REHASH, (Function) event_rehash);
01169   add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
01170   add_hook(HOOK_USERFILE, (Function) event_save);
01171   add_hook(HOOK_BACKUP, (Function) backup_userfile);
01172   add_hook(HOOK_DAILY, (Function) event_logfile);
01173   add_hook(HOOK_DAILY, (Function) event_resettraffic);
01174   add_hook(HOOK_LOADED, (Function) event_loaded);
01175 
01176   call_hook(HOOK_LOADED);
01177 
01178   debug0("main: entering loop");
01179   while (1) {
01180     mainloop(1);
01181   }
01182 }

Here is the call graph for this function:

int mainloop ( int  toplevel  ) 

Definition at line 715 of file main.c.

References dcc_table::activity, argc, argv, backgrd, botnetnick, call_hook, check_tcl_event, dcc_remove_lost(), dcc_total, dependancy_list, dequeue_sockets(), do_restart, do_tcl_sync(), e, dcc_table::eof, fatal, flushlogs(), _module_entry::funcs, garbage_collect(), HOOK_IDLE, HOOK_LOADED, HOOK_SECONDLY, init_language(), init_tcl(), itraffic_bn_today, itraffic_dcc_today, itraffic_irc_today, itraffic_trans_today, itraffic_unknown_today, kill_tcl(), killsock, LOG_MISC, lostdcc, MOD_STAGNANT, MODCALL_START, module_unload, _module_entry::name, _dependancy::needed, user_entry::next, _dependancy::next, _module_entry::next, nfree, now, NULL, putlog, rehash(), restart_chons(), dcc_t::sock, sockgets(), STDOUT, and dcc_t::type.

Referenced by main().

00716 {
00717   static int socket_cleanup = 0;
00718   int xx, i, eggbusy = 1, tclbusy = 0, old_do_restart;
00719   char buf[520];
00720 
00721   /* Lets move some of this here, reducing the numer of actual
00722    * calls to periodic_timers
00723    */
00724   now = time(NULL);
00725   /*
00726    * FIXME: Get rid of this, it's ugly and wastes lots of cpu.
00727    *
00728    * pre-1.3.0 Eggdrop had random() in the once a second block below.
00729    *
00730    * This attempts to keep random() more random by constantly
00731    * calling random() and updating the state information.
00732    */
00733   random();                /* Woop, lets really jumble things */
00734 
00735   /* If we want to restart, we have to unwind to the toplevel.
00736    * Tcl will Panic if we kill the interp with Tcl_Eval in progress.
00737    * This is done by returning -1 in tickle_WaitForEvent.
00738    */
00739   if (do_restart && do_restart != -2 && !toplevel)
00740     return -1;
00741 
00742   /* Once a second */
00743   if (now != then) {
00744     call_hook(HOOK_SECONDLY);
00745     then = now;
00746   }
00747 
00748   /* Only do this every so often. */
00749   if (!socket_cleanup) {
00750     socket_cleanup = 5;
00751 
00752     /* Remove dead dcc entries. */
00753     dcc_remove_lost();
00754 
00755     /* Check for server or dcc activity. */
00756     dequeue_sockets();
00757   } else
00758     socket_cleanup--;
00759 
00760   /* Free deleted binds, only if not recursing. */
00761   if (toplevel)
00762     garbage_collect();
00763 
00764   xx = sockgets(buf, &i);
00765   if (xx >= 0) {              /* Non-error */
00766     int idx;
00767 
00768     for (idx = 0; idx < dcc_total; idx++)
00769       if (dcc[idx].sock == xx) {
00770         if (dcc[idx].type && dcc[idx].type->activity) {
00771           /* Traffic stats */
00772           if (dcc[idx].type->name) {
00773             if (!strncmp(dcc[idx].type->name, "BOT", 3))
00774               itraffic_bn_today += strlen(buf) + 1;
00775             else if (!strcmp(dcc[idx].type->name, "SERVER"))
00776               itraffic_irc_today += strlen(buf) + 1;
00777             else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
00778               itraffic_dcc_today += strlen(buf) + 1;
00779             else if (!strncmp(dcc[idx].type->name, "FILES", 5))
00780               itraffic_dcc_today += strlen(buf) + 1;
00781             else if (!strcmp(dcc[idx].type->name, "SEND"))
00782               itraffic_trans_today += strlen(buf) + 1;
00783             else if (!strncmp(dcc[idx].type->name, "GET", 3))
00784               itraffic_trans_today += strlen(buf) + 1;
00785             else
00786               itraffic_unknown_today += strlen(buf) + 1;
00787           }
00788           dcc[idx].type->activity(idx, buf, i);
00789         } else
00790           putlog(LOG_MISC, "*",
00791                  "!!! untrapped dcc activity: type %s, sock %d",
00792                  dcc[idx].type->name, dcc[idx].sock);
00793         break;
00794       }
00795   } else if (xx == -1) {        /* EOF from someone */
00796     int idx;
00797 
00798     if (i == STDOUT && !backgrd)
00799       fatal("END OF FILE ON TERMINAL", 0);
00800     for (idx = 0; idx < dcc_total; idx++)
00801       if (dcc[idx].sock == i) {
00802         if (dcc[idx].type && dcc[idx].type->eof)
00803           dcc[idx].type->eof(idx);
00804         else {
00805           putlog(LOG_MISC, "*",
00806                  "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
00807                  i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
00808           killsock(i);
00809           lostdcc(idx);
00810         }
00811         idx = dcc_total + 1;
00812       }
00813     if (idx == dcc_total) {
00814       putlog(LOG_MISC, "*",
00815              "(@) EOF socket %d, not a dcc socket, not anything.", i);
00816       close(i);
00817       killsock(i);
00818     }
00819   } else if (xx == -2 && errno != EINTR) {      /* select() error */
00820     putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
00821     for (i = 0; i < dcc_total; i++) {
00822       if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) {
00823         putlog(LOG_MISC, "*",
00824                "DCC socket %d (type %d, name '%s') expired -- pfft",
00825                dcc[i].sock, dcc[i].type, dcc[i].nick);
00826         killsock(dcc[i].sock);
00827         lostdcc(i);
00828         i--;
00829       }
00830     }
00831   } else if (xx == -3) {
00832     call_hook(HOOK_IDLE);
00833     socket_cleanup = 0;       /* If we've been idle, cleanup & flush */
00834     eggbusy = 0;
00835   } else if (xx == -5) {
00836     eggbusy = 0;
00837     tclbusy = 1;
00838   }
00839 
00840 /* restart/rehash is performed here, reset do_restart ASAP to prevent
00841  * doing it again if rehash() recurses in Tcl_Eval() */
00842   if (do_restart) {
00843     old_do_restart = do_restart;
00844     do_restart = 0;
00845     if (old_do_restart == -2)
00846       rehash();
00847     else if (!toplevel)
00848       return -1; /* Unwind to toplevel before restarting */
00849     else {
00850       /* Unload as many modules as possible */
00851       int f = 1;
00852       module_entry *p;
00853       Function startfunc;
00854       char name[256];
00855 
00856       /* oops, I guess we should call this event before tcl is restarted */
00857       check_tcl_event("prerestart");
00858 
00859       while (f) {
00860         f = 0;
00861         for (p = module_list; p != NULL; p = p->next) {
00862           dependancy *d = dependancy_list;
00863           int ok = 1;
00864 
00865           while (ok && d) {
00866             if (d->needed == p)
00867               ok = 0;
00868             d = d->next;
00869           }
00870           if (ok) {
00871             strcpy(name, p->name);
00872             if (module_unload(name, botnetnick) == NULL) {
00873               f = 1;
00874               break;
00875             }
00876           }
00877         }
00878       }
00879 
00880       /* Make sure we don't have any modules left hanging around other than
00881        * "eggdrop" and the two that are supposed to be.
00882        */
00883       for (f = 0, p = module_list; p; p = p->next) {
00884         if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") &&
00885             strcmp(p->name, "uptime")) {
00886           f++;
00887         }
00888       }
00889       if (f != 0) {
00890         putlog(LOG_MISC, "*", MOD_STAGNANT);
00891       }
00892 
00893       flushlogs();
00894       kill_tcl();
00895       init_tcl(argc, argv);
00896       init_language(0);
00897 
00898       /* this resets our modules which we didn't unload (encryption and uptime) */
00899       for (p = module_list; p; p = p->next) {
00900         if (p->funcs) {
00901           startfunc = p->funcs[MODCALL_START];
00902           startfunc(NULL);
00903         }
00904       }
00905 
00906       rehash();
00907       restart_chons();
00908       call_hook(HOOK_LOADED);
00909     }
00910     eggbusy = 1;
00911   }
00912 
00913 #ifdef USE_TCL_EVENTS
00914   if (!eggbusy) {
00915 /* Process all pending tcl events */
00916 
00917 #  ifdef REPLACE_NOTIFIER
00918     tclevent_t *e;
00919     if (Tcl_ServiceAll())
00920       tclbusy = 1;
00921     while (tclevents) {
00922       e = tclevents;
00923       tclevents = tclevents->next;
00924       tclbusy = 1;
00925       do_tcl_sync(e->context, e->script, e->callback, 1);
00926       nfree(e);
00927     }
00928 #  else
00929     while (Tcl_DoOneEvent(TCL_DONT_WAIT | TCL_ALL_EVENTS))
00930       tclbusy = 1;
00931 #  endif /* REPLACE_NOTIFIER */
00932 
00933 #endif   /* USE_TCL_EVENTS   */
00934   }

Here is the call graph for this function:

Here is the caller graph for this function:

static void patch ( const char *  str  )  [static]

Definition at line 694 of file main.c.

References egg_numver, egg_version, and egg_xtra.

00695 {
00696   char *p = strchr(egg_version, '+');
00697 
00698   if (!p)
00699     p = &egg_version[strlen(egg_version)];
00700   sprintf(p, "+%s", str);
00701   egg_numver++;
00702   sprintf(&egg_xtra[strlen(egg_xtra)], " %s", str);
00703 }

void restart_chons (  ) 

Definition at line 1677 of file botnet.c.

References botnetnick, chat_info::channel, dcc_t::chat, check_tcl_chjn, check_tcl_chon, DCC_CHAT, dcc_total, from, geticon, and parties.

Referenced by mainloop().

01678 {
01679   int i;
01680 
01681   /* Dump party line members */
01682   for (i = 0; i < dcc_total; i++) {
01683     if (dcc[i].type == &DCC_CHAT) {
01684       check_tcl_chon(dcc[i].nick, dcc[i].sock);
01685       check_tcl_chjn(botnetnick, dcc[i].nick, dcc[i].u.chat->channel,
01686                      geticon(i), dcc[i].sock, dcc[i].host);
01687     }
01688   }
01689   for (i = 0; i < parties; i++) {
01690     check_tcl_chjn(party[i].bot, party[i].nick, party[i].chan,
01691                    party[i].flag, party[i].sock, party[i].from);
01692   }
01693 }

Here is the caller graph for this function:

return ( eggbusy||  tclbusy  ) 

Referenced by add_timer().

Here is the caller graph for this function:


Variable Documentation

sigjmp_buf alarmret

Definition at line 69 of file net.c.

int argc [static]

Definition at line 89 of file main.c.

Referenced by main(), and mainloop().

char** argv [static]

Definition at line 90 of file main.c.

Referenced by main(), and mainloop().

int backgrd = 1
char botnetnick[]

Definition at line 45 of file botnet.c.

int cache_hit

Definition at line 47 of file userrec.c.

Definition at line 47 of file userrec.c.

struct chanset_t* chanset

Definition at line 60 of file chanprog.c.

int con_chan = 0

Definition at line 107 of file main.c.

Referenced by core_secondly(), do_arg(), putlog(), tell_verbose_status(), and tell_verbose_uptime().

char configfile[121] = "eggdrop.conf"

Definition at line 111 of file main.c.

int conmask

Definition at line 66 of file misc.c.

struct dcc_t* dcc

Definition at line 46 of file dcc.c.

int dcc_total

Definition at line 47 of file dcc.c.

int default_flags = 0

Definition at line 103 of file main.c.

int default_uflags = 0

Definition at line 104 of file main.c.

Referenced by global(), and tcl_eggint().

int die_on_sighup = 0

Definition at line 133 of file main.c.

Referenced by got_hup().

int die_on_sigterm = 1

Definition at line 134 of file main.c.

Referenced by got_term().

int do_restart = 0

Definition at line 132 of file main.c.

int egg_numver = 1062100

Definition at line 100 of file main.c.

char egg_version[1024] = "1.6.21"

Definition at line 99 of file main.c.

Referenced by do_arg(), init_tcl(), main(), and patch().

char egg_xtra[2048]

Definition at line 130 of file main.c.

Referenced by main(), and patch().

char helpdir[121] = "help/"

Definition at line 113 of file main.c.

unsigned long itraffic_bn = 0

Definition at line 153 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long itraffic_bn_today = 0

Definition at line 154 of file main.c.

Referenced by cmd_traffic(), event_resettraffic(), and mainloop().

unsigned long itraffic_dcc = 0

Definition at line 155 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long itraffic_dcc_today = 0

Definition at line 156 of file main.c.

Referenced by cmd_traffic(), event_resettraffic(), and mainloop().

unsigned long itraffic_irc = 0

Definition at line 151 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long itraffic_irc_today = 0

Definition at line 152 of file main.c.

Referenced by cmd_traffic(), event_resettraffic(), and mainloop().

unsigned long itraffic_trans = 0

Definition at line 157 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long itraffic_trans_today = 0

Definition at line 158 of file main.c.

Referenced by cmd_traffic(), event_resettraffic(), and mainloop().

unsigned long itraffic_unknown = 0

Definition at line 159 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long itraffic_unknown_today = 0

Definition at line 160 of file main.c.

Referenced by cmd_traffic(), event_resettraffic(), and mainloop().

int keep_all_logs = 0

Definition at line 116 of file main.c.

Referenced by check_logsize(), core_secondly(), and putlog().

int lastmin = 99 [static]

Definition at line 520 of file main.c.

char logfile_suffix[21] = ".%d%b%Y"

Definition at line 117 of file main.c.

Referenced by logsuffix_change(), putlog(), and tcl_eggstr().

Definition at line 61 of file misc.c.

int make_userfile = 0

Definition at line 122 of file main.c.

int max_logs

Definition at line 62 of file misc.c.

Definition at line 186 of file modules.c.

char notify_new[121] = ""

Definition at line 102 of file main.c.

int notify_users_at = 0

Definition at line 126 of file main.c.

Referenced by core_secondly().

Definition at line 88 of file main.c.

struct tm nowtm [static]

Definition at line 522 of file main.c.

Referenced by core_minutely(), core_secondly(), and main().

Definition at line 120 of file main.c.

char origbotname[]

Definition at line 62 of file chanprog.c.

unsigned long otraffic_bn = 0

Definition at line 141 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_bn_today = 0

Definition at line 142 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_dcc = 0

Definition at line 143 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_dcc_today = 0

Definition at line 144 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_filesys = 0

Definition at line 145 of file main.c.

unsigned long otraffic_filesys_today = 0

Definition at line 146 of file main.c.

unsigned long otraffic_irc = 0

Definition at line 139 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_irc_today = 0

Definition at line 140 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_trans = 0

Definition at line 147 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_trans_today = 0

Definition at line 148 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_unknown = 0

Definition at line 149 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

unsigned long otraffic_unknown_today = 0

Definition at line 150 of file main.c.

Referenced by cmd_traffic(), and event_resettraffic().

char owner[121] = ""

Definition at line 123 of file main.c.

char pid_file[120]

Definition at line 112 of file main.c.

Definition at line 82 of file tcl.c.

Referenced by core_minutely(), core_secondly(), and flushlogs().

Definition at line 84 of file tcl.c.

Referenced by backup_chanfile(), backup_userfile(), channels_start(), core_secondly(), and write_channels().

char quit_msg[1024]

Definition at line 136 of file main.c.

int resolve_timeout = 15

Definition at line 135 of file main.c.

int save_users_at = 0

Definition at line 125 of file main.c.

int switch_logfiles_at = 300

Definition at line 118 of file main.c.

Referenced by core_secondly().

int term_z = 0

Definition at line 108 of file main.c.

Referenced by do_arg(), main(), putlog(), tell_verbose_status(), and tell_verbose_uptime().

char textdir[121] = "text/"

Definition at line 114 of file main.c.

Referenced by resolve_help().

time_t then [static]

Definition at line 521 of file main.c.

Definition at line 56 of file chanprog.c.

int use_stderr = 1

Definition at line 109 of file main.c.

Referenced by main(), and putlog().

char userfile[]
struct userrec* userlist

Definition at line 57 of file chanprog.c.

char ver[41]

Definition at line 129 of file main.c.

char version[81]

Definition at line 128 of file main.c.


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1