Ejemplo n.º 1
0
// ------------------------------------------------------------------------
//  Translates raw byte data into telnet data, and may send it out to
//  the connection's current protocol handler
// ------------------------------------------------------------------------
void Telnet::Translate( Connection<Telnet>& p_conn, char* p_buffer, int p_size )
{
    for( int i = 0; i < p_size; i++ )
    {

        // if the character is a letter and the buffer isn't full,
        // add it to the buffer
        char c = p_buffer[i];
        if( c >= 32 && c != 127 && m_buffersize < BUFFERSIZE )
        {
            m_buffer[m_buffersize] = c;
            m_buffersize++;
        }

        // else check if it's a backspace
        else if( c == 8 && m_buffersize > 0 )
        {
            // erase the last character
            m_buffersize--;
        }

        // else check if it is a newline, meaning the line is complete
        else if( c == '\n' || c == '\r' )
        {
            // if the buffer size is more than 0, turn the buffer into
            // a string and send it off to the current handler of the 
            // connection. Then reset the size of the buffer.
            if( m_buffersize > 0 && p_conn.Handler() != 0 )
            {
                p_conn.Handler()->Handle( string( m_buffer, m_buffersize ) );
            }
            m_buffersize = 0;
        }
    }
}
Ejemplo n.º 2
0
void sMiniFTPServer::ClientThreadFunc(sThread *t,void *user)
{
  Connection *c = (Connection *) user;
  sTCPSocket *socket = c->Socket;
  RequestInfo info;

  sVERIFYSTATIC(ServerBufferSize >= 16 && ServerBufferSize >= MAXREQUEST*2);
  sFixedArray<sU8> ioBuffer(ServerBufferSize);

  while(socket->IsConnected() && t->CheckTerminate())
  {
    // read request
    if(!socket->ReadAll(&ioBuffer[0],16))
      break;

    // "parse" it
    sU32 command;
    sInt filenameLen;
    sU64 extra;
    sUnalignedLittleEndianLoad32(&ioBuffer[0],command);
    sUnalignedLittleEndianLoad32(&ioBuffer[4],(sU32&) filenameLen);
    sUnalignedLittleEndianLoad64(&ioBuffer[8],extra);

    if(command > sMFC_LAST || filenameLen >= MAXREQUEST)
      break;

    // read the filename
    sString<MAXREQUEST> filename;
    if(!socket->ReadAll(&ioBuffer[0],filenameLen*2))
      break;

    // "parse" it
    for(sInt i=0;i<filenameLen;i++)
    {
      sU16 x;
      sUnalignedLittleEndianLoad16(&ioBuffer[i*2],x);
      filename[i] = x;
    }

    filename[filenameLen] = 0;

    // command-specific handling
    info.Command = (sMiniFTPCommand) command;
    info.Filename = filename;
    info.File = 0;
    info.DirListing.Clear();

    ioBuffer[0] = sU8(c->Handler(info) ? sMFE_OK : sMFE_NOSUCHFILE);
    sBool ok = socket->WriteAll(&ioBuffer[0],1);

    if(ok && ioBuffer[0] == sMFE_OK) // output processing (depends on command)
    {
      ok = sFALSE;

      switch(command)
      {
      case sMFC_EXISTS:
      case sMFC_DELETE:
        ok = sTRUE;
        break;

      case sMFC_GET:
        {
          sSize size = info.File->GetSize();

          sUnalignedLittleEndianStore64(&ioBuffer[0],size);
          if(socket->WriteAll(&ioBuffer[0],8) && info.File->SetOffset(extra))
          {
            sSize pos = extra;
            while(pos<size)
            {
              sInt bytes = (sInt) sMin<sS64>(size-pos,ioBuffer.GetSize());
              if(!info.File->Read(&ioBuffer[0],bytes)
                || !socket->WriteAll(&ioBuffer[0],bytes))
                break;

              pos += bytes;
            }

            ok = (pos == size);
          }
        }
        break;

      case sMFC_PUT:
        {
          sSize size;
          if(c->OnlyFullFiles && extra != 0)
            break;

          if(!socket->ReadAll(&ioBuffer[0],8))
            break;

          sUnalignedLittleEndianLoad64(&ioBuffer[0],(sU64&) size);
          if(info.File->SetOffset(extra))
          {
            sSize pos = extra;
            while(pos<size)
            {
              sInt bytes = (sInt) sMin<sS64>(size-pos,ioBuffer.GetSize());
              if(!socket->ReadAll(&ioBuffer[0],bytes)
                || !info.File->Write(&ioBuffer[0],bytes))
                break;

              pos += bytes;
            }

            ok = (pos == size);
            if(c->OnlyFullFiles && !ok)
            {
              sDelete(info.File);
              sLogF(L"miniftp",L"transfer of file <%s> incomplete, deleting it again.\n",info.Filename);

              // delete the file again
              info.Command = sMFC_DELETE;
              c->Handler(info);
            }
          }
        }
        break;

      case sMFC_LIST:
        {
          sInt count = info.DirListing.GetCount();
          sUnalignedLittleEndianStore64(&ioBuffer[0],count*2);
          if(socket->WriteAll(&ioBuffer[0],8))
          {
            sFixedArray<sU8> buffer(count*2);
            for(sInt i=0;i<count;i++)
              sUnalignedLittleEndianStore16(&buffer[i*2],info.DirListing[i]);

            ok = socket->WriteAll(&buffer[0],count*2);
          }
        }
        break;
      }
    }

    sDelete(info.File);
    if(!ok)
      break;
  }

  socket->Disconnect();
}