Home | History | Annotate | Download | only in tightvnc-filetransfer
      1 /*
      2  * Copyright (c) 2005 Novell, Inc.
      3  * All Rights Reserved.
      4  *
      5  * This program is free software; you can redistribute it and/or
      6  * modify it under the terms of version 2 of the GNU General Public License as
      7  * published by the Free Software Foundation.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, contact Novell, Inc.
     16  *
     17  * To contact Novell about this file by physical or electronic mail,
     18  * you may find current contact information at www.novell.com
     19  *
     20  * Author		: Rohit Kumar
     21  * Email ID	: rokumar (at) novell.com
     22  * Date		: 14th July 2005
     23  */
     24 
     25 
     26 #include <stdio.h>
     27 #include <string.h>
     28 #include <stdlib.h>
     29 #include <fcntl.h>
     30 #include <dirent.h>
     31 #include <utime.h>
     32 #include <errno.h>
     33 #include <unistd.h>
     34 #include <sys/stat.h>
     35 #include <sys/types.h>
     36 
     37 #include <rfb/rfb.h>
     38 #include "rfbtightproto.h"
     39 #include "filelistinfo.h"
     40 #include "filetransfermsg.h"
     41 #include "handlefiletransferrequest.h"
     42 
     43 #define SZ_RFBBLOCKSIZE 8192
     44 
     45 
     46 void
     47 FreeFileTransferMsg(FileTransferMsg ftm)
     48 {
     49 
     50 	if(ftm.data != NULL) {
     51 		free(ftm.data);
     52 		ftm.data = NULL;
     53 	}
     54 
     55 	ftm.length = 0;
     56 
     57 }
     58 
     59 
     60 /******************************************************************************
     61  * Methods to handle file list request.
     62  ******************************************************************************/
     63 
     64 int CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag);
     65 FileTransferMsg CreateFileListErrMsg(char flags);
     66 FileTransferMsg CreateFileListMsg(FileListInfo fileListInfo, char flags);
     67 
     68 
     69 /*
     70  * This is the method called by HandleFileListRequest to get the file list
     71  */
     72 
     73 FileTransferMsg
     74 GetFileListResponseMsg(char* path, char flags)
     75 {
     76 	FileTransferMsg fileListMsg;
     77 	FileListInfo fileListInfo;
     78 	int status = -1;
     79 
     80 	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
     81 	memset(&fileListInfo, 0, sizeof(FileListInfo));
     82 
     83 
     84 	 /* fileListInfo can have null data if the folder is Empty
     85     	or if some error condition has occured.
     86     	The return value is 'failure' only if some error condition has occured.
     87 	 */
     88 	status = CreateFileListInfo(&fileListInfo, path, !(flags  & 0x10));
     89 
     90 	if(status == FAILURE) {
     91 		fileListMsg = CreateFileListErrMsg(flags);
     92 	}
     93 	else {
     94 		/* DisplayFileList(fileListInfo); For Debugging  */
     95 
     96 		fileListMsg = CreateFileListMsg(fileListInfo, flags);
     97 		FreeFileListInfo(fileListInfo);
     98 	}
     99 
    100 	return fileListMsg;
    101 }
    102 
    103 #ifndef __GNUC__
    104 #define __FUNCTION__ "unknown"
    105 #endif
    106 
    107 int
    108 CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag)
    109 {
    110 	DIR* pDir = NULL;
    111 	struct dirent* pDirent = NULL;
    112 
    113 	if((path == NULL) || (strlen(path) == 0)) {
    114 		/* In this case we will send the list of entries in ftp root*/
    115 		sprintf(path, "%s%s", GetFtpRoot(), "/");
    116 	}
    117 
    118 	if((pDir = opendir(path)) == NULL) {
    119 		rfbLog("File [%s]: Method [%s]: not able to open the dir\n",
    120 				__FILE__, __FUNCTION__);
    121 		return FAILURE;
    122 	}
    123 
    124 	while((pDirent = readdir(pDir))) {
    125 		if(strcmp(pDirent->d_name, ".") && strcmp(pDirent->d_name, "..")) {
    126 			struct stat stat_buf;
    127 			/*
    128 			int fpLen = sizeof(char)*(strlen(pDirent->d_name)+strlen(path)+2);
    129 			*/
    130 			char fullpath[PATH_MAX];
    131 
    132 			memset(fullpath, 0, PATH_MAX);
    133 
    134 			strcpy(fullpath, path);
    135 			if(path[strlen(path)-1] != '/')
    136 				strcat(fullpath, "/");
    137 			strcat(fullpath, pDirent->d_name);
    138 
    139 			if(stat(fullpath, &stat_buf) < 0) {
    140 				rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n",
    141 						__FILE__, __FUNCTION__, fullpath);
    142 				continue;
    143 			}
    144 
    145 			if(S_ISDIR(stat_buf.st_mode)) {
    146 				if(AddFileListItemInfo(pFileListInfo, pDirent->d_name, -1, 0) == 0) {
    147 					rfbLog("File [%s]: Method [%s]: Add directory %s in the"
    148 							" list failed\n", __FILE__, __FUNCTION__, fullpath);
    149 					continue;
    150 				}
    151 			}
    152 			else {
    153 				if(flag) {
    154 					if(AddFileListItemInfo(pFileListInfo, pDirent->d_name,
    155 												stat_buf.st_size,
    156 												stat_buf.st_mtime) == 0) {
    157 						rfbLog("File [%s]: Method [%s]: Add file %s in the "
    158 								"list failed\n", __FILE__, __FUNCTION__, fullpath);
    159 						continue;
    160 					}
    161 				}
    162 			}
    163 		}
    164 	}
    165 	if(closedir(pDir) < 0) {
    166 	    rfbLog("File [%s]: Method [%s]: ERROR Couldn't close dir\n",
    167 	    	__FILE__, __FUNCTION__);
    168 	}
    169 
    170 	return SUCCESS;
    171 }
    172 
    173 
    174 FileTransferMsg
    175 CreateFileListErrMsg(char flags)
    176 {
    177 	FileTransferMsg fileListMsg;
    178 	rfbFileListDataMsg* pFLD = NULL;
    179 	char* data = NULL;
    180 	unsigned int length = 0;
    181 
    182 	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
    183 
    184 	data = (char*) calloc(sizeof(rfbFileListDataMsg), sizeof(char));
    185 	if(data == NULL) {
    186 		return fileListMsg;
    187 	}
    188 	length = sizeof(rfbFileListDataMsg) * sizeof(char);
    189 	pFLD = (rfbFileListDataMsg*) data;
    190 
    191 	pFLD->type = rfbFileListData;
    192 	pFLD->numFiles = Swap16IfLE(0);
    193 	pFLD->dataSize = Swap16IfLE(0);
    194 	pFLD->compressedSize = Swap16IfLE(0);
    195 	pFLD->flags = flags | 0x80;
    196 
    197 	fileListMsg.data = data;
    198 	fileListMsg.length = length;
    199 
    200 	return fileListMsg;
    201 }
    202 
    203 
    204 FileTransferMsg
    205 CreateFileListMsg(FileListInfo fileListInfo, char flags)
    206 {
    207 	FileTransferMsg fileListMsg;
    208 	rfbFileListDataMsg* pFLD = NULL;
    209 	char *data = NULL, *pFileNames = NULL;
    210 	unsigned int length = 0, dsSize = 0, i = 0;
    211 	FileListItemSizePtr pFileListItemSize = NULL;
    212 
    213 	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
    214 	dsSize = fileListInfo.numEntries * 8;
    215 	length = sz_rfbFileListDataMsg + dsSize +
    216 			GetSumOfFileNamesLength(fileListInfo) +
    217 			fileListInfo.numEntries;
    218 
    219 	data = (char*) calloc(length, sizeof(char));
    220 	if(data == NULL) {
    221 		return fileListMsg;
    222 	}
    223 	pFLD = (rfbFileListDataMsg*) data;
    224 	pFileListItemSize = (FileListItemSizePtr) &data[sz_rfbFileListDataMsg];
    225 	pFileNames = &data[sz_rfbFileListDataMsg + dsSize];
    226 
    227 	pFLD->type            = rfbFileListData;
    228     pFLD->flags 		  = flags & 0xF0;
    229     pFLD->numFiles 		  = Swap16IfLE(fileListInfo.numEntries);
    230     pFLD->dataSize 		  = Swap16IfLE(GetSumOfFileNamesLength(fileListInfo) +
    231     									fileListInfo.numEntries);
    232     pFLD->compressedSize  = pFLD->dataSize;
    233 
    234 	for(i =0; i <fileListInfo.numEntries; i++) {
    235 		pFileListItemSize[i].size = Swap32IfLE(GetFileSizeAt(fileListInfo, i));
    236 		pFileListItemSize[i].data = Swap32IfLE(GetFileDataAt(fileListInfo, i));
    237 		strcpy(pFileNames, GetFileNameAt(fileListInfo, i));
    238 
    239 		if(i+1 < fileListInfo.numEntries)
    240 			pFileNames += strlen(pFileNames) + 1;
    241 	}
    242 
    243 	fileListMsg.data 	= data;
    244 	fileListMsg.length 	= length;
    245 
    246 	return fileListMsg;
    247 }
    248 
    249 
    250 /******************************************************************************
    251  * Methods to handle File Download Request.
    252  ******************************************************************************/
    253 
    254 FileTransferMsg CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen);
    255 FileTransferMsg CreateFileDownloadZeroSizeDataMsg(unsigned long mTime);
    256 FileTransferMsg CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile);
    257 
    258 FileTransferMsg
    259 GetFileDownLoadErrMsg()
    260 {
    261 	FileTransferMsg fileDownloadErrMsg;
    262 
    263 	char reason[] = "An internal error on the server caused download failure";
    264 	int reasonLen = strlen(reason);
    265 
    266 	memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
    267 
    268 	fileDownloadErrMsg = CreateFileDownloadErrMsg(reason, reasonLen);
    269 
    270 	return fileDownloadErrMsg;
    271 }
    272 
    273 
    274 FileTransferMsg
    275 GetFileDownloadReadDataErrMsg()
    276 {
    277 	char reason[] = "Cannot open file, perhaps it is absent or is a directory";
    278 	int reasonLen = strlen(reason);
    279 
    280 	return CreateFileDownloadErrMsg(reason, reasonLen);
    281 
    282 }
    283 
    284 
    285 FileTransferMsg
    286 GetFileDownloadLengthErrResponseMsg()
    287 {
    288 	char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
    289 	int reasonLen = strlen(reason);
    290 
    291 	return CreateFileDownloadErrMsg(reason, reasonLen);
    292 }
    293 
    294 
    295 FileTransferMsg
    296 GetFileDownloadResponseMsgInBlocks(rfbClientPtr cl, rfbTightClientPtr rtcp)
    297 {
    298 	/* const unsigned int sz_rfbBlockSize = SZ_RFBBLOCKSIZE; */
    299     int numOfBytesRead = 0;
    300 	char pBuf[SZ_RFBBLOCKSIZE];
    301 	char* path = rtcp->rcft.rcfd.fName;
    302 
    303 	memset(pBuf, 0, SZ_RFBBLOCKSIZE);
    304 
    305 	if((rtcp->rcft.rcfd.downloadInProgress == FALSE) && (rtcp->rcft.rcfd.downloadFD == -1)) {
    306 		if((rtcp->rcft.rcfd.downloadFD = open(path, O_RDONLY)) == -1) {
    307 			rfbLog("File [%s]: Method [%s]: Error: Couldn't open file\n",
    308 					__FILE__, __FUNCTION__);
    309 			return GetFileDownloadReadDataErrMsg();
    310 		}
    311 		rtcp->rcft.rcfd.downloadInProgress = TRUE;
    312 	}
    313 	if((rtcp->rcft.rcfd.downloadInProgress == TRUE) && (rtcp->rcft.rcfd.downloadFD != -1)) {
    314 		if( (numOfBytesRead = read(rtcp->rcft.rcfd.downloadFD, pBuf, SZ_RFBBLOCKSIZE)) <= 0) {
    315 			close(rtcp->rcft.rcfd.downloadFD);
    316 			rtcp->rcft.rcfd.downloadFD = -1;
    317 			rtcp->rcft.rcfd.downloadInProgress = FALSE;
    318 			if(numOfBytesRead == 0) {
    319 				return CreateFileDownloadZeroSizeDataMsg(rtcp->rcft.rcfd.mTime);
    320 			}
    321 			return GetFileDownloadReadDataErrMsg();
    322 		}
    323 	return CreateFileDownloadBlockSizeDataMsg(numOfBytesRead, pBuf);
    324 	}
    325 	return GetFileDownLoadErrMsg();
    326 }
    327 
    328 
    329 FileTransferMsg
    330 ChkFileDownloadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
    331 {
    332     FileTransferMsg fileDownloadMsg;
    333 	struct stat stat_buf;
    334 	int sz_rfbFileSize = 0;
    335 	char* path = rtcp->rcft.rcfd.fName;
    336 
    337 	memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
    338 
    339 	if( (path == NULL) || (strlen(path) == 0) ||
    340 		(stat(path, &stat_buf) < 0) || (!(S_ISREG(stat_buf.st_mode))) ) {
    341 
    342 			char reason[] = "Cannot open file, perhaps it is absent or is not a regular file";
    343 			int reasonLen = strlen(reason);
    344 
    345 			rfbLog("File [%s]: Method [%s]: Reading stat for path %s failed\n",
    346 					__FILE__, __FUNCTION__, path);
    347 
    348 			fileDownloadMsg = CreateFileDownloadErrMsg(reason, reasonLen);
    349 	}
    350 	else {
    351 		rtcp->rcft.rcfd.mTime = stat_buf.st_mtime;
    352 		sz_rfbFileSize = stat_buf.st_size;
    353 		if(sz_rfbFileSize <= 0) {
    354 			fileDownloadMsg = CreateFileDownloadZeroSizeDataMsg(stat_buf.st_mtime);
    355 		}
    356 
    357 	}
    358 	return fileDownloadMsg;
    359 }
    360 
    361 
    362 FileTransferMsg
    363 CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen)
    364 {
    365 	FileTransferMsg fileDownloadErrMsg;
    366 	int length = sz_rfbFileDownloadFailedMsg + reasonLen + 1;
    367 	rfbFileDownloadFailedMsg *pFDF = NULL;
    368 	char *pFollow = NULL;
    369 
    370 	char *pData = (char*) calloc(length, sizeof(char));
    371 	memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
    372 	if(pData == NULL) {
    373 		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
    374 				__FILE__, __FUNCTION__);
    375 		return fileDownloadErrMsg;
    376 	}
    377 
    378 	pFDF = (rfbFileDownloadFailedMsg *) pData;
    379 	pFollow = &pData[sz_rfbFileDownloadFailedMsg];
    380 
    381 	pFDF->type = rfbFileDownloadFailed;
    382 	pFDF->reasonLen = Swap16IfLE(reasonLen);
    383 	memcpy(pFollow, reason, reasonLen);
    384 
    385 	fileDownloadErrMsg.data	= pData;
    386 	fileDownloadErrMsg.length	= length;
    387 
    388 	return fileDownloadErrMsg;
    389 }
    390 
    391 
    392 FileTransferMsg
    393 CreateFileDownloadZeroSizeDataMsg(unsigned long mTime)
    394 {
    395 	FileTransferMsg fileDownloadZeroSizeDataMsg;
    396 	int length = sz_rfbFileDownloadDataMsg + sizeof(unsigned long);
    397 	rfbFileDownloadDataMsg *pFDD = NULL;
    398 	char *pFollow = NULL;
    399 
    400 	char *pData = (char*) calloc(length, sizeof(char));
    401 	memset(&fileDownloadZeroSizeDataMsg, 0, sizeof(FileTransferMsg));
    402 	if(pData == NULL) {
    403 		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
    404 				__FILE__, __FUNCTION__);
    405 		return fileDownloadZeroSizeDataMsg;
    406 	}
    407 
    408 	pFDD = (rfbFileDownloadDataMsg *) pData;
    409 	pFollow = &pData[sz_rfbFileDownloadDataMsg];
    410 
    411 	pFDD->type = rfbFileDownloadData;
    412 	pFDD->compressLevel = 0;
    413 	pFDD->compressedSize = Swap16IfLE(0);
    414 	pFDD->realSize = Swap16IfLE(0);
    415 
    416 	memcpy(pFollow, &mTime, sizeof(unsigned long));
    417 
    418 	fileDownloadZeroSizeDataMsg.data	= pData;
    419 	fileDownloadZeroSizeDataMsg.length	= length;
    420 
    421 	return fileDownloadZeroSizeDataMsg;
    422 
    423 }
    424 
    425 
    426 FileTransferMsg
    427 CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile)
    428 {
    429 	FileTransferMsg fileDownloadBlockSizeDataMsg;
    430 	int length = sz_rfbFileDownloadDataMsg + sizeFile;
    431 	rfbFileDownloadDataMsg *pFDD = NULL;
    432 	char *pFollow = NULL;
    433 
    434 	char *pData = (char*) calloc(length, sizeof(char));
    435 	memset(&fileDownloadBlockSizeDataMsg, 0, sizeof(FileTransferMsg));
    436 	if(NULL == pData) {
    437 		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
    438 				__FILE__, __FUNCTION__);
    439 		return fileDownloadBlockSizeDataMsg;
    440 	}
    441 
    442 	pFDD = (rfbFileDownloadDataMsg *) pData;
    443 	pFollow = &pData[sz_rfbFileDownloadDataMsg];
    444 
    445 	pFDD->type = rfbFileDownloadData;
    446 	pFDD->compressLevel = 0;
    447 	pFDD->compressedSize = Swap16IfLE(sizeFile);
    448 	pFDD->realSize = Swap16IfLE(sizeFile);
    449 
    450 	memcpy(pFollow, pFile, sizeFile);
    451 
    452 	fileDownloadBlockSizeDataMsg.data	= pData;
    453 	fileDownloadBlockSizeDataMsg.length	= length;
    454 
    455 	return fileDownloadBlockSizeDataMsg;
    456 
    457 }
    458 
    459 
    460 /******************************************************************************
    461  * Methods to handle file upload request
    462  ******************************************************************************/
    463 
    464 FileTransferMsg CreateFileUploadErrMsg(char* reason, unsigned int reasonLen);
    465 
    466 FileTransferMsg
    467 GetFileUploadLengthErrResponseMsg()
    468 {
    469 	char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
    470 	int reasonLen = strlen(reason);
    471 
    472 	return CreateFileUploadErrMsg(reason, reasonLen);
    473 }
    474 
    475 
    476 FileTransferMsg
    477 ChkFileUploadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
    478 {
    479     FileTransferMsg fileUploadErrMsg;
    480 
    481 	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
    482 	if( (rtcp->rcft.rcfu.fName == NULL) ||
    483 		(strlen(rtcp->rcft.rcfu.fName) == 0) ||
    484 		((rtcp->rcft.rcfu.uploadFD = creat(rtcp->rcft.rcfu.fName,
    485 		S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1)) {
    486 
    487 			char reason[] = "Could not create file";
    488 			int reasonLen = strlen(reason);
    489 			fileUploadErrMsg = CreateFileUploadErrMsg(reason, reasonLen);
    490 	}
    491 	else
    492 		rtcp->rcft.rcfu.uploadInProgress = TRUE;
    493 
    494 	return fileUploadErrMsg;
    495 }
    496 
    497 
    498 FileTransferMsg
    499 GetFileUploadCompressedLevelErrMsg()
    500 {
    501 	char reason[] = "Server does not support data compression on upload";
    502 	int reasonLen = strlen(reason);
    503 
    504 	return CreateFileUploadErrMsg(reason, reasonLen);
    505 }
    506 
    507 
    508 FileTransferMsg
    509 ChkFileUploadWriteErr(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf)
    510 {
    511 	FileTransferMsg ftm;
    512 	unsigned long numOfBytesWritten = 0;
    513 
    514 	memset(&ftm, 0, sizeof(FileTransferMsg));
    515 
    516 	numOfBytesWritten = write(rtcp->rcft.rcfu.uploadFD, pBuf, rtcp->rcft.rcfu.fSize);
    517 
    518 	if(numOfBytesWritten != rtcp->rcft.rcfu.fSize) {
    519 		char reason[] = "Error writing file data";
    520 		int reasonLen = strlen(reason);
    521 		ftm = CreateFileUploadErrMsg(reason, reasonLen);
    522 		CloseUndoneFileTransfer(cl, rtcp);
    523 	}
    524 	return ftm;
    525 }
    526 
    527 
    528 void
    529 FileUpdateComplete(rfbClientPtr cl, rfbTightClientPtr rtcp)
    530 {
    531 	/* Here we are settimg the modification and access time of the file */
    532 	/* Windows code stes mod/access/creation time of the file */
    533 	struct utimbuf utb;
    534 
    535 	utb.actime = utb.modtime = rtcp->rcft.rcfu.mTime;
    536 	if(utime(rtcp->rcft.rcfu.fName, &utb) == -1) {
    537 		rfbLog("File [%s]: Method [%s]: Setting the modification/access"
    538 				" time for the file <%s> failed\n", __FILE__,
    539 				__FUNCTION__, rtcp->rcft.rcfu.fName);
    540 	}
    541 
    542 	if(rtcp->rcft.rcfu.uploadFD != -1) {
    543 		close(rtcp->rcft.rcfu.uploadFD);
    544 		rtcp->rcft.rcfu.uploadFD = -1;
    545 		rtcp->rcft.rcfu.uploadInProgress = FALSE;
    546 	}
    547 }
    548 
    549 
    550 FileTransferMsg
    551 CreateFileUploadErrMsg(char* reason, unsigned int reasonLen)
    552 {
    553 	FileTransferMsg fileUploadErrMsg;
    554 	int length = sz_rfbFileUploadCancelMsg + reasonLen;
    555 	rfbFileUploadCancelMsg *pFDF = NULL;
    556 	char *pFollow = NULL;
    557 
    558 	char *pData = (char*) calloc(length, sizeof(char));
    559 	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
    560 	if(pData == NULL) {
    561 		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
    562 				__FILE__, __FUNCTION__);
    563 		return fileUploadErrMsg;
    564 	}
    565 
    566 	pFDF = (rfbFileUploadCancelMsg *) pData;
    567 	pFollow = &pData[sz_rfbFileUploadCancelMsg];
    568 
    569 	pFDF->type = rfbFileUploadCancel;
    570 	pFDF->reasonLen = Swap16IfLE(reasonLen);
    571 	memcpy(pFollow, reason, reasonLen);
    572 
    573 	fileUploadErrMsg.data		= pData;
    574 	fileUploadErrMsg.length		= length;
    575 
    576 	return fileUploadErrMsg;
    577 }
    578 
    579 
    580 /******************************************************************************
    581  * Method to cancel File Transfer operation.
    582  ******************************************************************************/
    583 
    584 void
    585 CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr rtcp)
    586 {
    587 	/* TODO :: File Upload case is not handled currently */
    588 	/* TODO :: In case of concurrency we need to use Critical Section */
    589 
    590 	if(cl == NULL)
    591 		return;
    592 
    593 
    594 	if(rtcp->rcft.rcfu.uploadInProgress == TRUE) {
    595 		rtcp->rcft.rcfu.uploadInProgress = FALSE;
    596 
    597 		if(rtcp->rcft.rcfu.uploadFD != -1) {
    598 			close(rtcp->rcft.rcfu.uploadFD);
    599 			rtcp->rcft.rcfu.uploadFD = -1;
    600 		}
    601 
    602 		if(unlink(rtcp->rcft.rcfu.fName) == -1) {
    603 			rfbLog("File [%s]: Method [%s]: Delete operation on file <%s> failed\n",
    604 					__FILE__, __FUNCTION__, rtcp->rcft.rcfu.fName);
    605 		}
    606 
    607 		memset(rtcp->rcft.rcfu.fName, 0 , PATH_MAX);
    608 	}
    609 
    610 	if(rtcp->rcft.rcfd.downloadInProgress == TRUE) {
    611 		rtcp->rcft.rcfd.downloadInProgress = FALSE;
    612 
    613 		if(rtcp->rcft.rcfd.downloadFD != -1) {
    614 			close(rtcp->rcft.rcfd.downloadFD);
    615 			rtcp->rcft.rcfd.downloadFD = -1;
    616 		}
    617 		memset(rtcp->rcft.rcfd.fName, 0 , PATH_MAX);
    618 	}
    619 }
    620 
    621 
    622 /******************************************************************************
    623  * Method to handle create directory request.
    624  ******************************************************************************/
    625 
    626 void
    627 CreateDirectory(char* dirName)
    628 {
    629 	if(dirName == NULL) return;
    630 
    631 	if(mkdir(dirName, 0700) == -1) {
    632 		rfbLog("File [%s]: Method [%s]: Create operation for directory <%s> failed\n",
    633 				__FILE__, __FUNCTION__, dirName);
    634 	}
    635 }
    636 
    637