/*
 * 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

#ifdef WIN32
#include <io.h>
#include <direct.h>
#include <sys/utime.h>
#ifdef _MSC_VER
#define S_ISREG(m)	(((m) & _S_IFMT) == _S_IFREG)
#define S_ISDIR(m)	(((m) & S_IFDIR) == S_IFDIR)
#define S_IWUSR		S_IWRITE
#define S_IRUSR		S_IREAD
#define S_IWOTH		0x0000002
#define S_IROTH		0x0000004
#define S_IWGRP		0x0000010
#define S_IRGRP		0x0000020
#define mkdir(path, perms) _mkdir(path) /* Match POSIX signature */
/* Prevent POSIX deprecation warnings on MSVC */
#define creat _creat
#define open _open
#define read _read
#define write _write
#define close _close
#define unlink _unlink
#endif /* _MSC_VER */
#else
#include <dirent.h>
#include <utime.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <rfb/rfb.h>
#include "rfbtightproto.h"
#include "filelistinfo.h"
#include "filetransfermsg.h"
#include "handlefiletransferrequest.h"

#define SZ_RFBBLOCKSIZE 8192


void
FreeFileTransferMsg(FileTransferMsg ftm)
{

	if(ftm.data != NULL) {
		free(ftm.data);
		ftm.data = NULL;
	}

	ftm.length = 0;

}


/******************************************************************************
 * Methods to handle file list request.
 ******************************************************************************/

int CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag);
FileTransferMsg CreateFileListErrMsg(char flags);
FileTransferMsg CreateFileListMsg(FileListInfo fileListInfo, char flags);


/*
 * This is the method called by HandleFileListRequest to get the file list
 */

FileTransferMsg 
GetFileListResponseMsg(char* path, char flags)
{
	FileTransferMsg fileListMsg;
	FileListInfo fileListInfo;
	int status = -1;
	
	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
	memset(&fileListInfo, 0, sizeof(FileListInfo));

	
	 /* fileListInfo can have null data if the folder is Empty 
    	or if some error condition has occured.
    	The return value is 'failure' only if some error condition has occured.
	 */
	status = CreateFileListInfo(&fileListInfo, path, !(flags  & 0x10));

	if(status == FAILURE) {
		fileListMsg = CreateFileListErrMsg(flags);
	}
	else {
		/* DisplayFileList(fileListInfo); For Debugging  */
		
		fileListMsg = CreateFileListMsg(fileListInfo, flags);
		FreeFileListInfo(fileListInfo);
	}
	
	return fileListMsg;
}

#if !defined(__GNUC__) && !defined(_MSC_VER)
#define __FUNCTION__ "unknown"
#endif

#ifdef WIN32

/* Most of the Windows version here is based on https://github.com/danielgindi/FileDir */

#define FILETIME_TO_TIME_T(FILETIME) (((((__int64)FILETIME.dwLowDateTime) | (((__int64)FILETIME.dwHighDateTime) << 32)) - 116444736000000000L) / 10000000L)

#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
#define IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM))
#else
#define IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) 0
#endif

#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
#define IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA))
#else
#define IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) 0
#endif

#define IS_REGULAR_FILE(dwFileAttributes) \
	( \
	!!(dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || \
	( \
	!(dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && \
	!(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && \
	!(dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && \
	!IS_REGULAR_FILE_HAS_ATTRIBUTE_INTEGRITY_STREAM(dwFileAttributes) && \
	!IS_REGULAR_FILE_HAS_ATTRIBUTE_NO_SCRUB_DATA(dwFileAttributes) && \
	!(dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && \
	!(dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) \
	) \
	)

#define IS_FOLDER(dwFileAttributes) (!!(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))

int
CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag)
{
	int pathLen, basePathLength;
	char *basePath, *pChar;
	WIN32_FIND_DATAA winFindData;
	HANDLE findHandle;

	if(path == NULL) {
		return FAILURE;
	}

	if(strlen(path) == 0) {
		/* In this case we will send the list of entries in ftp root*/
		sprintf(path, "%s%s", GetFtpRoot(), "/");
	}

	/* Create a search string, like C:\folder\* */

	pathLen = strlen(path);
	basePath = malloc(pathLen + 3);
	memcpy(basePath, path, pathLen);
	basePathLength = pathLen;
	basePath[basePathLength] = '\\';
	basePath[basePathLength + 1] = '*';
	basePath[basePathLength + 2] = '\0';

	/* Start a search */
	memset(&winFindData, 0, sizeof(winFindData));
	findHandle = FindFirstFileA(path, &winFindData);

	basePath[basePathLength] = '\0'; /* Restore to a basePath + \ */
	/* Convert \ to / */
	for(pChar = basePath; *pChar; pChar++) {
		if (*pChar == '\\') {
			*pChar = '/';
		}
	}

	/* While we can find a next file do...
	   But ignore \. and '.. entries, which are current folder and parent folder respectively */
	while(findHandle != INVALID_HANDLE_VALUE && winFindData.cFileName[0] == '.' && 
		(winFindData.cFileName[1] == '\0' || 
		(winFindData.cFileName[1] == '.' && winFindData.cFileName[2] == '\0'))) {
		char fullpath[PATH_MAX];
		fullpath[0] = 0;

		strncpy_s(fullpath, PATH_MAX, basePath, basePathLength);
		strncpy_s(fullpath + basePathLength, PATH_MAX - basePathLength, winFindData.cFileName, (int)strlen(winFindData.cFileName));

		if(IS_FOLDER(winFindData.dwFileAttributes)) {
			if (AddFileListItemInfo(pFileListInfo, winFindData.cFileName, -1, 0) == 0) {
				rfbLog("File [%s]: Method [%s]: Add directory %s in the"
					" list failed\n", __FILE__, __FUNCTION__, fullpath);
				continue;
			}
		} 
		else if(IS_REGULAR_FILE(winFindData.dwFileAttributes)) {
			if(flag) {
				unsigned int fileSize = (winFindData.nFileSizeHigh * (MAXDWORD+1)) + winFindData.nFileSizeLow;
				if(AddFileListItemInfo(pFileListInfo, winFindData.cFileName, fileSize, FILETIME_TO_TIME_T(winFindData.ftLastWriteTime)) == 0) {
					rfbLog("File [%s]: Method [%s]: Add file %s in the "
						"list failed\n", __FILE__, __FUNCTION__, fullpath);
					continue;
				}			
			}
		}

		if(FindNextFileA(findHandle, &winFindData) == 0) {
			FindClose(findHandle);
			findHandle = INVALID_HANDLE_VALUE;
		}
	}

	if(findHandle != INVALID_HANDLE_VALUE) {
		FindClose(findHandle);
	}

	free(basePath);
	
	return SUCCESS;
}

#else /* WIN32 */

int
CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag)
{
	DIR* pDir = NULL;
	struct dirent* pDirent = NULL;

	if(path == NULL) {
		return FAILURE;
	}

	if(strlen(path) == 0) {
		/* In this case we will send the list of entries in ftp root*/
		sprintf(path, "%s%s", GetFtpRoot(), "/");
	}

	if((pDir = opendir(path)) == NULL) {
		rfbLog("File [%s]: Method [%s]: not able to open the dir\n",
				__FILE__, __FUNCTION__);
		return FAILURE; 		
	}

	while((pDirent = readdir(pDir))) {
		if(strcmp(pDirent->d_name, ".") && strcmp(pDirent->d_name, "..")) {
			struct stat stat_buf;
			/*
			int fpLen = sizeof(char)*(strlen(pDirent->d_name)+strlen(path)+2);
			*/
			char fullpath[PATH_MAX];

			memset(fullpath, 0, PATH_MAX);

			strcpy(fullpath, path);
			if(path[strlen(path)-1] != '/')
				strcat(fullpath, "/");
			strcat(fullpath, pDirent->d_name);

			if(stat(fullpath, &stat_buf) < 0) {
				rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n", 
						__FILE__, __FUNCTION__, fullpath);
				continue;
			}

			if(S_ISDIR(stat_buf.st_mode)) {
				if(AddFileListItemInfo(pFileListInfo, pDirent->d_name, -1, 0) == 0) {
					rfbLog("File [%s]: Method [%s]: Add directory %s in the"
							" list failed\n", __FILE__, __FUNCTION__, fullpath);
					continue;
				}
			}
			else {
				if(flag) {
					if(AddFileListItemInfo(pFileListInfo, pDirent->d_name, 
												stat_buf.st_size, 
												stat_buf.st_mtime) == 0) {
						rfbLog("File [%s]: Method [%s]: Add file %s in the "
								"list failed\n", __FILE__, __FUNCTION__, fullpath);
						continue;
					}			
				}
			}
		}
	}
	if(closedir(pDir) < 0) {
	    rfbLog("File [%s]: Method [%s]: ERROR Couldn't close dir\n",
	    	__FILE__, __FUNCTION__);
	}
	
	return SUCCESS;
}

#endif


FileTransferMsg
CreateFileListErrMsg(char flags)
{
	FileTransferMsg fileListMsg;
	rfbFileListDataMsg* pFLD = NULL;
	char* data = NULL;
	unsigned int length = 0;

	memset(&fileListMsg, 0, sizeof(FileTransferMsg));

	data = (char*) calloc(sizeof(rfbFileListDataMsg), sizeof(char));
	if(data == NULL) {
		return fileListMsg;
	}
	length = sizeof(rfbFileListDataMsg) * sizeof(char);
	pFLD = (rfbFileListDataMsg*) data;
	
	pFLD->type = rfbFileListData;
	pFLD->numFiles = Swap16IfLE(0);
	pFLD->dataSize = Swap16IfLE(0);
	pFLD->compressedSize = Swap16IfLE(0);
	pFLD->flags = flags | 0x80;

	fileListMsg.data = data;
	fileListMsg.length = length;

	return fileListMsg;
}


FileTransferMsg
CreateFileListMsg(FileListInfo fileListInfo, char flags)
{
	FileTransferMsg fileListMsg;
	rfbFileListDataMsg* pFLD = NULL;
	char *data = NULL, *pFileNames = NULL;
	unsigned int length = 0, dsSize = 0, i = 0;
	FileListItemSizePtr pFileListItemSize = NULL;

	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
	dsSize = fileListInfo.numEntries * 8;
	length = sz_rfbFileListDataMsg + dsSize + 
			GetSumOfFileNamesLength(fileListInfo) + 
			fileListInfo.numEntries;

	data = (char*) calloc(length, sizeof(char));
	if(data == NULL) {
		return fileListMsg;
	}
	pFLD = (rfbFileListDataMsg*) data;
	pFileListItemSize = (FileListItemSizePtr) &data[sz_rfbFileListDataMsg];
	pFileNames = &data[sz_rfbFileListDataMsg + dsSize];

	pFLD->type            = rfbFileListData;
    pFLD->flags 		  = flags & 0xF0;
    pFLD->numFiles 		  = Swap16IfLE(fileListInfo.numEntries);
    pFLD->dataSize 		  = Swap16IfLE(GetSumOfFileNamesLength(fileListInfo) + 
    									fileListInfo.numEntries);
    pFLD->compressedSize  = pFLD->dataSize;

	for(i =0; i <fileListInfo.numEntries; i++) {
		pFileListItemSize[i].size = Swap32IfLE(GetFileSizeAt(fileListInfo, i));
		pFileListItemSize[i].data = Swap32IfLE(GetFileDataAt(fileListInfo, i));
		strcpy(pFileNames, GetFileNameAt(fileListInfo, i));
		
		if(i+1 < fileListInfo.numEntries)
			pFileNames += strlen(pFileNames) + 1;
	}

	fileListMsg.data 	= data;
	fileListMsg.length 	= length;

	return fileListMsg;
}


/******************************************************************************
 * Methods to handle File Download Request.
 ******************************************************************************/

FileTransferMsg CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen);
FileTransferMsg CreateFileDownloadZeroSizeDataMsg(unsigned long mTime);
FileTransferMsg CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile);

FileTransferMsg 
GetFileDownLoadErrMsg()
{
	FileTransferMsg fileDownloadErrMsg;

	char reason[] = "An internal error on the server caused download failure";
	int reasonLen = strlen(reason);

	memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
	
	fileDownloadErrMsg = CreateFileDownloadErrMsg(reason, reasonLen);

	return fileDownloadErrMsg;
}


FileTransferMsg
GetFileDownloadReadDataErrMsg()
{
	char reason[] = "Cannot open file, perhaps it is absent or is a directory";
	int reasonLen = strlen(reason);

	return CreateFileDownloadErrMsg(reason, reasonLen);

}


FileTransferMsg
GetFileDownloadLengthErrResponseMsg()
{
	char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
	int reasonLen = strlen(reason);

	return CreateFileDownloadErrMsg(reason, reasonLen);
}


FileTransferMsg
GetFileDownloadResponseMsgInBlocks(rfbClientPtr cl, rfbTightClientPtr rtcp)
{
	/* const unsigned int sz_rfbBlockSize = SZ_RFBBLOCKSIZE; */
    int numOfBytesRead = 0;
	char pBuf[SZ_RFBBLOCKSIZE];
	char* path = rtcp->rcft.rcfd.fName;

	memset(pBuf, 0, SZ_RFBBLOCKSIZE);

	if((rtcp->rcft.rcfd.downloadInProgress == FALSE) && (rtcp->rcft.rcfd.downloadFD == -1)) {
		if((rtcp->rcft.rcfd.downloadFD = open(path, O_RDONLY)) == -1) {
			rfbLog("File [%s]: Method [%s]: Error: Couldn't open file\n", 
					__FILE__, __FUNCTION__);
			return GetFileDownloadReadDataErrMsg();
		}
		rtcp->rcft.rcfd.downloadInProgress = TRUE;
	}
	if((rtcp->rcft.rcfd.downloadInProgress == TRUE) && (rtcp->rcft.rcfd.downloadFD != -1)) {
		if( (numOfBytesRead = read(rtcp->rcft.rcfd.downloadFD, pBuf, SZ_RFBBLOCKSIZE)) <= 0) {
			close(rtcp->rcft.rcfd.downloadFD);
			rtcp->rcft.rcfd.downloadFD = -1;
			rtcp->rcft.rcfd.downloadInProgress = FALSE;
			if(numOfBytesRead == 0) {
				return CreateFileDownloadZeroSizeDataMsg(rtcp->rcft.rcfd.mTime);
			}			
			return GetFileDownloadReadDataErrMsg();
		}
	return CreateFileDownloadBlockSizeDataMsg(numOfBytesRead, pBuf);
	}
	return GetFileDownLoadErrMsg();
}


FileTransferMsg
ChkFileDownloadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
{
    FileTransferMsg fileDownloadMsg;
	struct stat stat_buf;
	int sz_rfbFileSize = 0;
	char* path = rtcp->rcft.rcfd.fName;

	memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));

	if( (path == NULL) || (strlen(path) == 0) ||
		(stat(path, &stat_buf) < 0) || (!(S_ISREG(stat_buf.st_mode))) ) {

			char reason[] = "Cannot open file, perhaps it is absent or is not a regular file";
			int reasonLen = strlen(reason);

			rfbLog("File [%s]: Method [%s]: Reading stat for path %s failed\n", 
					__FILE__, __FUNCTION__, path);	
			
			fileDownloadMsg = CreateFileDownloadErrMsg(reason, reasonLen);
	}
	else {
		rtcp->rcft.rcfd.mTime = stat_buf.st_mtime;
		sz_rfbFileSize = stat_buf.st_size;
		if(sz_rfbFileSize <= 0) {
			fileDownloadMsg = CreateFileDownloadZeroSizeDataMsg(stat_buf.st_mtime);
		}

	}
	return fileDownloadMsg;
}


FileTransferMsg
CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen)
{
	FileTransferMsg fileDownloadErrMsg;
	int length = sz_rfbFileDownloadFailedMsg + reasonLen + 1;
	rfbFileDownloadFailedMsg *pFDF = NULL;
	char *pFollow = NULL;
	
	char *pData = (char*) calloc(length, sizeof(char));
	memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
	if(pData == NULL) {
		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
				__FILE__, __FUNCTION__);	
		return fileDownloadErrMsg;
	}

	pFDF = (rfbFileDownloadFailedMsg *) pData;
	pFollow = &pData[sz_rfbFileDownloadFailedMsg];
	
	pFDF->type = rfbFileDownloadFailed;
	pFDF->reasonLen = Swap16IfLE(reasonLen);
	memcpy(pFollow, reason, reasonLen);

	fileDownloadErrMsg.data	= pData;
	fileDownloadErrMsg.length	= length;

	return fileDownloadErrMsg;
}


FileTransferMsg
CreateFileDownloadZeroSizeDataMsg(unsigned long mTime)
{
	FileTransferMsg fileDownloadZeroSizeDataMsg;
	int length = sz_rfbFileDownloadDataMsg + sizeof(unsigned long);
	rfbFileDownloadDataMsg *pFDD = NULL;
	char *pFollow = NULL;
	
	char *pData = (char*) calloc(length, sizeof(char));
	memset(&fileDownloadZeroSizeDataMsg, 0, sizeof(FileTransferMsg));
	if(pData == NULL) {
		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
				__FILE__, __FUNCTION__);	
		return fileDownloadZeroSizeDataMsg;
	}

	pFDD = (rfbFileDownloadDataMsg *) pData;
	pFollow = &pData[sz_rfbFileDownloadDataMsg];
	
	pFDD->type = rfbFileDownloadData;
	pFDD->compressLevel = 0;
	pFDD->compressedSize = Swap16IfLE(0);
	pFDD->realSize = Swap16IfLE(0);
	
	memcpy(pFollow, &mTime, sizeof(unsigned long));

	fileDownloadZeroSizeDataMsg.data	= pData;
	fileDownloadZeroSizeDataMsg.length	= length;

	return fileDownloadZeroSizeDataMsg;

}


FileTransferMsg
CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile)
{
	FileTransferMsg fileDownloadBlockSizeDataMsg;
	int length = sz_rfbFileDownloadDataMsg + sizeFile;
	rfbFileDownloadDataMsg *pFDD = NULL;
	char *pFollow = NULL;
	
	char *pData = (char*) calloc(length, sizeof(char));
	memset(&fileDownloadBlockSizeDataMsg, 0, sizeof(FileTransferMsg));
	if(NULL == pData) {
		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
				__FILE__, __FUNCTION__);	
		return fileDownloadBlockSizeDataMsg;
	}

	pFDD = (rfbFileDownloadDataMsg *) pData;
	pFollow = &pData[sz_rfbFileDownloadDataMsg];
	
	pFDD->type = rfbFileDownloadData;
	pFDD->compressLevel = 0;
	pFDD->compressedSize = Swap16IfLE(sizeFile);
	pFDD->realSize = Swap16IfLE(sizeFile);
	
	memcpy(pFollow, pFile, sizeFile);

	fileDownloadBlockSizeDataMsg.data	= pData;
	fileDownloadBlockSizeDataMsg.length	= length;

	return fileDownloadBlockSizeDataMsg;

}


/******************************************************************************
 * Methods to handle file upload request
 ******************************************************************************/

FileTransferMsg CreateFileUploadErrMsg(char* reason, unsigned int reasonLen);

FileTransferMsg 
GetFileUploadLengthErrResponseMsg()
{
	char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
	int reasonLen = strlen(reason);

	return CreateFileUploadErrMsg(reason, reasonLen);
}


FileTransferMsg
ChkFileUploadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
{
    FileTransferMsg fileUploadErrMsg;

	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
	if( (rtcp->rcft.rcfu.fName == NULL) ||
		(strlen(rtcp->rcft.rcfu.fName) == 0) ||
		((rtcp->rcft.rcfu.uploadFD = creat(rtcp->rcft.rcfu.fName, 
		S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1)) {

			char reason[] = "Could not create file";
			int reasonLen = strlen(reason);
			fileUploadErrMsg = CreateFileUploadErrMsg(reason, reasonLen);
	}
	else
		rtcp->rcft.rcfu.uploadInProgress = TRUE;
	
	return fileUploadErrMsg;
}


FileTransferMsg
GetFileUploadCompressedLevelErrMsg()
{
	char reason[] = "Server does not support data compression on upload";
	int reasonLen = strlen(reason);

	return CreateFileUploadErrMsg(reason, reasonLen);
}


FileTransferMsg
ChkFileUploadWriteErr(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf)
{
	FileTransferMsg ftm;
	unsigned long numOfBytesWritten = 0;

	memset(&ftm, 0, sizeof(FileTransferMsg));

	numOfBytesWritten = write(rtcp->rcft.rcfu.uploadFD, pBuf, rtcp->rcft.rcfu.fSize);

	if(numOfBytesWritten != rtcp->rcft.rcfu.fSize) {		
		char reason[] = "Error writing file data";
		int reasonLen = strlen(reason);
		ftm = CreateFileUploadErrMsg(reason, reasonLen);
		CloseUndoneFileTransfer(cl, rtcp);
	}		
	return ftm;
}


void
FileUpdateComplete(rfbClientPtr cl, rfbTightClientPtr rtcp)
{
	/* Here we are settimg the modification and access time of the file */
	/* Windows code stes mod/access/creation time of the file */
	struct utimbuf utb;

	utb.actime = utb.modtime = rtcp->rcft.rcfu.mTime;
	if(utime(rtcp->rcft.rcfu.fName, &utb) == -1) {
		rfbLog("File [%s]: Method [%s]: Setting the modification/access"
				" time for the file <%s> failed\n", __FILE__, 
				__FUNCTION__, rtcp->rcft.rcfu.fName);
	}

	if(rtcp->rcft.rcfu.uploadFD != -1) {
		close(rtcp->rcft.rcfu.uploadFD);
		rtcp->rcft.rcfu.uploadFD = -1;
		rtcp->rcft.rcfu.uploadInProgress = FALSE;
	}
}


FileTransferMsg
CreateFileUploadErrMsg(char* reason, unsigned int reasonLen)
{
	FileTransferMsg fileUploadErrMsg;
	int length = sz_rfbFileUploadCancelMsg + reasonLen;
	rfbFileUploadCancelMsg *pFDF = NULL;
	char *pFollow = NULL;
	
	char *pData = (char*) calloc(length, sizeof(char));
	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
	if(pData == NULL) {
		rfbLog("File [%s]: Method [%s]: pData is NULL\n",
				__FILE__, __FUNCTION__);	
		return fileUploadErrMsg;
	}

	pFDF = (rfbFileUploadCancelMsg *) pData;
	pFollow = &pData[sz_rfbFileUploadCancelMsg];
	
	pFDF->type = rfbFileUploadCancel;
	pFDF->reasonLen = Swap16IfLE(reasonLen);
	memcpy(pFollow, reason, reasonLen);

	fileUploadErrMsg.data		= pData;
	fileUploadErrMsg.length		= length;

	return fileUploadErrMsg;
}


/******************************************************************************
 * Method to cancel File Transfer operation.
 ******************************************************************************/

void
CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr rtcp)
{
	/* TODO :: File Upload case is not handled currently */
	/* TODO :: In case of concurrency we need to use Critical Section */

	if(cl == NULL)
		return;

	
	if(rtcp->rcft.rcfu.uploadInProgress == TRUE) {
		rtcp->rcft.rcfu.uploadInProgress = FALSE;

		if(rtcp->rcft.rcfu.uploadFD != -1) {
			close(rtcp->rcft.rcfu.uploadFD);
			rtcp->rcft.rcfu.uploadFD = -1;
		}

		if(unlink(rtcp->rcft.rcfu.fName) == -1) {
			rfbLog("File [%s]: Method [%s]: Delete operation on file <%s> failed\n", 
					__FILE__, __FUNCTION__, rtcp->rcft.rcfu.fName);
		}

		memset(rtcp->rcft.rcfu.fName, 0 , PATH_MAX);
	}
	
	if(rtcp->rcft.rcfd.downloadInProgress == TRUE) {
		rtcp->rcft.rcfd.downloadInProgress = FALSE;

		if(rtcp->rcft.rcfd.downloadFD != -1) {			
			close(rtcp->rcft.rcfd.downloadFD);
			rtcp->rcft.rcfd.downloadFD = -1;
		}
		memset(rtcp->rcft.rcfd.fName, 0 , PATH_MAX);
	}
}


/******************************************************************************
 * Method to handle create directory request.
 ******************************************************************************/

#ifdef _MSC_VER
#undef CreateDirectory /* Prevent macro clashes under Windows */
#endif /* _MSC_VER */

void
CreateDirectory(char* dirName)
{
	if(dirName == NULL) return;

	if(mkdir(dirName, 0700) == -1) {
		rfbLog("File [%s]: Method [%s]: Create operation for directory <%s> failed\n", 
				__FILE__, __FUNCTION__, dirName);
	}
}
