Пример #1
0
void
readsocks(const char *fname)
{
  /* Don't bother setting this if a hub
     ... it is only intended to prevent parting channels (in bot_shouldjoin())
   */
  if (!conf.bot->hub)
    restarting = 1;

  char *nick = NULL, *jnick = NULL, *ip4 = NULL, *ip6 = NULL;
  time_t old_buildts = 0;

  bool cached_005 = 0;
  const char salt1[] = SALT1;
  EncryptedStream stream(salt1);
  stream.loadFile(fname);
  bd::String str, type;

  reset_chans = 0;

  while (stream.tell() < stream.length()) {
    str = stream.getline().chomp();
    dprintf(DP_DEBUG, "read line: %s\n", str.c_str());
    type = newsplit(str);

    if (type == STR("-dcc"))
      dprintf(DP_DEBUG, STR("Added dcc: %d\n"), dcc_read(stream));
    else if (type == STR("-sock"))
      dprintf(DP_DEBUG, STR("Added fd: %d\n"), sock_read(stream));
    else if (type == STR("+online_since"))
      online_since = strtol(str.c_str(), NULL, 10);
    else if (type == STR("+server_online"))
      server_online = strtol(str.c_str(), NULL, 10);
    else if (type == STR("+server_floodless"))
      floodless = 1;
    else if (type == STR("+in_deaf"))
      in_deaf = 1;
    else if (type == STR("+in_callerid"))
      in_callerid = 1;
    else if (type == STR("+chan")) {
      bd::String chname = str;
      channel_add(NULL, chname.c_str(), NULL);
      struct chanset_t* chan = findchan_by_dname(chname.c_str());
      strlcpy(chan->name, chan->dname, sizeof(chan->name));
      chan->status = chan->ircnet_status = 0;
      chan->ircnet_status |= CHAN_PEND;
      reset_chans = 2;
    }
    else if (type == STR("+buildts"))
      old_buildts = strtol(str.c_str(), NULL, 10);
    else if (type == STR("+botname"))
      nick = str.dup();
    else if (type == STR("+rolls"))
      rolls = atoi(str.c_str());
    else if (type == STR("+altnick_char"))
      altnick_char = str[0];
    else if (type == STR("+burst"))
      burst = atoi(str.c_str());
    else if (type == STR("+flood_count"))
      flood_count = atoi(str.c_str());
    else if (type == STR("+my_cookie_counter")) {
      my_cookie_counter = strtol(str.c_str(), NULL, 10);
      my_cookie_counter += 100; // Increase to avoid race conditions
    }
    else if (type == STR("+ip4"))
      ip4 = str.dup();
    else if (type == STR("+ip6"))
      ip6 = str.dup();
    else if (type == STR("+serv_cache")) {
      if (!cached_005 && str.find(STR("005")))
        cached_005 = 1;
      dprintf(DP_CACHE, "%s", str.c_str());
    }
  }

  restart_time = now;
  if (old_buildts && buildts > old_buildts)
    restart_was_update = 1;

  tell_dcc(DP_DEBUG);
  tell_netdebug(DP_DEBUG);

  unlink(fname);

  if (servidx >= 0) {
    char nserv[50] = "";

    if ((ip4 && ip6) && (strcmp(ip4, myipstr(AF_INET)) || strcmp(ip6, myipstr(AF_INET6)))) {
      if (tands > 0) {		/* We're not linked yet.. but for future */
        botnet_send_chat(-1, conf.bot->nick, STR("IP changed."));
        botnet_send_bye(STR("IP changed."));
      }
      fatal("brb", 1);
    } else if (conf.bot->hub) {
      // I became a hub during restart... disconnect from IRC.
      if (tands > 0) {		/* We're not linked yet.. but for future */
        botnet_send_chat(-1, conf.bot->nick, STR("Changing to HUB."));
        botnet_send_bye(STR("Changing to HUB."));
      }
      nuke_server("emoquit");
    } else {
      simple_snprintf(nserv, sizeof(nserv), "%s:%d", dcc[servidx].host, dcc[servidx].port);
      add_server(nserv);
      curserv = 0;
      keepnick = 0; /* Wait to change nicks until relinking, fixes nick/jupenick switching issues during restart */
      reset_flood();
      if (!server_online) server_online = now;
      rehash_server(dcc[servidx].host, nick);
      if (cached_005)
        replay_cache(servidx, NULL);
      else
        dprintf(DP_DUMP, "VERSION\n");
      if (!reset_chans)
        reset_chans = 1;
    }
  }
  delete[] nick;
  delete[] ip4;
  delete[] ip6;
  if (jnick)
    free(jnick);
  if (socksfile)
    free(socksfile);
}
Пример #2
0
void
restart(int idx)
{
  const char *reason = updating ? STR("Updating...") : STR("Restarting...");
  Tempfile *socks = new Tempfile("socks");
  int fd = 0;

  sdprintf("%s", reason); 

  if (tands > 0) {
    botnet_send_chat(-1, conf.bot->nick, (char *) reason);
    botnet_send_bye(reason);
  }

  /* kill all connections except STDOUT/server */
  for (fd = 0; fd < dcc_total; fd++) {
    if (dcc[fd].type && dcc[fd].type != &SERVER_SOCKET && dcc[fd].sock != STDOUT) {
      if (dcc[fd].sock >= 0)
        killsock(dcc[fd].sock);
      lostdcc(fd);
    }
  }

  const char salt1[] = SALT1;
  EncryptedStream stream(salt1);

  /* write out all leftover dcc[] entries */
  for (fd = 0; fd < dcc_total; fd++)
    if (dcc[fd].type && dcc[fd].sock != STDOUT)
      dcc_write(stream, fd);

  /* write out all leftover socklist[] entries */
  for (fd = 0; fd < MAXSOCKS; fd++)
    if (socklist[fd].sock != STDOUT)
      sock_write(stream, fd);

  if (server_online) {
    if (botname[0])
      stream << bd::String::printf(STR("+botname %s\n"), botname);
    if (rolls)
      stream << bd::String::printf(STR("+rolls %d\n"), rolls);
    if (altnick_char)
      stream << bd::String::printf(STR("+altnick_char %c\n"), altnick_char);
    if (burst)
      stream << bd::String::printf(STR("+burst %d\n"), burst);
    if (flood_count)
      stream << bd::String::printf(STR("+flood_count %d\n"), flood_count);
    if (my_cookie_counter)
      stream << bd::String::printf(STR("+my_cookie_counter %lu\n"), my_cookie_counter);
    stream << bd::String::printf(STR("+server_online %li\n"), (long)server_online);
  }
  stream << bd::String::printf(STR("+online_since %li\n"), (long)online_since);
  if (floodless)
    stream << bd::String::printf(STR("+server_floodless %d\n"), floodless);
  if (in_deaf)
    stream << bd::String::printf(STR("+in_deaf\n"));
  if (in_callerid)
    stream << bd::String::printf(STR("+in_callerid\n"));
  for (struct chanset_t *chan = chanset; chan; chan = chan->next)
    if (shouldjoin(chan) && (channel_active(chan) || channel_pending(chan)))
      stream << bd::String::printf(STR("+chan %s\n"), chan->dname);
  stream << bd::String::printf(STR("+buildts %li\n"), (long)buildts);
  stream << bd::String::printf(STR("+ip4 %s\n"), myipstr(AF_INET));
  stream << bd::String::printf(STR("+ip6 %s\n"), myipstr(AF_INET6));
  replay_cache(-1, &stream);

  stream.writeFile(socks->fd);

  socks->my_close();

  write_userfile(idx);
/*
  if (server_online) {
    do_chanset(NULL, NULL, STR("+inactive"), DO_LOCAL);
    dprintf(DP_DUMP, STR("JOIN 0\n"));
  }
*/
  fixmod(binname);

  /* replace image now */
  char *argv[4] = { NULL, NULL, NULL, NULL };

  argv[0] = strdup(binname);

  if (!backgrd || term_z || sdebug) {
    char shit[7] = "";

    simple_snprintf(shit, sizeof(shit), STR("-%s%s%s"), !backgrd ? "n" : "", term_z ? "t" : "", sdebug ? "D" : "");
    argv[1] = strdup(shit);
    argv[2] = strdup(conf.bot->nick);
  } else {
    argv[1] = strdup(conf.bot->nick);
  }

  unlink(conf.bot->pid_file);
  FILE *fp = NULL;
  if (!(fp = fopen(conf.bot->pid_file, "w")))
    return;
  fprintf(fp, "%d %s\n", getpid(), socks->file);
  fclose(fp);

  execvp(argv[0], &argv[0]);

  /* hopefully this is never reached */
  putlog(LOG_MISC, "*", STR("Could not restart: %s"), strerror(errno));
  return;
}
Пример #3
0
void LastValueCache::run()
{
  // One for each internal statistic (0.._statcount-1) and one for the publisher.
  zmq_pollitem_t items[_statcount + 1];

  for (int ii = 0; ii < _statcount; ii++)
  {
    _subscriber[ii] = zmq_socket(_context, ZMQ_SUB);
    LOG_DEBUG("Initializing inproc://%s statistic listener", _statnames[ii].c_str());
    zmq_connect(_subscriber[ii], ("inproc://" + _statnames[ii]).c_str());
    zmq_setsockopt(_subscriber[ii], ZMQ_SUBSCRIBE, "", 0);
  }

  _publisher = zmq_socket(_context, ZMQ_XPUB);
  zmq_bind(_publisher, "tcp://*:6666");

  while (!_terminate)
  {
    // Reset the poll items
    for (int ii = 0; ii < _statcount; ii++)
    {
      items[ii].socket = _subscriber[ii];
      items[ii].fd = 0;
      items[ii].events = ZMQ_POLLIN;
      items[ii].revents = 0;
    }
    items[_statcount].socket = _publisher;
    items[_statcount].fd = 0;
    items[_statcount].events = ZMQ_POLLIN;
    items[_statcount].revents = 0;

    // Poll for an event
    //LOG_DEBUG("Poll for %d items", _statcount + 1);
    int rc = zmq_poll(items, _statcount + 1, _poll_timeout_ms);
    assert(rc >= 0 || errno == EINTR);

    for (int ii = 0; ii < _statcount; ii++)
    {
      if (items[ii].revents & ZMQ_POLLIN)
      {
        LOG_DEBUG("Update to %s statistic", _statnames[ii].c_str());
        clear_cache(_subscriber[ii]);
        while (1)
        {
          zmq_msg_t message;
          zmq_msg_t *cached_message = (zmq_msg_t *)malloc(sizeof(zmq_msg_t));
          int more;
          size_t more_size = sizeof (more);

          zmq_msg_init(&message);
          zmq_msg_init(cached_message);
          zmq_msg_recv(&message, _subscriber[ii], 0);
          zmq_msg_copy(cached_message, &message);
          _cache[_subscriber[ii]].push_back(cached_message);
          zmq_getsockopt(_subscriber[ii], ZMQ_RCVMORE, &more, &more_size);
          zmq_msg_send(&message, _publisher, more ? ZMQ_SNDMORE : 0);
          zmq_msg_close(&message);
          if (!more)
            break;      //  Last message frame
        }
      }
    }

    // Recognize incoming subscription events
    if (items[_statcount].revents & ZMQ_POLLIN)
    {
      zmq_msg_t message;
      zmq_msg_init(&message);
      zmq_msg_recv(&message, _publisher, 0);
      char *msg_body = (char *)zmq_msg_data(&message);
      if (msg_body[0] == ZMQ_NEW_SUBSCRIPTION_MARKER)
      {
        // This is a new subscription
        std::string topic = std::string(msg_body + 1, zmq_msg_size(&message) - 1);
        LOG_DEBUG("New subscription for %s", topic.c_str());
        bool recognized = false;

        for (int ii = 0; ii < _statcount; ii++)
        {
          if (topic == _statnames[ii])
          {
            LOG_DEBUG("Statistic found, check for cached value");
            recognized = true;

            // Replay the cached message if one exists
            if (_cache.find(_subscriber[ii]) != _cache.end())
            {
              replay_cache(_subscriber[ii]);
            }
            else
            {
              LOG_DEBUG("No cached record found, reporting empty statistic");
              std::string status = "OK";
              zmq_send(_publisher, _statnames[ii].c_str(), _statnames[ii].length(), ZMQ_SNDMORE);
              zmq_send(_publisher, status.c_str(), status.length(), 0);
            }
          }
        }

        if (!recognized)
        {
          LOG_DEBUG("Subscription for unknown stat %s", topic.c_str());
          std::string status = "Unknown";
          zmq_send(_publisher, topic.c_str(), topic.length(), ZMQ_SNDMORE);
          zmq_send(_publisher, status.c_str(), status.length(), 0);
        }
      }
      zmq_msg_close(&message);
    }
  }

  for (int ii = 0; ii < _statcount; ii++)
  {
    zmq_disconnect(_subscriber[ii], ("inproc://" + _statnames[ii]).c_str());
    zmq_close(_subscriber[ii]);
    clear_cache(_subscriber[ii]);
  }
  zmq_unbind(_publisher, "tcp://*:6666");
  zmq_close(_publisher);
}