Example #1
0
bool sepstream::GetToken(Flux::string &token)
{
	Flux::string::iterator lsp = last_starting_position;
	while (n != tokens.end())
	{
		if (*n == sep || n + 1 == tokens.end())
		{
			last_starting_position = n + 1;
			token = Flux::string(lsp, n + 1 == tokens.end() ? n + 1 : n);

			while (token.length() && token.rfind(sep) == token.length() - 1)
				token.erase(token.end() - 1);

			++n;

			return true;
		}
		++n;
	}
	token.clear();
	return false;
}
Example #2
0
void SocketIO::Process()
{
  SET_SEGV_LOCATION();
  timeval timeout;
  timeout.tv_sec = Config->SockWait;
  timeout.tv_usec = 0; //this timeout keeps the bot from being a CPU hog for no reason :)
  fd_set read = ReadFD, write = WriteFD, except = ExceptFD;

  FD_ZERO(&read);
  FD_SET(this->GetFD(), &read);

  int sres = select(this->GetFD() + 1, &read, &write, &except, &timeout);
  if(sres == -1 && errno != EINTR)
  {
    Log(LOG_DEBUG) << "Select() error: " << strerror(errno);
    return;
  }

  if(throwex) //throw a socket exception if we want to. mainly used for ping timeouts.
    throw SocketException(throwmsg);

  bool has_read = FD_ISSET(this->GetFD(), &read);
  bool has_write = FD_ISSET(this->GetFD(), &write);
  bool has_error = FD_ISSET(this->GetFD(), &except);

  if(has_error)
  {
    int optval = 0;
    socklen_t optlen = sizeof(optval);
    getsockopt(this->GetFD(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&optval), &optlen);
    errno = optval;
    FOREACH_MOD(I_OnSocketError, OnSocketError(optval ? strerror(errno) : "Unknown socket error"));
    throw SocketException("Socket error");
  }
  
  if(has_read)
  {
    char tbuf[BUFSIZE + 1] = "\0";
    size_t i = recv(this->GetFD(), tbuf, BUFSIZE, 0);
    
    if(i <= 0)
      throw SocketException(printfify("Socket Error: %s", strerror(errno)));
    
    sepstream sep(tbuf, '\n');
    Flux::string buf;
    while(sep.GetToken(buf))
    {
      this->LastBuf.clear();
      this->LastBuf = buf;
      if(!this->Read(buf))
	throw SocketException("Error reading socket");
    }

    FD_CLR(this->GetFD(), &ReadFD);
  }

  if(has_write)
  {
    Flux::string buf;
    while(!this->WriteBuffer.empty())
    {
      buf = this->WriteBuffer.front();
      this->WriteBuffer.pop();

      int i = ::send(this->GetFD(), buf.c_str(), buf.size(), MSG_NOSIGNAL);

      if(i <= -1 && !quitting)
	throw SocketException(printfify("Error writing \"%s\" to socket: %s", buf.c_str(), strerror(errno)));

      Log(LOG_RAWIO) << "Sent: " << buf << " | " << buf.size() << " bytes";
      
      this->LastBuf.clear();
      this->LastBuf = buf;

      buf.clear();
    }

    FD_CLR(this->GetFD(), &WriteFD);
  }
}
Example #3
0
 void SetQuery(unsigned n, const Flux::vector &params)
 {
   query.clear();
   if (n < params.size()) for(unsigned i=n; i < params.size(); ++i) query += params[i]+' ';
 }