Added the file transfer feature to the server side.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@534 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb/SFileTransfer.cxx b/rfb/SFileTransfer.cxx
new file mode 100644
index 0000000..e947a74
--- /dev/null
+++ b/rfb/SFileTransfer.cxx
@@ -0,0 +1,334 @@
+/* Copyright (C) 2006 TightVNC Team.  All Rights Reserved.

+ *    

+ * Developed by Dennis Syrovatsky

+ *

+ * This is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by

+ * the Free Software Foundation; either version 2 of the License, or

+ * (at your option) any later version.

+ * 

+ * This software is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU General Public License for more details.

+ * 

+ * You should have received a copy of the GNU General Public License

+ * along with this software; if not, write to the Free Software

+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,

+ * USA.

+ *

+ * TightVNC distribution homepage on the Web: http://www.tightvnc.com/

+ *

+ */

+

+// -=- SFileTransfer.cxx

+

+#include <rfb/msgTypes.h>

+#include <rfb/SFileTransfer.h>

+

+using namespace rfb;

+

+SFileTransfer::SFileTransfer(network::Socket *sock) : 

+  m_pSocket(sock), m_reader(&sock->inStream()), m_writer(&sock->outStream()),

+  m_bUploadStarted(false), m_bDownloadStarted(false)

+{

+}

+

+SFileTransfer::~SFileTransfer()

+{

+}

+

+bool

+SFileTransfer::processMessages(int type)

+{

+  switch(type)

+  {

+    case msgTypeFileListRequest:

+      return processFileListRequest();

+    case msgTypeFileDownloadRequest:

+      return processFileDownloadRequest();

+    case msgTypeFileUploadRequest:

+      return processFileUploadRequest();

+    case msgTypeFileUploadData:

+      return processFileUploadData();

+    case msgTypeFileDownloadCancel:

+      return processFileDownloadCancel();

+    case msgTypeFileUploadFailed:

+      return processFileUploadFailed();

+    case msgTypeFileCreateDirRequest:

+      return processFileCreateDirRequest();

+    case msgTypeFileDirSizeRequest:

+      return processFileDirSizeRequest();

+    case msgTypeFileRenameRequest:

+      return processFileRenameRequest();

+    case msgTypeFileDeleteRequest:

+      return processFileDeleteRequest();

+    default:

+      return false;

+  }

+}

+

+bool 

+SFileTransfer::processFileListRequest()

+{

+  char szDirName[FT_FILENAME_SIZE] = {0};

+  unsigned int dirNameSize = FT_FILENAME_SIZE;

+  unsigned int flags = 0;

+

+  if (!m_reader.readFileListRqst(&dirNameSize, szDirName, &flags)) return false;

+

+  if (!convertPathFromNet(szDirName)) return false;

+

+  bool bDirOnly = false;

+  if (flags & 0x10) bDirOnly = true;

+

+  FileInfo fi;

+  if (!makeFileList(szDirName, &fi, bDirOnly)) return false;

+

+  return m_writer.writeFileListData((unsigned char)flags, &fi);

+}

+

+bool 

+SFileTransfer::processFileDownloadRequest()

+{

+  char szName[FT_FILENAME_SIZE] = {0};

+  unsigned int nameSize = FT_FILENAME_SIZE;

+  unsigned int position = 0;

+

+  if (!m_reader.readFileDownloadRqst(&nameSize, szName, &position)) return false;

+

+  if (!convertPathFromNet(szName)) return false;

+

+  if (m_bDownloadStarted) {

+    char reason[] = "The download is already started";

+    m_writer.writeFileLastRqstFailed(msgTypeFileDownloadRequest, strlen(reason), reason);

+    return false;

+  }

+

+  if (!m_fileReader.create(szName)) return false;

+

+  m_bDownloadStarted = true;

+

+  sendFileDownloadPortion();

+

+  return true;

+}

+

+bool

+SFileTransfer::sendFileDownloadPortion()

+{

+  char buffer[FT_MAX_SENDING_SIZE];

+  unsigned int bytesRead = 0;

+

+  if (m_fileReader.read((void *)buffer, FT_MAX_SENDING_SIZE, &bytesRead)) {

+    if (bytesRead == 0) {

+      m_writer.writeFileDownloadData(m_fileReader.getTime());

+      m_fileReader.close();

+      m_bDownloadStarted = false;

+      return true;

+    } else {

+      m_writer.writeFileDownloadData(bytesRead, buffer);

+      return initDownloadCallback();

+    }

+  } else {

+    char reason[] = "Error while reading from file";

+    m_writer.writeFileDownloadFailed(strlen(reason), reason);

+    m_fileReader.close();

+    m_bDownloadStarted = false;

+    return true;

+  }

+}

+

+bool 

+SFileTransfer::processFileUploadRequest()

+{

+  char szName[FT_FILENAME_SIZE] = {0};

+  unsigned int nameSize = FT_FILENAME_SIZE;

+  unsigned int position = 0;

+

+  if (!m_reader.readFileUploadRqst(&nameSize, szName, &position)) return false;

+

+  if (!convertPathFromNet(szName)) return false;

+

+  if (m_bUploadStarted) {

+    char reason[] = "The upload is already started";

+    m_writer.writeFileLastRqstFailed(msgTypeFileUploadRequest, strlen(reason), reason);

+    return false;

+  }

+

+  if (!m_fileWriter.create(szName)) {

+    char reason[] = "Can't create local file";

+    m_writer.writeFileLastRqstFailed(msgTypeFileUploadRequest, strlen(reason), reason);

+    return true;

+  }

+

+  m_bUploadStarted = true;

+

+  return true;

+}

+

+bool 

+SFileTransfer::processFileUploadData()

+{

+  unsigned int dataSize = 0;

+  unsigned int modTime = 0;

+

+  void *pUploadData = m_reader.readFileUploadData(&dataSize, &modTime);

+

+  if (!m_bUploadStarted) {

+      char reason[] = "Upload is impossible";

+      m_writer.writeFileUploadCancel(strlen(reason), reason);

+  } else {

+    if (pUploadData == NULL) {

+      if (modTime == 0) {

+        char reason[] = "Upload failed";

+        m_writer.writeFileUploadCancel(strlen(reason), reason);

+      } else {

+        m_fileWriter.setTime(modTime);

+      }

+      m_fileWriter.close();

+      m_bUploadStarted = false;

+    } else {

+      unsigned int dataWritten = 0;

+      m_fileWriter.write(pUploadData, dataSize, &dataWritten);

+      if (dataWritten != dataSize) {

+        char reason[] = "Upload failed";

+        m_writer.writeFileUploadCancel(strlen(reason), reason);

+        m_fileWriter.close();

+        m_bUploadStarted = false;

+      }

+    }

+  }

+  delete [] pUploadData;

+  return true;

+}

+

+bool 

+SFileTransfer::processFileDownloadCancel()

+{

+  char szReason[FT_FILENAME_SIZE] = {0};

+  unsigned int reasonSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileDownloadCancel(&reasonSize, szReason)) return false;

+

+  m_fileReader.close();

+  m_bDownloadStarted = false;

+  return true;

+}

+

+bool 

+SFileTransfer::processFileUploadFailed()

+{

+  char szReason[FT_FILENAME_SIZE] = {0};

+  unsigned int reasonSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileUploadFailed(&reasonSize, szReason)) return false;

+

+  deleteIt(m_fileWriter.getFilename());

+  m_fileWriter.close();

+  m_bUploadStarted = false;

+  return true;

+}

+

+bool 

+SFileTransfer::processFileCreateDirRequest()

+{

+  char szName[FT_FILENAME_SIZE] = {0};

+  unsigned int nameSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileCreateDirRqst(&nameSize, szName)) return false;

+

+  if (!convertPathFromNet(szName)) return false;

+

+  return createDir(szName);

+}

+

+bool 

+SFileTransfer::processFileDirSizeRequest()

+{

+  char szName[FT_FILENAME_SIZE] = {0};

+  unsigned int nameSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileDirSizeRqst(&nameSize, szName)) return false;

+

+  if (!convertPathFromNet(szName)) return false;

+

+  unsigned short highSize16 = 0;

+  unsigned int lowSize32 = 0;

+

+  if (!getDirSize(szName, &highSize16, &lowSize32)) return false;

+

+  return m_writer.writeFileDirSizeData(lowSize32, highSize16);

+}

+

+bool 

+SFileTransfer::processFileRenameRequest()

+{

+  char szOldName[FT_FILENAME_SIZE] = {0};

+  char szNewName[FT_FILENAME_SIZE] = {0};

+

+  unsigned int oldNameSize = FT_FILENAME_SIZE;

+  unsigned int newNameSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileRenameRqst(&oldNameSize, &newNameSize, szOldName, szNewName)) return false;

+

+  if ((!convertPathFromNet(szOldName)) || (!convertPathFromNet(szNewName))) return false;

+

+  return renameIt(szOldName, szNewName);

+}

+

+bool 

+SFileTransfer::processFileDeleteRequest()

+{

+  char szName[FT_FILENAME_SIZE] = {0};

+  unsigned int nameSize = FT_FILENAME_SIZE;

+

+  if (!m_reader.readFileDeleteRqst(&nameSize, szName)) return false;

+

+  if (!convertPathFromNet(szName)) return false;

+

+  return deleteIt(szName);

+}

+

+bool 

+SFileTransfer::convertPathFromNet(char *pszPath)

+{

+  return true;

+}

+

+bool 

+SFileTransfer::makeFileList(char *pszPath, FileInfo *pFI, bool bDirOnly)

+{

+  return false;

+}

+

+bool 

+SFileTransfer::deleteIt(char *pszPath)

+{

+  return false;

+}

+

+bool 

+SFileTransfer::renameIt(char *pszOldPath, char *pszNewPath)

+{

+  return false;

+}

+

+bool 

+SFileTransfer::createDir(char *pszPath)

+{

+  return false;

+}

+

+bool 

+SFileTransfer::getDirSize(char *pszName, unsigned short *pHighSize16, 

+                          unsigned int *pLowSize32)

+{

+  return false;

+}

+

+bool

+SFileTransfer::initDownloadCallback()

+{

+  return false;

+}