예제 #1
0
static void timeout_server(int idx)
{
  putlog(LOG_SERV, "*", "Timeout: connect to %s", dcc[idx].host);
  disconnect_server(idx);
  check_tcl_event("fail-server");
  lostdcc(idx);
}
예제 #2
0
파일: main.c 프로젝트: Abysim/NyanLion
/* Got ILL signal -- log context and continue
 */
static void got_ill(int z)
{
  check_tcl_event("sigill");
#ifdef DEBUG_CONTEXT
  putlog(LOG_MISC, "*", "* Context: %s/%d [%s]", cx_file[cx_ptr],
         cx_line[cx_ptr], (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
#endif
}
예제 #3
0
static void server_resolve_failure(int servidx)
{
  serv = -1;
  resolvserv = 0;
  putlog(LOG_SERV, "*", "%s %s (%s)", IRC_FAILEDCONNECT, dcc[servidx].host,
         IRC_DNSFAILED);
  check_tcl_event("fail-server");
  lostdcc(servidx);
}
예제 #4
0
/* 001: welcome to IRC (use it to fix the server name) */
static int got001(char *from, char *msg)
{
  int i;
  char *key;
  struct chanset_t *chan;
  struct server_list *x = serverlist;

  /* FIXME - x should never be NULL anywhere in this function, but
   * apparently it sometimes is. */
  if (x) {
    for (i = curserv; i > 0 && x; i--)
      x = x->next;
    if (!x) {
      putlog(LOG_MISC, "*", "Invalid server list!");
    } else {
      if (x->realname)
        nfree(x->realname);
      x->realname = nmalloc(strlen(from) + 1);
      strcpy(x->realname, from);
    }
    if (realservername)
      nfree(realservername);
    realservername = nmalloc(strlen(from) + 1);
    strcpy(realservername, from);
  } else
    putlog(LOG_MISC, "*", "No server list!");

  server_online = now;
  fixcolon(msg);
  strncpyz(botname, msg, NICKLEN);
  altnick_char = 0;
  dprintf(DP_SERVER, "WHOIS %s\n", botname); /* get user@host */
  if (initserver[0])
    do_tcl("init-server", initserver); /* Call Tcl init-server */
  check_tcl_event("init-server");

  if (!x)
    return 0;

  if (module_find("irc", 0, 0)) {  /* Only join if the IRC module is loaded. */
    for (chan = chanset; chan; chan = chan->next) {
      chan->status &= ~(CHAN_ACTIVE | CHAN_PEND);
      if (!channel_inactive(chan)) {

        key = chan->channel.key[0] ? chan->channel.key : chan->key_prot;
        if (key[0])
          dprintf(DP_SERVER, "JOIN %s %s\n",
                  chan->name[0] ? chan->name : chan->dname, key);
        else
          dprintf(DP_SERVER, "JOIN %s\n",
                  chan->name[0] ? chan->name : chan->dname);
      }
    }
  }

  return 0;
}
예제 #5
0
파일: main.c 프로젝트: Abysim/NyanLion
static void got_term(int z)
{
  write_userfile(-1);
  check_tcl_event("sigterm");
  if (die_on_sigterm) {
    botnet_send_chat(-1, botnetnick, "ACK, I've been terminated!");
    fatal("TERMINATE SIGNAL -- SIGNING OFF", 0);
  } else
    putlog(LOG_MISC, "*", "RECEIVED TERMINATE SIGNAL (IGNORING)");
}
예제 #6
0
파일: main.c 프로젝트: Abysim/NyanLion
static void got_hup(int z)
{
  write_userfile(-1);
  check_tcl_event("sighup");
  if (die_on_sighup) {
    fatal("HANGUP SIGNAL -- SIGNING OFF", 0);
  } else
    putlog(LOG_MISC, "*", "Received HUP signal: rehashing...");
  do_restart = -2;
  return;
}
예제 #7
0
static void disconnect_server(int idx)
{
  if (server_online > 0)
    check_tcl_event("disconnect-server");
  server_online = 0;
  if (realservername)
    nfree(realservername);
  realservername = 0;
  if (dcc[idx].sock >= 0)
    killsock(dcc[idx].sock);
  dcc[idx].sock = -1;
  serv = -1;
  botuserhost[0] = 0;
}
예제 #8
0
static void server_resolve_success(int servidx)
{
  char s[121], pass[121];

  resolvserv = 0;
  dcc[servidx].addr = dcc[servidx].u.dns->ip;
  strcpy(pass, dcc[servidx].u.dns->cbuf);
  changeover_dcc(servidx, &SERVER_SOCKET, 0);
  serv = open_telnet(iptostr(htonl(dcc[servidx].addr)), dcc[servidx].port);
  if (serv < 0) {
    neterror(s);
    putlog(LOG_SERV, "*", "%s %s (%s)", IRC_FAILEDCONNECT, dcc[servidx].host,
           s);
    check_tcl_event("fail-server");
    lostdcc(servidx);
  } else {
    dcc[servidx].sock = serv;
    /* Queue standard login */
    dcc[servidx].timeval = now;
    SERVER_SOCKET.timeout_val = &server_timeout;
    /* Another server may have truncated it, so use the original */
    strcpy(botname, origbotname);
    /* Start alternate nicks from the beginning */
    altnick_char = 0;
    check_tcl_event("preinit-server");
    if (pass[0])
      dprintf(DP_MODE, "PASS %s\n", pass);
    dprintf(DP_MODE, "NICK %s\n", botname);

    rmspace(botrealname);
    if (botrealname[0] == 0)
      strcpy(botrealname, "/msg LamestBot hello");
    dprintf(DP_MODE, "USER %s . . :%s\n", botuser, botrealname);

    /* Wait for async result now. */
  }
}
예제 #9
0
파일: chanprog.c 프로젝트: asterIRC/kaosdal
/* Reload the user file from disk
 */
void reload()
{
  if (!file_readable(userfile)) {
    putlog(LOG_MISC, "*", MISC_CANTRELOADUSER);
    return;
  }

  noshare = 1;
  clear_userlist(userlist);
  noshare = 0;
  userlist = NULL;
  if (!readuserfile(userfile, &userlist))
    fatal(MISC_MISSINGUSERF, 0);
  reaffirm_owners();
  check_tcl_event("userfile-loaded");
  call_hook(HOOK_READ_USERFILE);
}
예제 #10
0
파일: chanprog.c 프로젝트: asterIRC/kaosdal
void chanprog()
{
  int i;
  FILE *f;
  char s[161], rands[8];

  admin[0]   = 0;
  helpdir[0] = 0;
  tempdir[0] = 0;
  conmask    = 0;

  for (i = 0; i < max_logs; i++)
    logs[i].flags |= LF_EXPIRING;

  /* Turn off read-only variables (make them write-able) for rehash */
  protect_readonly = 0;

  /* Now read it */
  if (!readtclprog(configfile))
    fatal(MISC_NOCONFIGFILE, 0);

  for (i = 0; i < max_logs; i++) {
    if (logs[i].flags & LF_EXPIRING) {
      if (logs[i].filename != NULL) {
        nfree(logs[i].filename);
        logs[i].filename = NULL;
      }
      if (logs[i].chname != NULL) {
        nfree(logs[i].chname);
        logs[i].chname = NULL;
      }
      if (logs[i].f != NULL) {
        fclose(logs[i].f);
        logs[i].f = NULL;
      }
      logs[i].mask = 0;
      logs[i].flags = 0;
    }
  }

  /* We should be safe now */
  call_hook(HOOK_REHASH);
  protect_readonly = 1;

  if (!botnetnick[0])
    strncpyz(botnetnick, origbotname, HANDLEN + 1);

  if (!botnetnick[0])
    fatal("I don't have a botnet nick!!\n", 0);

  if (!userfile[0])
    fatal(MISC_NOUSERFILE2, 0);

  if (!readuserfile(userfile, &userlist)) {
    if (!make_userfile) {
      char tmp[178];

      egg_snprintf(tmp, sizeof tmp, MISC_NOUSERFILE, configfile);
      fatal(tmp, 0);
    }
    printf("\n\n%s\n", MISC_NOUSERFILE2);
    if (module_find("server", 0, 0))
      printf(MISC_USERFCREATE1, origbotname);
    printf("%s\n\n", MISC_USERFCREATE2);
  } else if (make_userfile) {
    make_userfile = 0;
    printf("%s\n", MISC_USERFEXISTS);
  }

  if (helpdir[0])
    if (helpdir[strlen(helpdir) - 1] != '/')
      strcat(helpdir, "/");

  if (tempdir[0])
    if (tempdir[strlen(tempdir) - 1] != '/')
      strcat(tempdir, "/");

  /* Test tempdir: it's vital. */

  /* Possible file race condition solved by using a random string
   * and the process id in the filename.
   * FIXME: This race is only partitially fixed. We could still be
   *        overwriting an existing file / following a malicious
   *        link.
   */
  make_rand_str(rands, 7); /* create random string */
  sprintf(s, "%s.test-%u-%s", tempdir, getpid(), rands);
  f = fopen(s, "w");
  if (f == NULL)
    fatal(MISC_CANTWRITETEMP, 0);
  fclose(f);
  unlink(s);
  reaffirm_owners();
  check_tcl_event("userfile-loaded");
}
예제 #11
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
int mainloop(int toplevel)
{
  static int socket_cleanup = 0;
  int xx, i, eggbusy = 1, tclbusy = 0;
  char buf[520];

  /* Lets move some of this here, reducing the numer of actual
   * calls to periodic_timers
   */
  now = time(NULL);
  /*
   * FIXME: Get rid of this, it's ugly and wastes lots of cpu.
   *
   * pre-1.3.0 Eggdrop had random() in the once a second block below.
   *
   * This attempts to keep random() more random by constantly
   * calling random() and updating the state information.
   */
  random();                /* Woop, lets really jumble things */

  /* If we want to restart, we have to unwind to the toplevel.
   * Tcl will Panic if we kill the interp with Tcl_Eval in progress.
   * This is done by returning -1 in tickle_WaitForEvent.
   */
  if (do_restart && do_restart != -2 && !toplevel)
    return -1;

  /* Once a 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) {
        if (dcc[idx].type && dcc[idx].type->activity) {
          /* Traffic stats */
          if (dcc[idx].type->name) {
            if (!strncmp(dcc[idx].type->name, "BOT", 3))
              itraffic_bn_today += strlen(buf) + 1;
            else if (!strcmp(dcc[idx].type->name, "SERVER"))
              itraffic_irc_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
              itraffic_dcc_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "FILES", 5))
              itraffic_dcc_today += strlen(buf) + 1;
            else if (!strcmp(dcc[idx].type->name, "SEND"))
              itraffic_trans_today += strlen(buf) + 1;
            else if (!strncmp(dcc[idx].type->name, "GET", 3))
              itraffic_trans_today += strlen(buf) + 1;
            else
              itraffic_unknown_today += strlen(buf) + 1;
          }
          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 from someone */
    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) {
        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 */
    eggbusy = 0;
  } else if (xx == -5) {
    eggbusy = 0;
    tclbusy = 1;
  }

  if (do_restart) {
    if (do_restart == -2)
      rehash();
    else if (!toplevel)
      return -1; /* Unwind to toplevel before restarting */
    else {
      /* Unload as many modules as possible */
      int f = 1;
      module_entry *p;
      Function startfunc;
      char name[256];

      /* oops, I guess we should call this event before tcl is restarted */
      check_tcl_event("prerestart");

      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);
      }

      flushlogs();
      kill_tcl();
      init_tcl(argc, argv);
      init_language(0);

      /* 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();
#ifdef TLS
      ssl_cleanup();
      ssl_init();
#endif
      restart_chons();
      call_hook(HOOK_LOADED);
    }
    eggbusy = 1;
    do_restart = 0;
  }

#ifdef USE_TCL_EVENTS
  if (!eggbusy) {
/* Process all pending tcl events */
#  ifdef REPLACE_NOTIFIER
    if (Tcl_ServiceAll())
      tclbusy = 1;
#  else
    while (Tcl_DoOneEvent(TCL_DONT_WAIT | TCL_ALL_EVENTS))
      tclbusy = 1;
#  endif /* REPLACE_NOTIFIER */
#endif   /* USE_TCL_EVENTS   */
  }

  return (eggbusy || tclbusy);
}
예제 #12
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
static void event_loaded()
{
  check_tcl_event("loaded");
}
예제 #13
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
static void event_logfile()
{
  check_tcl_event("logfile");
}
예제 #14
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
static void event_save()
{
  check_tcl_event("save");
}
예제 #15
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
static void event_prerehash()
{
  check_tcl_event("prerehash");
}
예제 #16
0
파일: main.c 프로젝트: Estella/eggdrop-1.8
static void event_rehash()
{
  check_tcl_event("rehash");
}
예제 #17
0
/* Hook up to a server
 */
static void connect_server(void)
{
  char pass[121], botserver[UHOSTLEN];
  int servidx;
  unsigned int botserverport = 0;

  lastpingcheck = 0;
  trying_server = now;
  empty_msgq();
  if (newserverport) {          /* Jump to specified server */
    curserv = -1;             /* Reset server list */
    strcpy(botserver, newserver);
    botserverport = newserverport;
    strcpy(pass, newserverpass);
    newserver[0] = 0;
    newserverport = 0;
    newserverpass[0] = 0;
  } else {
    if (curserv == -1)
      curserv = 999;
    pass[0] = 0;
  }
  if (!cycle_time) {
    struct chanset_t *chan;
    struct server_list *x = serverlist;

    if (!x && !botserverport) {
      putlog(LOG_SERV, "*", "No servers in server list");
      cycle_time = 300;
      return;
    }

    servidx = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
    if (servidx < 0) {
      putlog(LOG_SERV, "*",
             "NO MORE DCC CONNECTIONS -- Can't create server connection.");
      return;
    }

    if (connectserver[0])       /* drummer */
      do_tcl("connect-server", connectserver);
    check_tcl_event("connect-server");
    next_server(&curserv, botserver, &botserverport, pass);
#ifdef TLS
    putlog(LOG_SERV, "*", "%s [%s]:%s%d", IRC_SERVERTRY, botserver,
           use_ssl ? "+" : "", botserverport);
    dcc[servidx].ssl = use_ssl;
#else
    putlog(LOG_SERV, "*", "%s [%s]:%d", IRC_SERVERTRY, botserver,
           botserverport);
#endif
    dcc[servidx].port = botserverport;
    strcpy(dcc[servidx].nick, "(server)");
    strncpyz(dcc[servidx].host, botserver, UHOSTLEN);

    botuserhost[0] = 0;

    nick_juped = 0;
    for (chan = chanset; chan; chan = chan->next)
      chan->status &= ~CHAN_JUPED;

    dcc[servidx].timeval = now;
    dcc[servidx].sock = -1;
    dcc[servidx].u.dns->host = get_data_ptr(strlen(dcc[servidx].host) + 1);
    strcpy(dcc[servidx].u.dns->host, dcc[servidx].host);
    dcc[servidx].u.dns->cbuf = get_data_ptr(strlen(pass) + 1);
    strcpy(dcc[servidx].u.dns->cbuf, pass);
    dcc[servidx].u.dns->dns_success = server_resolve_success;
    dcc[servidx].u.dns->dns_failure = server_resolve_failure;
    dcc[servidx].u.dns->dns_type = RES_IPBYHOST;
    dcc[servidx].u.dns->type = &SERVER_SOCKET;

    if (server_cycle_wait)
      /* Back to 1st server & set wait time.
       * Note: Put it here, just in case the server quits on us quickly
       */
      cycle_time = server_cycle_wait;
    else
      cycle_time = 0;

    /* I'm resolving... don't start another server connect request */
    resolvserv = 1;
    /* Resolve the hostname. */
    dcc_dnsipbyhost(dcc[servidx].host);
  }
}
예제 #18
0
파일: main.c 프로젝트: Abysim/NyanLion
static void got_quit(int z)
{
  check_tcl_event("sigquit");
  putlog(LOG_MISC, "*", "RECEIVED QUIT SIGNAL (IGNORING)");
  return;
}
예제 #19
0
파일: main.c 프로젝트: Estella/eggdrop-1.7
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;
    }
  }
}
예제 #20
0
파일: main.c 프로젝트: Estella/eggdrop-1.7
/* Got ILL signal. */
static void got_ill(int z)
{
  check_tcl_event("sigill");
}
예제 #21
0
파일: main.c 프로젝트: Estella/eggdrop-1.7
static void got_quit(int z)
{
  check_tcl_event("sigquit");
  putlog(LOG_MISC, "*", "Received QUIT signal (ignoring).");
  return;
}