diff options
Diffstat (limited to 'libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c')
-rw-r--r-- | libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c | 988 |
1 files changed, 988 insertions, 0 deletions
diff --git a/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c new file mode 100644 index 0000000..d9165ef --- /dev/null +++ b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c @@ -0,0 +1,988 @@ +/* + * Copyright (c) 2005 Novell, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program 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 program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com + * + * Author : Rohit Kumar + * Email ID : rokumar@novell.com + * Date : 14th July 2005 + */ + +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <dirent.h> +#include <pthread.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <limits.h> + +#include <rfb/rfb.h> +#include "rfbtightproto.h" +#include "filetransfermsg.h" +#include "handlefiletransferrequest.h" + + +pthread_mutex_t fileDownloadMutex = PTHREAD_MUTEX_INITIALIZER; + +rfbBool fileTransferEnabled = TRUE; +rfbBool fileTransferInitted = FALSE; +char ftproot[PATH_MAX]; + + +/****************************************************************************** + * File Transfer Init methods. These methods are called for initializating + * File Transfer and setting ftproot. + ******************************************************************************/ + +void InitFileTransfer(); +int SetFtpRoot(char* path); +char* GetHomeDir(uid_t uid); +void FreeHomeDir(char *homedir); + +/* + * InitFileTransfer method is called before parsing the command-line options + * for Xvnc. This sets the ftproot to the Home dir of the user running the Xvnc + * server. In case of error ftproot is set to '\0' char. + */ + +void +InitFileTransfer() +{ + char* userHome = NULL; + uid_t uid = geteuid(); + + if(fileTransferInitted) + return; + + memset(ftproot, 0, sizeof(ftproot)); + + userHome = GetHomeDir(uid); + + if((userHome != NULL) && (strlen(userHome) != 0)) { + SetFtpRoot(userHome); + FreeHomeDir(userHome); + } + + fileTransferEnabled = TRUE; + fileTransferInitted = TRUE; +} + + +/* + * This method is called from InitFileTransfer method and + * if the command line option for ftproot is provided. + */ +int +SetFtpRoot(char* path) +{ + struct stat stat_buf; + DIR* dir = NULL; + + if((path == NULL) || (strlen(path) == 0) || (strlen(path) > (PATH_MAX - 1))) { + rfbLog("File [%s]: Method [%s]: parameter passed is improper, ftproot" + " not changed\n", __FILE__, __FUNCTION__); + return FALSE; + } + + if(stat(path, &stat_buf) < 0) { + rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n", + __FILE__, __FUNCTION__, path); + return FALSE; + } + + if(S_ISDIR(stat_buf.st_mode) == 0) { + rfbLog("File [%s]: Method [%s]: path specified is not a directory\n", + __FILE__, __FUNCTION__); + return FALSE; + } + + if((dir = opendir(path)) == NULL) { + rfbLog("File [%s]: Method [%s]: Not able to open the directory\n", + __FILE__, __FUNCTION__); + return FALSE; + } + else { + closedir(dir); + dir = NULL; + } + + + memset(ftproot, 0, PATH_MAX); + if(path[strlen(path)-1] == '/') { + memcpy(ftproot, path, strlen(path)-1); + } + else + memcpy(ftproot, path, strlen(path)); + + + return TRUE; +} + + +/* + * Get the home directory for the user name + * param: username - name of the user for whom the home directory is required. + * returns: returns the home directory for the user, or null in case the entry + * is not found or any error. The returned string must be freed by calling the + * freehomedir function. +*/ +char* +GetHomeDir(uid_t uid) +{ + struct passwd *pwEnt = NULL; + char *homedir = NULL; + + pwEnt = getpwuid (uid); + if (pwEnt == NULL) + return NULL; + + if(pwEnt->pw_dir != NULL) { + homedir = strdup (pwEnt->pw_dir); + } + + return homedir; +} + + +/* + * Free the home directory allocated by a previous call to retrieve the home + * directory. param: homedir - the string returned by a previous call to + * retrieve home directory for a user. + */ +void +FreeHomeDir(char *homedir) +{ + free (homedir); +} + + +/****************************************************************************** + * General methods. + ******************************************************************************/ + +/* + * When the console sends the File Transfer Request, it sends the file path with + * ftproot as "/". So on Agent, to get the absolute file path we need to prepend + * the ftproot to it. + */ +char* +ConvertPath(char* path) +{ + char p[PATH_MAX]; + memset(p, 0, PATH_MAX); + + if( (path == NULL) || + (strlen(path) == 0) || + (strlen(path)+strlen(ftproot) > PATH_MAX - 1) ) { + + rfbLog("File [%s]: Method [%s]: cannot create path for file transfer\n", + __FILE__, __FUNCTION__); + return NULL; + } + + memcpy(p, path, strlen(path)); + memset(path, 0, PATH_MAX); + sprintf(path, "%s%s", ftproot, p); + + return path; +} + + +void +EnableFileTransfer(rfbBool enable) +{ + fileTransferEnabled = enable; +} + + +rfbBool +IsFileTransferEnabled() +{ + return fileTransferEnabled; +} + + +char* +GetFtpRoot() +{ + return ftproot; +} + + +/****************************************************************************** + * Methods to Handle File List Request. + ******************************************************************************/ + +/* + * HandleFileListRequest method is called when the server receives + * FileListRequest. In case of success a file list is sent to the client. + * For File List Request there is no failure reason sent.So here in case of any + * "unexpected" error no information will be sent. As these conditions should + * never come. Lets hope it never arrives :) + * In case of dir open failure an empty list will be sent, just the header of + * the message filled up. So on console you will get an Empty listing. + */ +void +HandleFileListRequest(rfbClientPtr cl, rfbTightClientRec* data) +{ + rfbClientToServerTightMsg msg; + int n = 0; + char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */ + FileTransferMsg fileListMsg; + + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + memset(path, 0, PATH_MAX); + memset(&fileListMsg, 0, sizeof(FileTransferMsg)); + + if(cl == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileListRequestMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Socket error while reading dir name" + " length\n", __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.flr.dirNameSize = Swap16IfLE(msg.flr.dirNameSize); + if ((msg.flr.dirNameSize == 0) || + (msg.flr.dirNameSize > (PATH_MAX - 1))) { + + rfbLog("File [%s]: Method [%s]: Unexpected error:: path length is " + "greater that PATH_MAX\n", __FILE__, __FUNCTION__); + + return; + } + + if((n = rfbReadExact(cl, path, msg.flr.dirNameSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Socket error while reading dir name\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + if(ConvertPath(path) == NULL) { + + /* The execution should never reach here */ + rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL", + __FILE__, __FUNCTION__); + return; + } + + fileListMsg = GetFileListResponseMsg(path, (char) (msg.flr.flags)); + + if((fileListMsg.data == NULL) || (fileListMsg.length == 0)) { + + rfbLog("File [%s]: Method [%s]: Unexpected error:: Data to be sent is " + "of Zero length\n", __FILE__, __FUNCTION__); + return; + } + + rfbWriteExact(cl, fileListMsg.data, fileListMsg.length); + + FreeFileTransferMsg(fileListMsg); +} + + +/****************************************************************************** + * Methods to Handle File Download Request. + ******************************************************************************/ + +void HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize); +void SendFileDownloadLengthErrMsg(rfbClientPtr cl); +void HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr data); +#ifdef TODO +void HandleFileDownloadRequest(rfbClientPtr cl); +void SendFileDownloadErrMsg(rfbClientPtr cl); +void* RunFileDownloadThread(void* client); +#endif + +/* + * HandleFileDownloadRequest method is called when the server receives + * rfbFileDownload request message. + */ +void +HandleFileDownloadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */ + rfbClientToServerTightMsg msg; + + memset(path, 0, sizeof(path)); + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if(cl == NULL) { + + rfbLog("File [%s]: Method [%s]: Unexpected error:: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadRequestMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fdr.fNameSize = Swap16IfLE(msg.fdr.fNameSize); + msg.fdr.position = Swap16IfLE(msg.fdr.position); + + if ((msg.fdr.fNameSize == 0) || + (msg.fdr.fNameSize > (PATH_MAX - 1))) { + + rfbLog("File [%s]: Method [%s]: Error: path length is greater than" + " PATH_MAX\n", __FILE__, __FUNCTION__); + + HandleFileDownloadLengthError(cl, msg.fdr.fNameSize); + return; + } + + if((n = rfbReadExact(cl, rtcp->rcft.rcfd.fName, msg.fdr.fNameSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + rtcp->rcft.rcfd.fName[msg.fdr.fNameSize] = '\0'; + + if(ConvertPath(rtcp->rcft.rcfd.fName) == NULL) { + + rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL", + __FILE__, __FUNCTION__); + + + /* This condition can come only if the file path is greater than + PATH_MAX. So sending file path length error msg back to client. + */ + + SendFileDownloadLengthErrMsg(cl); + return; + } + + HandleFileDownload(cl, rtcp); + +} + + +void +HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize) +{ + char *path = NULL; + int n = 0; + + if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) { + rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n", + __FILE__, __FUNCTION__); + return; + } + if((n = rfbReadExact(cl, path, fNameSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading dir name\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + + if(path != NULL) { + free(path); + path = NULL; + } + + return; + } + + if(path != NULL) { + free(path); + path = NULL; + } + + SendFileDownloadLengthErrMsg(cl); +} + + +void +SendFileDownloadLengthErrMsg(rfbClientPtr cl) +{ + FileTransferMsg fileDownloadErrMsg; + + memset(&fileDownloadErrMsg, 0 , sizeof(FileTransferMsg)); + + fileDownloadErrMsg = GetFileDownloadLengthErrResponseMsg(); + + if((fileDownloadErrMsg.data == NULL) || (fileDownloadErrMsg.length == 0)) { + rfbLog("File [%s]: Method [%s]: Unexpected error: fileDownloadErrMsg " + "is null\n", __FILE__, __FUNCTION__); + return; + } + + rfbWriteExact(cl, fileDownloadErrMsg.data, fileDownloadErrMsg.length); + + FreeFileTransferMsg(fileDownloadErrMsg); +} + +extern rfbTightClientPtr rfbGetTightClientData(rfbClientPtr cl); + +void* +RunFileDownloadThread(void* client) +{ + rfbClientPtr cl = (rfbClientPtr) client; + rfbTightClientPtr rtcp = rfbGetTightClientData(cl); + FileTransferMsg fileDownloadMsg; + + if(rtcp == NULL) + return NULL; + + memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg)); + do { + pthread_mutex_lock(&fileDownloadMutex); + fileDownloadMsg = GetFileDownloadResponseMsgInBlocks(cl, rtcp); + pthread_mutex_unlock(&fileDownloadMutex); + + if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) { + if(rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length) < 0) { + rfbLog("File [%s]: Method [%s]: Error while writing to socket \n" + , __FILE__, __FUNCTION__); + + if(cl != NULL) { + rfbCloseClient(cl); + CloseUndoneFileTransfer(cl, rtcp); + } + + FreeFileTransferMsg(fileDownloadMsg); + return NULL; + } + FreeFileTransferMsg(fileDownloadMsg); + } + } while(rtcp->rcft.rcfd.downloadInProgress == TRUE); + return NULL; +} + + +void +HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + pthread_t fileDownloadThread; + FileTransferMsg fileDownloadMsg; + + memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg)); + fileDownloadMsg = ChkFileDownloadErr(cl, rtcp); + if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) { + rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length); + FreeFileTransferMsg(fileDownloadMsg); + return; + } + rtcp->rcft.rcfd.downloadInProgress = FALSE; + rtcp->rcft.rcfd.downloadFD = -1; + + if(pthread_create(&fileDownloadThread, NULL, RunFileDownloadThread, (void*) + cl) != 0) { + FileTransferMsg ftm = GetFileDownLoadErrMsg(); + + rfbLog("File [%s]: Method [%s]: Download thread creation failed\n", + __FILE__, __FUNCTION__); + + if((ftm.data != NULL) && (ftm.length != 0)) { + rfbWriteExact(cl, ftm.data, ftm.length); + FreeFileTransferMsg(ftm); + return; + } + + } + +} + + +/****************************************************************************** + * Methods to Handle File Download Cancel Request. + ******************************************************************************/ + + +void +HandleFileDownloadCancelRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char *reason = NULL; + rfbClientToServerTightMsg msg; + + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadCancelMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading " + "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fdc.reasonLen = Swap16IfLE(msg.fdc.reasonLen); + + if(msg.fdc.reasonLen == 0) { + rfbLog("File [%s]: Method [%s]: reason length received is Zero\n", + __FILE__, __FUNCTION__); + return; + } + + reason = (char*) calloc(msg.fdc.reasonLen + 1, sizeof(char)); + if(reason == NULL) { + rfbLog("File [%s]: Method [%s]: Fatal Error: Memory alloc failed\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, reason, msg.fdc.reasonLen)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading " + "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + } + + rfbLog("File [%s]: Method [%s]: File Download Cancel Request received:" + " reason <%s>\n", __FILE__, __FUNCTION__, reason); + + pthread_mutex_lock(&fileDownloadMutex); + CloseUndoneFileTransfer(cl, rtcp); + pthread_mutex_unlock(&fileDownloadMutex); + + if(reason != NULL) { + free(reason); + reason = NULL; + } + +} + + +/****************************************************************************** + * Methods to Handle File upload request + ******************************************************************************/ + +#ifdef TODO +void HandleFileUploadRequest(rfbClientPtr cl); +#endif +void HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr data); +void HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize); +void SendFileUploadLengthErrMsg(rfbClientPtr cl); + + +void +HandleFileUploadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */ + rfbClientToServerTightMsg msg; + + memset(path, 0, PATH_MAX); + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if(cl == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadRequestMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fupr.fNameSize = Swap16IfLE(msg.fupr.fNameSize); + msg.fupr.position = Swap16IfLE(msg.fupr.position); + + if ((msg.fupr.fNameSize == 0) || + (msg.fupr.fNameSize > (PATH_MAX - 1))) { + + rfbLog("File [%s]: Method [%s]: error: path length is greater than PATH_MAX\n", + __FILE__, __FUNCTION__); + HandleFileUploadLengthError(cl, msg.fupr.fNameSize); + return; + } + + if((n = rfbReadExact(cl, rtcp->rcft.rcfu.fName, msg.fupr.fNameSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n" + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + rtcp->rcft.rcfu.fName[msg.fupr.fNameSize] = '\0'; + + if(ConvertPath(rtcp->rcft.rcfu.fName) == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n", + __FILE__, __FUNCTION__); + + /* This may come if the path length exceeds PATH_MAX. + So sending path length error to client + */ + SendFileUploadLengthErrMsg(cl); + return; + } + + HandleFileUpload(cl, rtcp); +} + + +void +HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize) +{ + char *path = NULL; + int n = 0; + + if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) { + rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n", + __FILE__, __FUNCTION__); + return; + } + if((n = rfbReadExact(cl, path, fNameSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading dir name\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + + if(path != NULL) { + free(path); + path = NULL; + } + + return; + } + + rfbLog("File [%s]: Method [%s]: File Upload Length Error occured" + "file path requested is <%s>\n", __FILE__, __FUNCTION__, path); + + if(path != NULL) { + free(path); + path = NULL; + } + + SendFileUploadLengthErrMsg(cl); +} + +void +SendFileUploadLengthErrMsg(rfbClientPtr cl) +{ + + FileTransferMsg fileUploadErrMsg; + + memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg)); + fileUploadErrMsg = GetFileUploadLengthErrResponseMsg(); + + if((fileUploadErrMsg.data == NULL) || (fileUploadErrMsg.length == 0)) { + rfbLog("File [%s]: Method [%s]: Unexpected error: fileUploadErrMsg is null\n", + __FILE__, __FUNCTION__); + return; + } + + rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length); + FreeFileTransferMsg(fileUploadErrMsg); +} + +void +HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + FileTransferMsg fileUploadErrMsg; + + memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg)); + + rtcp->rcft.rcfu.uploadInProgress = FALSE; + rtcp->rcft.rcfu.uploadFD = -1; + + fileUploadErrMsg = ChkFileUploadErr(cl, rtcp); + if((fileUploadErrMsg.data != NULL) && (fileUploadErrMsg.length != 0)) { + rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length); + FreeFileTransferMsg(fileUploadErrMsg); + } +} + + +/****************************************************************************** + * Methods to Handle File Upload Data Request + *****************************************************************************/ + +void HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf); + + +void +HandleFileUploadDataRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char* pBuf = NULL; + rfbClientToServerTightMsg msg; + + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if(cl == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadDataMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fud.realSize = Swap16IfLE(msg.fud.realSize); + msg.fud.compressedSize = Swap16IfLE(msg.fud.compressedSize); + if((msg.fud.realSize == 0) && (msg.fud.compressedSize == 0)) { + if((n = rfbReadExact(cl, (char*)&(rtcp->rcft.rcfu.mTime), sizeof(unsigned + long))) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + FileUpdateComplete(cl, rtcp); + return; + } + + pBuf = (char*) calloc(msg.fud.compressedSize, sizeof(char)); + if(pBuf == NULL) { + rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__); + return; + } + if((n = rfbReadExact(cl, pBuf, msg.fud.compressedSize)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + + if(pBuf != NULL) { + free(pBuf); + pBuf = NULL; + } + + return; + } + if(msg.fud.compressedLevel != 0) { + FileTransferMsg ftm; + memset(&ftm, 0, sizeof(FileTransferMsg)); + + ftm = GetFileUploadCompressedLevelErrMsg(); + + if((ftm.data != NULL) && (ftm.length != 0)) { + rfbWriteExact(cl, ftm.data, ftm.length); + FreeFileTransferMsg(ftm); + } + + CloseUndoneFileTransfer(cl, rtcp); + + if(pBuf != NULL) { + free(pBuf); + pBuf = NULL; + } + + return; + } + + rtcp->rcft.rcfu.fSize = msg.fud.compressedSize; + + HandleFileUploadWrite(cl, rtcp, pBuf); + + if(pBuf != NULL) { + free(pBuf); + pBuf = NULL; + } + +} + + +void +HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf) +{ + FileTransferMsg ftm; + memset(&ftm, 0, sizeof(FileTransferMsg)); + + ftm = ChkFileUploadWriteErr(cl, rtcp, pBuf); + + if((ftm.data != NULL) && (ftm.length != 0)) { + rfbWriteExact(cl, ftm.data, ftm.length); + FreeFileTransferMsg(ftm); + } +} + + +/****************************************************************************** + * Methods to Handle File Upload Failed Request. + ******************************************************************************/ + + +void +HandleFileUploadFailedRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char* reason = NULL; + rfbClientToServerTightMsg msg; + + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if(cl == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadFailedMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fuf.reasonLen = Swap16IfLE(msg.fuf.reasonLen); + if(msg.fuf.reasonLen == 0) { + rfbLog("File [%s]: Method [%s]: reason length received is Zero\n", + __FILE__, __FUNCTION__); + return; + } + + + reason = (char*) calloc(msg.fuf.reasonLen + 1, sizeof(char)); + if(reason == NULL) { + rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, reason, msg.fuf.reasonLen)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + + if(reason != NULL) { + free(reason); + reason = NULL; + } + + return; + } + + rfbLog("File [%s]: Method [%s]: File Upload Failed Request received:" + " reason <%s>\n", __FILE__, __FUNCTION__, reason); + + CloseUndoneFileTransfer(cl, rtcp); + + if(reason != NULL) { + free(reason); + reason = NULL; + } + +} + + +/****************************************************************************** + * Methods to Handle File Create Request. + ******************************************************************************/ + + +void +HandleFileCreateDirRequest(rfbClientPtr cl, rfbTightClientPtr rtcp) +{ + int n = 0; + char dirName[PATH_MAX]; + rfbClientToServerTightMsg msg; + + memset(dirName, 0, PATH_MAX); + memset(&msg, 0, sizeof(rfbClientToServerTightMsg)); + + if(cl == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n", + __FILE__, __FUNCTION__); + return; + } + + if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileCreateDirRequestMsg-1)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileCreateDirRequestMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + msg.fcdr.dNameLen = Swap16IfLE(msg.fcdr.dNameLen); + + /* TODO :: chk if the dNameLen is greater than PATH_MAX */ + + if((n = rfbReadExact(cl, dirName, msg.fcdr.dNameLen)) <= 0) { + + if (n < 0) + rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n", + __FILE__, __FUNCTION__); + + rfbCloseClient(cl); + return; + } + + if(ConvertPath(dirName) == NULL) { + rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n", + __FILE__, __FUNCTION__); + + return; + } + + CreateDirectory(dirName); +} + + |