| /* 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. |
| * |
| * |
| * |
| */ |
| |
| // -=- SFileTransfer.cxx |
| |
| #include <rfb/msgTypes.h> |
| #include <rfb/SFileTransfer.h> |
| |
| using namespace rfb; |
| |
| SFileTransfer::SFileTransfer(network::Socket *sock) : |
| m_bUploadStarted(false), m_bDownloadStarted(false), |
| m_reader(&sock->inStream()), m_writer(&sock->outStream()), m_pSocket(sock) |
| { |
| } |
| |
| 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)) { |
| flags = (flags | 0x80); |
| } |
| 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; |
| |
| char *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; |
| } |