void FileTransferRequestHandler::dirSizeRequested()
{
  WinFilePath fullPathName;

  {
    m_input->readUTF8(&fullPathName);
  } // end of reading block.

  m_log->message(_T("Size of folder '%s\' requested"),
               fullPathName.getString());

  checkAccess();

  UINT64 directorySize = 0;

  if (!getDirectorySize(fullPathName.getString(), &directorySize)) {
    throw SystemException();
  }

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::DIRSIZE_REPLY);
    m_output->writeUInt64(directorySize);

    m_output->flush();
  }
} // void
void FileTransferRequestHandler::mvFileRequested()
{
  WinFilePath oldFileName;
  WinFilePath newFileName;

  {
    m_input->readUTF8(&oldFileName);
    m_input->readUTF8(&newFileName);
  } // end of reading block.

  m_log->message(_T("move \"%s\" \"%s\" command requested"), oldFileName.getString(), newFileName.getString());

  checkAccess();

  File srcFile(oldFileName.getString());
  File dstFile(newFileName.getString());

  if (!srcFile.renameTo(&dstFile)) {
    throw SystemException();
  }

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::RENAME_REPLY);

    m_output->flush();
  }
}
void FileTransferRequestHandler::rmFileRequested()
{
  WinFilePath fullPathName;

  {
    m_input->readUTF8(&fullPathName);
  } // end of reading block.

  m_log->message(_T("rm \"%s\" command requested"), fullPathName.getString());

  checkAccess();

  File file(fullPathName.getString());

  if (!file.exists()) {
    throw SystemException();
  } // file file does not exists

  if (!file.remove()) {
    throw SystemException();
  } // if cannot delete file

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::REMOVE_REPLY);

    m_output->flush();
  }
} // void
void FileTransferRequestHandler::mkDirRequested()
{
  WinFilePath folderPath;

  {
    m_input->readUTF8(&folderPath);
  } // end of reading block.

  m_log->message(_T("mkdir \"%s\" command requested"), folderPath.getString());

  checkAccess();

  if (folderPath.parentPathIsRoot()) {
    throw FileTransferException(_T("Cannot create folder in root folder"));
  }

  File folder(folderPath.getString());

  if (folder.exists()) {
    throw FileTransferException(_T("Directory already exists"));
  }

  if (!folder.mkdir()) {
    throw SystemException();
  }

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::MKDIR_REPLY);

    m_output->flush();
  }
}
void FileTransferRequestHandler::downloadStartRequested()
{
  WinFilePath fullPathName;
  UINT64 initialOffset;

  //
  // Reading command arguments
  //

  {
    m_input->readUTF8(&fullPathName);
    initialOffset = m_input->readUInt64();
  } // end of reading block.

  m_log->message(_T("download of \"%s\" file (offset = %d) requested"), fullPathName.getString(), initialOffset);

  checkAccess();

  //
  // Ending previous download if it was broken
  //

  if (m_fileInputStream != 0) {
    delete m_fileInputStream;
    m_fileInputStream = 0;
  }
  if (m_downloadFile != 0) {
    delete m_downloadFile;
    m_downloadFile = 0;
  }

  m_downloadFile = new File(fullPathName.getString());


  //
  // Try to open file for reading and seek to initial
  // file position.
  //

  m_fileInputStream = new WinFileChannel(fullPathName.getString(), F_READ,
                                         FM_OPEN);
  m_fileInputStream->seek(initialOffset);

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::DOWNLOAD_START_REPLY);

    m_output->flush();
  }
}
Exemple #6
0
WinFilePath::WinFilePath(const WinFilePath &stringBuffer)
: m_parentPathIsRoot(false)
{
  setString(stringBuffer.getString());
}
void FileTransferRequestHandler::uploadStartRequested()
{
  //
  // Request input variables.
  //

  WinFilePath fullPathName;
  UINT8 uploadFlags;
  UINT64 initialOffset;

  {
    m_input->readUTF8(&fullPathName);
    uploadFlags = m_input->readUInt8();
    initialOffset = m_input->readUInt64();
  }

  m_log->message(_T("upload \"%s\" %d %d command requested"), fullPathName.getString(), uploadFlags, initialOffset);

  checkAccess();

  //
  // Closing previous upload if it was broken
  //

  if (m_fileOutputStream != NULL) {
    delete m_fileOutputStream;
    m_fileOutputStream = 0;
  }
  if (m_uploadFile != NULL) {
    delete m_uploadFile;
    m_uploadFile = 0;
  }

  if (fullPathName.parentPathIsRoot()) {
    throw FileTransferException(_T("Cannot upload file to root folder"));
  }

  m_uploadFile = new File(fullPathName.getString());

  //
  // Trying to create file or overwrite existing
  //

  if ((uploadFlags & 0x1) && (!m_uploadFile->truncate())) {
    throw SystemException();
  }

  //
  // Trying to open file and seek to initial file position
  //
  m_fileOutputStream = new WinFileChannel(fullPathName.getString(),
                                          F_WRITE,
                                          FM_OPEN);
  m_fileOutputStream->seek(initialOffset);

  //
  // Send reply
  //

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::UPLOAD_START_REPLY);

    m_output->flush();
  }
} // void
void FileTransferRequestHandler::md5Requested()
{
  WinFilePath fullPathName;

  UINT64 offset;
  UINT64 dataLen;

  {
    m_input->readUTF8(&fullPathName);

    offset = m_input->readUInt64();
    dataLen = m_input->readUInt64();
  } // end of reading block.

  m_log->message(_T("md5 \"%s\" %d %d command requested"), fullPathName.getString(), offset, dataLen);

  checkAccess();

  //
  // Action
  //

  MD5 md5calculator;

  File file(fullPathName.getString());

  StringStorage path;
  file.getPath(&path);
  WinFileChannel fileInputStream(path.getString(), F_READ, FM_OPEN);
  fileInputStream.seek(offset);

  //
  // Begin reading needed file data
  //

  DWORD bytesToRead = 1024 * 1024;
  UINT64 bytesToReadTotal = dataLen;
  size_t bytesRead = 0;
  UINT64 bytesReadTotal = 0;

  if (dataLen < (UINT64)bytesToRead) {
    bytesToRead = (DWORD)dataLen;
  }

  std::vector<UINT8> buffer(bytesToRead);

  while (bytesToReadTotal > 0) {
    bytesRead = fileInputStream.read(&buffer.front(), bytesToRead);
    bytesReadTotal += bytesRead;
    bytesToReadTotal -= bytesRead;

    if (bytesToReadTotal < (UINT64)bytesToRead) {
      bytesToRead = (DWORD)bytesToReadTotal;
    }

    md5calculator.update(&buffer.front(), (UINT32)bytesRead);
  } // while

  md5calculator.finalize();

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::MD5_REPLY);
    m_output->writeFully((const char *)md5calculator.getHash(), 16);

    m_output->flush();
  }
}
void FileTransferRequestHandler::fileListRequested()
{
  UINT8 requestedCompressionLevel;
  WinFilePath fullPathName;

  //
  // Read input data
  //

  {
    requestedCompressionLevel = m_input->readUInt8();

    m_input->readUTF8(&fullPathName);
  }

  m_log->message(_T("File list of folder '%s' requested"),
               fullPathName.getString());

  checkAccess();

  UINT8 compressionLevel = requestedCompressionLevel;
  UINT32 compressedSize = 0;
  UINT32 uncompressedSize = 0;
  UINT32 filesCount = 0;
  UINT32 filesInfoDataSize = 0;
  const FileInfo *files = NULL;

  //
  // Get file list from specified folder
  //

  FolderListener folderListener(fullPathName.getString());

  if (!folderListener.list()) {
    throw SystemException();
  }

  files = folderListener.getFilesInfo();
  filesCount = folderListener.getFilesCount();

  //
  // Create buffer with "CompressedData" block inside
  //

  ByteArrayOutputStream memStream;
  DataOutputStream outMemStream(&memStream);

  outMemStream.writeUInt32(filesCount);
  for (UINT32 i = 0; i < filesCount; i++) {
    outMemStream.writeUInt64(files[i].getSize());
    outMemStream.writeUInt64(files[i].lastModified());
    outMemStream.writeUInt16(files[i].getFlags());
    outMemStream.writeUTF8(files[i].getFileName());
  } // for

  _ASSERT((UINT32)memStream.size() == memStream.size());
  uncompressedSize = (UINT32)memStream.size();

  //
  // Buffer for data in "CompressedData" block
  //

  compressedSize = uncompressedSize;

  if (compressionLevel != 0) {
    m_deflater.setInput(memStream.toByteArray(), memStream.size());
    m_deflater.deflate();
    _ASSERT((UINT32)m_deflater.getOutputSize() == m_deflater.getOutputSize());
    compressedSize = (UINT32)m_deflater.getOutputSize();
  }

  //
  // Write data to socket
  //

  {
    AutoLock l(m_output);

    m_output->writeUInt32(FTMessage::FILE_LIST_REPLY);

    m_output->writeUInt8(compressionLevel);
    m_output->writeUInt32(compressedSize);
    m_output->writeUInt32(uncompressedSize);

    if (compressionLevel != 0) {
      m_output->writeFully(m_deflater.getOutput(), compressedSize);
    } else {
      m_output->writeFully(memStream.toByteArray(), uncompressedSize);
    }

    m_output->flush();
  } // synchronized(m_output)
} // void