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 #include <pwd.h>
     26 #include <stdio.h>
     27 #include <stdlib.h>
     28 #include <string.h>
     29 #include <unistd.h>
     30 #include <dirent.h>
     31 #include <pthread.h>
     32 #include <sys/stat.h>
     33 #include <sys/types.h>
     34 #include <limits.h>
     35 
     36 #include <rfb/rfb.h>
     37 #include "rfbtightproto.h"
     38 #include "filetransfermsg.h"
     39 #include "handlefiletransferrequest.h"
     40 
     41 
     42 pthread_mutex_t fileDownloadMutex = PTHREAD_MUTEX_INITIALIZER;
     43 
     44 rfbBool fileTransferEnabled = TRUE;
     45 rfbBool fileTransferInitted = FALSE;
     46 char ftproot[PATH_MAX];
     47 
     48 
     49 /******************************************************************************
     50  * File Transfer Init methods. These methods are called for initializating
     51  * File Transfer and setting ftproot.
     52  ******************************************************************************/
     53 
     54 void InitFileTransfer();
     55 int SetFtpRoot(char* path);
     56 char* GetHomeDir(uid_t uid);
     57 void FreeHomeDir(char *homedir);
     58 
     59 /*
     60  * InitFileTransfer method is called before parsing the command-line options
     61  * for Xvnc. This sets the ftproot to the Home dir of the user running the Xvnc
     62  * server. In case of error ftproot is set to '\0' char.
     63  */
     64 
     65 void
     66 InitFileTransfer()
     67 {
     68 	char* userHome = NULL;
     69 	uid_t uid = geteuid();
     70 
     71 	if(fileTransferInitted)
     72 		return;
     73 
     74 	rfbLog("tightvnc-filetransfer/InitFileTransfer\n");
     75 
     76 	memset(ftproot, 0, sizeof(ftproot));
     77 
     78 	userHome = GetHomeDir(uid);
     79 
     80 	if((userHome != NULL) && (strlen(userHome) != 0)) {
     81 		SetFtpRoot(userHome);
     82 		FreeHomeDir(userHome);
     83 	}
     84 
     85 	fileTransferEnabled = TRUE;
     86 	fileTransferInitted = TRUE;
     87 }
     88 
     89 #ifndef __GNUC__
     90 #define __FUNCTION__ "unknown"
     91 #endif
     92 
     93 /*
     94  *  This method is called from InitFileTransfer method and
     95  *  if the command line option for ftproot is provided.
     96  */
     97 int
     98 SetFtpRoot(char* path)
     99 {
    100 	struct stat stat_buf;
    101 	DIR* dir = NULL;
    102 
    103 	rfbLog("tightvnc-filetransfer/SetFtpRoot\n");
    104 
    105 	if((path == NULL) || (strlen(path) == 0) || (strlen(path) > (PATH_MAX - 1))) {
    106 		rfbLog("File [%s]: Method [%s]: parameter passed is improper, ftproot"
    107 				" not changed\n", __FILE__, __FUNCTION__);
    108 		return FALSE;
    109 	}
    110 
    111 	if(stat(path, &stat_buf) < 0) {
    112 		rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n",
    113 				__FILE__, __FUNCTION__, path);
    114 		return FALSE;
    115 	}
    116 
    117 	if(S_ISDIR(stat_buf.st_mode) == 0) {
    118 		rfbLog("File [%s]: Method [%s]: path specified is not a directory\n",
    119 				__FILE__, __FUNCTION__);
    120 		return FALSE;
    121 	}
    122 
    123 	if((dir = opendir(path)) == NULL) {
    124 		rfbLog("File [%s]: Method [%s]: Not able to open the directory\n",
    125 				__FILE__, __FUNCTION__);
    126 		return FALSE;
    127 	}
    128 	else {
    129 		closedir(dir);
    130 		dir = NULL;
    131 	}
    132 
    133 
    134 	memset(ftproot, 0, PATH_MAX);
    135 	if(path[strlen(path)-1] == '/') {
    136 		memcpy(ftproot, path, strlen(path)-1);
    137 	}
    138 	else
    139 		memcpy(ftproot, path, strlen(path));
    140 
    141 
    142 	return TRUE;
    143 }
    144 
    145 
    146 /*
    147  * Get the home directory for the user name
    148  * param: username - name of the user for whom the home directory is required.
    149  * returns: returns the home directory for the user, or null in case the entry
    150  * is not found or any error. The returned string must be freed by calling the
    151  * freehomedir function.
    152 */
    153 char*
    154 GetHomeDir(uid_t uid)
    155 {
    156 	struct passwd *pwEnt = NULL;
    157 	char *homedir = NULL;
    158 
    159 	pwEnt = getpwuid (uid);
    160 	if (pwEnt == NULL)
    161 		return NULL;
    162 
    163 	if(pwEnt->pw_dir != NULL) {
    164 		homedir = strdup (pwEnt->pw_dir);
    165 	}
    166 
    167 	return homedir;
    168 }
    169 
    170 
    171 /*
    172  * Free the home directory allocated by a previous call to retrieve the home
    173  * directory. param: homedir - the string returned by a previous call to
    174  * retrieve home directory for a user.
    175  */
    176 void
    177 FreeHomeDir(char *homedir)
    178 {
    179     free (homedir);
    180 }
    181 
    182 
    183 /******************************************************************************
    184  * General methods.
    185  ******************************************************************************/
    186 
    187 /*
    188  * When the console sends the File Transfer Request, it sends the file path with
    189  * ftproot as "/". So on Agent, to get the absolute file path we need to prepend
    190  * the ftproot to it.
    191  */
    192 char*
    193 ConvertPath(char* path)
    194 {
    195 	char p[PATH_MAX];
    196 	memset(p, 0, PATH_MAX);
    197 
    198 	if( (path == NULL) ||
    199 		(strlen(path) == 0) ||
    200 		(strlen(path)+strlen(ftproot) > PATH_MAX - 1) ) {
    201 
    202 		rfbLog("File [%s]: Method [%s]: cannot create path for file transfer\n",
    203 				__FILE__, __FUNCTION__);
    204 		return NULL;
    205 	}
    206 
    207 	memcpy(p, path, strlen(path));
    208 	memset(path, 0, PATH_MAX);
    209 	sprintf(path, "%s%s", ftproot, p);
    210 
    211 	return path;
    212 }
    213 
    214 
    215 void
    216 EnableFileTransfer(rfbBool enable)
    217 {
    218 	fileTransferEnabled = enable;
    219 }
    220 
    221 
    222 rfbBool
    223 IsFileTransferEnabled()
    224 {
    225 	return fileTransferEnabled;
    226 }
    227 
    228 
    229 char*
    230 GetFtpRoot()
    231 {
    232 	return ftproot;
    233 }
    234 
    235 
    236 /******************************************************************************
    237  * Methods to Handle File List Request.
    238  ******************************************************************************/
    239 
    240 /*
    241  *  HandleFileListRequest method is called when the server receives
    242  *  FileListRequest. In case of success a file list is sent to the client.
    243  *  For File List Request there is no failure reason sent.So here in case of any
    244  *  "unexpected" error no information will be sent. As these conditions should
    245  *  never come. Lets hope it never arrives :)
    246  *  In case of dir open failure an empty list will be sent, just the header of
    247  *  the message filled up. So on console you will get an Empty listing.
    248  */
    249 void
    250 HandleFileListRequest(rfbClientPtr cl, rfbTightClientRec* data)
    251 {
    252 	rfbClientToServerTightMsg msg;
    253 	int n = 0;
    254 	char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
    255 	FileTransferMsg fileListMsg;
    256 
    257 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    258 	memset(path, 0, PATH_MAX);
    259 	memset(&fileListMsg, 0, sizeof(FileTransferMsg));
    260 
    261 	if(cl == NULL) {
    262 		rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
    263 				__FILE__, __FUNCTION__);
    264 		return;
    265 	}
    266 
    267 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileListRequestMsg-1)) <= 0) {
    268 
    269 		if (n < 0)
    270 			rfbLog("File [%s]: Method [%s]: Socket error while reading dir name"
    271 					" length\n", __FILE__, __FUNCTION__);
    272 
    273 	    rfbCloseClient(cl);
    274 	    return;
    275 	}
    276 
    277 	msg.flr.dirNameSize = Swap16IfLE(msg.flr.dirNameSize);
    278 	if ((msg.flr.dirNameSize == 0) ||
    279 		(msg.flr.dirNameSize > (PATH_MAX - 1))) {
    280 
    281 		rfbLog("File [%s]: Method [%s]: Unexpected error:: path length is "
    282 				"greater that PATH_MAX\n", __FILE__, __FUNCTION__);
    283 
    284 		return;
    285 	}
    286 
    287 	if((n = rfbReadExact(cl, path, msg.flr.dirNameSize)) <= 0) {
    288 
    289 		if (n < 0)
    290 			rfbLog("File [%s]: Method [%s]: Socket error while reading dir name\n",
    291 							__FILE__, __FUNCTION__);
    292 
    293 	    rfbCloseClient(cl);
    294 	    return;
    295 	}
    296 
    297 	if(ConvertPath(path) == NULL) {
    298 
    299 		/* The execution should never reach here */
    300     	rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL",
    301     			__FILE__, __FUNCTION__);
    302     	return;
    303 	}
    304 
    305     fileListMsg = GetFileListResponseMsg(path, (char) (msg.flr.flags));
    306 
    307     if((fileListMsg.data == NULL) || (fileListMsg.length == 0)) {
    308 
    309     	rfbLog("File [%s]: Method [%s]: Unexpected error:: Data to be sent is "
    310     		"of Zero length\n",	__FILE__, __FUNCTION__);
    311     	return;
    312 	}
    313 
    314     rfbWriteExact(cl, fileListMsg.data, fileListMsg.length);
    315 
    316     FreeFileTransferMsg(fileListMsg);
    317 }
    318 
    319 
    320 /******************************************************************************
    321  * Methods to Handle File Download Request.
    322  ******************************************************************************/
    323 
    324 void HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize);
    325 void SendFileDownloadLengthErrMsg(rfbClientPtr cl);
    326 void HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr data);
    327 #ifdef TODO
    328 void HandleFileDownloadRequest(rfbClientPtr cl);
    329 void SendFileDownloadErrMsg(rfbClientPtr cl);
    330 void* RunFileDownloadThread(void* client);
    331 #endif
    332 
    333 /*
    334  * HandleFileDownloadRequest method is called when the server receives
    335  * rfbFileDownload request message.
    336  */
    337 void
    338 HandleFileDownloadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    339 {
    340 	int n = 0;
    341 	char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
    342 	rfbClientToServerTightMsg msg;
    343 
    344  	memset(path, 0, sizeof(path));
    345 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    346 
    347 	if(cl == NULL) {
    348 
    349 		rfbLog("File [%s]: Method [%s]: Unexpected error:: rfbClientPtr is null\n",
    350 				__FILE__, __FUNCTION__);
    351 		return;
    352 	}
    353 
    354 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadRequestMsg-1)) <= 0) {
    355 
    356 		if (n < 0)
    357 			rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n",
    358 					__FILE__, __FUNCTION__);
    359 
    360 	    rfbCloseClient(cl);
    361 	    return;
    362 	}
    363 
    364 	msg.fdr.fNameSize = Swap16IfLE(msg.fdr.fNameSize);
    365 	msg.fdr.position = Swap16IfLE(msg.fdr.position);
    366 
    367 	if ((msg.fdr.fNameSize == 0) ||
    368 		(msg.fdr.fNameSize > (PATH_MAX - 1))) {
    369 
    370 		rfbLog("File [%s]: Method [%s]: Error: path length is greater than"
    371 				" PATH_MAX\n", __FILE__, __FUNCTION__);
    372 
    373 		HandleFileDownloadLengthError(cl, msg.fdr.fNameSize);
    374 		return;
    375 	}
    376 
    377 	if((n = rfbReadExact(cl, rtcp->rcft.rcfd.fName, msg.fdr.fNameSize)) <= 0) {
    378 
    379 		if (n < 0)
    380 			rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n",
    381 							__FILE__, __FUNCTION__);
    382 
    383 	    rfbCloseClient(cl);
    384 	    return;
    385 	}
    386 	rtcp->rcft.rcfd.fName[msg.fdr.fNameSize] = '\0';
    387 
    388 	if(ConvertPath(rtcp->rcft.rcfd.fName) == NULL) {
    389 
    390     	rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL",
    391     			__FILE__, __FUNCTION__);
    392 
    393 
    394 		 /* This condition can come only if the file path is greater than
    395 		    PATH_MAX. So sending file path length error msg back to client.
    396 		 */
    397 
    398     	SendFileDownloadLengthErrMsg(cl);
    399 	return;
    400 	}
    401 
    402 	HandleFileDownload(cl, rtcp);
    403 
    404 }
    405 
    406 
    407 void
    408 HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize)
    409 {
    410 	char *path = NULL;
    411 	int n = 0;
    412 
    413 	if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) {
    414 		rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n",
    415 				__FILE__, __FUNCTION__);
    416 		return;
    417 	}
    418 	if((n = rfbReadExact(cl, path, fNameSize)) <= 0) {
    419 
    420 		if (n < 0)
    421 			rfbLog("File [%s]: Method [%s]: Error while reading dir name\n",
    422 							__FILE__, __FUNCTION__);
    423 
    424 	    rfbCloseClient(cl);
    425 
    426 	    if(path != NULL) {
    427 			free(path);
    428 			path = NULL;
    429 		}
    430 
    431 	    return;
    432 	}
    433 
    434     if(path != NULL) {
    435 		free(path);
    436 		path = NULL;
    437 	}
    438 
    439 	SendFileDownloadLengthErrMsg(cl);
    440 }
    441 
    442 
    443 void
    444 SendFileDownloadLengthErrMsg(rfbClientPtr cl)
    445 {
    446 	FileTransferMsg fileDownloadErrMsg;
    447 
    448 	memset(&fileDownloadErrMsg, 0 , sizeof(FileTransferMsg));
    449 
    450 	fileDownloadErrMsg = GetFileDownloadLengthErrResponseMsg();
    451 
    452 	if((fileDownloadErrMsg.data == NULL) || (fileDownloadErrMsg.length == 0)) {
    453 		rfbLog("File [%s]: Method [%s]: Unexpected error: fileDownloadErrMsg "
    454 				"is null\n", __FILE__, __FUNCTION__);
    455 		return;
    456 	}
    457 
    458 	rfbWriteExact(cl, fileDownloadErrMsg.data, fileDownloadErrMsg.length);
    459 
    460 	FreeFileTransferMsg(fileDownloadErrMsg);
    461 }
    462 
    463 extern rfbTightClientPtr rfbGetTightClientData(rfbClientPtr cl);
    464 
    465 void*
    466 RunFileDownloadThread(void* client)
    467 {
    468 	rfbClientPtr cl = (rfbClientPtr) client;
    469 	rfbTightClientPtr rtcp = rfbGetTightClientData(cl);
    470 	FileTransferMsg fileDownloadMsg;
    471 
    472 	if(rtcp == NULL)
    473 		return NULL;
    474 
    475 	memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
    476 	do {
    477 		pthread_mutex_lock(&fileDownloadMutex);
    478 		fileDownloadMsg = GetFileDownloadResponseMsgInBlocks(cl, rtcp);
    479 		pthread_mutex_unlock(&fileDownloadMutex);
    480 
    481 		if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) {
    482 			if(rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length) < 0)  {
    483 				rfbLog("File [%s]: Method [%s]: Error while writing to socket \n"
    484 						, __FILE__, __FUNCTION__);
    485 
    486 				if(cl != NULL) {
    487 			    	rfbCloseClient(cl);
    488 				CloseUndoneFileTransfer(cl, rtcp);
    489 				}
    490 
    491 				FreeFileTransferMsg(fileDownloadMsg);
    492 				return NULL;
    493 			}
    494 			FreeFileTransferMsg(fileDownloadMsg);
    495 		}
    496 	} while(rtcp->rcft.rcfd.downloadInProgress == TRUE);
    497 	return NULL;
    498 }
    499 
    500 
    501 void
    502 HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr rtcp)
    503 {
    504 	pthread_t fileDownloadThread;
    505 	FileTransferMsg fileDownloadMsg;
    506 
    507 	memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
    508 	fileDownloadMsg = ChkFileDownloadErr(cl, rtcp);
    509 	if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) {
    510 		rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length);
    511 		FreeFileTransferMsg(fileDownloadMsg);
    512 		return;
    513 	}
    514 	rtcp->rcft.rcfd.downloadInProgress = FALSE;
    515 	rtcp->rcft.rcfd.downloadFD = -1;
    516 
    517 	if(pthread_create(&fileDownloadThread, NULL, RunFileDownloadThread, (void*)
    518 	cl) != 0) {
    519 		FileTransferMsg ftm = GetFileDownLoadErrMsg();
    520 
    521 		rfbLog("File [%s]: Method [%s]: Download thread creation failed\n",
    522 				__FILE__, __FUNCTION__);
    523 
    524 		if((ftm.data != NULL) && (ftm.length != 0)) {
    525 			rfbWriteExact(cl, ftm.data, ftm.length);
    526 			FreeFileTransferMsg(ftm);
    527 			return;
    528 		}
    529 
    530 	}
    531 
    532 }
    533 
    534 
    535 /******************************************************************************
    536  * Methods to Handle File Download Cancel Request.
    537  ******************************************************************************/
    538 
    539 
    540 void
    541 HandleFileDownloadCancelRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    542 {
    543 	int n = 0;
    544 	char *reason = NULL;
    545 	rfbClientToServerTightMsg msg;
    546 
    547 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    548 
    549 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadCancelMsg-1)) <= 0) {
    550 
    551 		if (n < 0)
    552 			rfbLog("File [%s]: Method [%s]: Error while reading "
    553 					"FileDownloadCancelMsg\n", __FILE__, __FUNCTION__);
    554 
    555 	    rfbCloseClient(cl);
    556 	    return;
    557 	}
    558 
    559 	msg.fdc.reasonLen = Swap16IfLE(msg.fdc.reasonLen);
    560 
    561 	if(msg.fdc.reasonLen == 0) {
    562 		rfbLog("File [%s]: Method [%s]: reason length received is Zero\n",
    563 				__FILE__, __FUNCTION__);
    564 		return;
    565 	}
    566 
    567 	reason = (char*) calloc(msg.fdc.reasonLen + 1, sizeof(char));
    568 	if(reason == NULL) {
    569 		rfbLog("File [%s]: Method [%s]: Fatal Error: Memory alloc failed\n",
    570 				__FILE__, __FUNCTION__);
    571 		return;
    572 	}
    573 
    574 	if((n = rfbReadExact(cl, reason, msg.fdc.reasonLen)) <= 0) {
    575 
    576 		if (n < 0)
    577 			rfbLog("File [%s]: Method [%s]: Error while reading "
    578 					"FileDownloadCancelMsg\n", __FILE__, __FUNCTION__);
    579 
    580 	    rfbCloseClient(cl);
    581 	}
    582 
    583 	rfbLog("File [%s]: Method [%s]: File Download Cancel Request received:"
    584 					" reason <%s>\n", __FILE__, __FUNCTION__, reason);
    585 
    586 	pthread_mutex_lock(&fileDownloadMutex);
    587 	CloseUndoneFileTransfer(cl, rtcp);
    588 	pthread_mutex_unlock(&fileDownloadMutex);
    589 
    590 	if(reason != NULL) {
    591 		free(reason);
    592 		reason = NULL;
    593 	}
    594 
    595 }
    596 
    597 
    598 /******************************************************************************
    599  * Methods to Handle File upload request
    600  ******************************************************************************/
    601 
    602 #ifdef TODO
    603 void HandleFileUploadRequest(rfbClientPtr cl);
    604 #endif
    605 void HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr data);
    606 void HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize);
    607 void SendFileUploadLengthErrMsg(rfbClientPtr cl);
    608 
    609 
    610 void
    611 HandleFileUploadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    612 {
    613 	int n = 0;
    614 	char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
    615 	rfbClientToServerTightMsg msg;
    616 
    617 	memset(path, 0, PATH_MAX);
    618 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    619 
    620 	if(cl == NULL) {
    621 		rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
    622 				__FILE__, __FUNCTION__);
    623 		return;
    624 	}
    625 
    626 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadRequestMsg-1)) <= 0) {
    627 
    628 		if (n < 0)
    629 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
    630 					__FILE__, __FUNCTION__);
    631 
    632 	    rfbCloseClient(cl);
    633 	    return;
    634 	}
    635 
    636 	msg.fupr.fNameSize = Swap16IfLE(msg.fupr.fNameSize);
    637 	msg.fupr.position = Swap16IfLE(msg.fupr.position);
    638 
    639 	if ((msg.fupr.fNameSize == 0) ||
    640 		(msg.fupr.fNameSize > (PATH_MAX - 1))) {
    641 
    642 		rfbLog("File [%s]: Method [%s]: error: path length is greater than PATH_MAX\n",
    643 				__FILE__, __FUNCTION__);
    644 		HandleFileUploadLengthError(cl, msg.fupr.fNameSize);
    645 		return;
    646 	}
    647 
    648 	if((n = rfbReadExact(cl, rtcp->rcft.rcfu.fName, msg.fupr.fNameSize)) <= 0) {
    649 
    650 		if (n < 0)
    651 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n"
    652 					__FILE__, __FUNCTION__);
    653 
    654 	    rfbCloseClient(cl);
    655 	    return;
    656 	}
    657 	rtcp->rcft.rcfu.fName[msg.fupr.fNameSize] = '\0';
    658 
    659 	if(ConvertPath(rtcp->rcft.rcfu.fName) == NULL) {
    660     	rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n",
    661     			__FILE__, __FUNCTION__);
    662 
    663     	/* This may come if the path length exceeds PATH_MAX.
    664     	   So sending path length error to client
    665     	 */
    666     	 SendFileUploadLengthErrMsg(cl);
    667     	return;
    668 	}
    669 
    670 	HandleFileUpload(cl, rtcp);
    671 }
    672 
    673 
    674 void
    675 HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize)
    676 {
    677 	char *path = NULL;
    678 	int n = 0;
    679 
    680 	if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) {
    681 		rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n",
    682 				__FILE__, __FUNCTION__);
    683 		return;
    684 	}
    685 	if((n = rfbReadExact(cl, path, fNameSize)) <= 0) {
    686 
    687 		if (n < 0)
    688 			rfbLog("File [%s]: Method [%s]: Error while reading dir name\n",
    689 							__FILE__, __FUNCTION__);
    690 
    691 	    rfbCloseClient(cl);
    692 
    693 	    if(path != NULL) {
    694 			free(path);
    695 			path = NULL;
    696 		}
    697 
    698 	    return;
    699 	}
    700 
    701 	rfbLog("File [%s]: Method [%s]: File Upload Length Error occured"
    702 			"file path requested is <%s>\n", __FILE__, __FUNCTION__, path);
    703 
    704     if(path != NULL) {
    705 		free(path);
    706 		path = NULL;
    707 	}
    708 
    709     SendFileUploadLengthErrMsg(cl);
    710 }
    711 
    712 void
    713 SendFileUploadLengthErrMsg(rfbClientPtr cl)
    714 {
    715 
    716 	FileTransferMsg fileUploadErrMsg;
    717 
    718 	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
    719 	fileUploadErrMsg = GetFileUploadLengthErrResponseMsg();
    720 
    721 	if((fileUploadErrMsg.data == NULL) || (fileUploadErrMsg.length == 0)) {
    722 		rfbLog("File [%s]: Method [%s]: Unexpected error: fileUploadErrMsg is null\n",
    723 				__FILE__, __FUNCTION__);
    724 		return;
    725 	}
    726 
    727 	rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length);
    728 	FreeFileTransferMsg(fileUploadErrMsg);
    729 }
    730 
    731 void
    732 HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr rtcp)
    733 {
    734 	FileTransferMsg fileUploadErrMsg;
    735 
    736 	memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
    737 
    738 	rtcp->rcft.rcfu.uploadInProgress = FALSE;
    739 	rtcp->rcft.rcfu.uploadFD = -1;
    740 
    741 	fileUploadErrMsg = ChkFileUploadErr(cl, rtcp);
    742 	if((fileUploadErrMsg.data != NULL) && (fileUploadErrMsg.length != 0)) {
    743 		rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length);
    744 		FreeFileTransferMsg(fileUploadErrMsg);
    745 	}
    746 }
    747 
    748 
    749 /******************************************************************************
    750  * Methods to Handle File Upload Data Request
    751  *****************************************************************************/
    752 
    753 void HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf);
    754 
    755 
    756 void
    757 HandleFileUploadDataRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    758 {
    759 	int n = 0;
    760 	char* pBuf = NULL;
    761 	rfbClientToServerTightMsg msg;
    762 
    763 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    764 
    765 	if(cl == NULL) {
    766 		rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
    767 				__FILE__, __FUNCTION__);
    768 		return;
    769 	}
    770 
    771 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadDataMsg-1)) <= 0) {
    772 
    773 		if (n < 0)
    774 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
    775 					__FILE__, __FUNCTION__);
    776 
    777 	    rfbCloseClient(cl);
    778 	    return;
    779 	}
    780 
    781 	msg.fud.realSize = Swap16IfLE(msg.fud.realSize);
    782 	msg.fud.compressedSize = Swap16IfLE(msg.fud.compressedSize);
    783 	if((msg.fud.realSize == 0) && (msg.fud.compressedSize == 0)) {
    784 		if((n = rfbReadExact(cl, (char*)&(rtcp->rcft.rcfu.mTime), sizeof(unsigned
    785 		long))) <= 0) {
    786 
    787 			if (n < 0)
    788 				rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
    789 						__FILE__, __FUNCTION__);
    790 
    791 		    rfbCloseClient(cl);
    792 		    return;
    793 		}
    794 
    795 		FileUpdateComplete(cl, rtcp);
    796 		return;
    797 	}
    798 
    799 	pBuf = (char*) calloc(msg.fud.compressedSize, sizeof(char));
    800 	if(pBuf == NULL) {
    801 		rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__);
    802 		return;
    803 	}
    804 	if((n = rfbReadExact(cl, pBuf, msg.fud.compressedSize)) <= 0) {
    805 
    806 		if (n < 0)
    807 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
    808 					__FILE__, __FUNCTION__);
    809 
    810 	    rfbCloseClient(cl);
    811 
    812 	    if(pBuf != NULL) {
    813 	    	free(pBuf);
    814 	    	pBuf = NULL;
    815 		}
    816 
    817 	    return;
    818 	}
    819 	if(msg.fud.compressedLevel != 0) {
    820 		FileTransferMsg ftm;
    821 		memset(&ftm, 0, sizeof(FileTransferMsg));
    822 
    823 		ftm = GetFileUploadCompressedLevelErrMsg();
    824 
    825 		if((ftm.data != NULL) && (ftm.length != 0)) {
    826 			rfbWriteExact(cl, ftm.data, ftm.length);
    827 			FreeFileTransferMsg(ftm);
    828 		}
    829 
    830 		CloseUndoneFileTransfer(cl, rtcp);
    831 
    832 	    if(pBuf != NULL) {
    833 	    	free(pBuf);
    834 	    	pBuf = NULL;
    835 		}
    836 
    837 		return;
    838 	}
    839 
    840 	rtcp->rcft.rcfu.fSize = msg.fud.compressedSize;
    841 
    842 	HandleFileUploadWrite(cl, rtcp, pBuf);
    843 
    844     if(pBuf != NULL) {
    845     	free(pBuf);
    846     	pBuf = NULL;
    847 	}
    848 
    849 }
    850 
    851 
    852 void
    853 HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf)
    854 {
    855 	FileTransferMsg ftm;
    856 	memset(&ftm, 0, sizeof(FileTransferMsg));
    857 
    858 	ftm = ChkFileUploadWriteErr(cl, rtcp, pBuf);
    859 
    860 	if((ftm.data != NULL) && (ftm.length != 0)) {
    861 		rfbWriteExact(cl, ftm.data, ftm.length);
    862 		FreeFileTransferMsg(ftm);
    863 	}
    864 }
    865 
    866 
    867 /******************************************************************************
    868  * Methods to Handle File Upload Failed Request.
    869  ******************************************************************************/
    870 
    871 
    872 void
    873 HandleFileUploadFailedRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    874 {
    875 	int n = 0;
    876 	char* reason = NULL;
    877 	rfbClientToServerTightMsg msg;
    878 
    879 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    880 
    881 	if(cl == NULL) {
    882 		rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
    883 				__FILE__, __FUNCTION__);
    884 		return;
    885 	}
    886 
    887 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadFailedMsg-1)) <= 0) {
    888 
    889 		if (n < 0)
    890 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
    891 					__FILE__, __FUNCTION__);
    892 
    893 	    rfbCloseClient(cl);
    894 	    return;
    895 	}
    896 
    897 	msg.fuf.reasonLen = Swap16IfLE(msg.fuf.reasonLen);
    898 	if(msg.fuf.reasonLen  == 0) {
    899 		rfbLog("File [%s]: Method [%s]: reason length received is Zero\n",
    900 				__FILE__, __FUNCTION__);
    901 		return;
    902 	}
    903 
    904 
    905 	reason = (char*) calloc(msg.fuf.reasonLen + 1, sizeof(char));
    906 	if(reason == NULL) {
    907 		rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__);
    908 		return;
    909 	}
    910 
    911 	if((n = rfbReadExact(cl, reason, msg.fuf.reasonLen)) <= 0) {
    912 
    913 		if (n < 0)
    914 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
    915 					__FILE__, __FUNCTION__);
    916 
    917 	    rfbCloseClient(cl);
    918 
    919 		if(reason != NULL) {
    920 			free(reason);
    921 			reason = NULL;
    922 		}
    923 
    924 	    return;
    925 	}
    926 
    927 	rfbLog("File [%s]: Method [%s]: File Upload Failed Request received:"
    928 				" reason <%s>\n", __FILE__, __FUNCTION__, reason);
    929 
    930 	CloseUndoneFileTransfer(cl, rtcp);
    931 
    932 	if(reason != NULL) {
    933 		free(reason);
    934 		reason = NULL;
    935 	}
    936 
    937 }
    938 
    939 
    940 /******************************************************************************
    941  * Methods to Handle File Create Request.
    942  ******************************************************************************/
    943 
    944 
    945 void
    946 HandleFileCreateDirRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
    947 {
    948 	int n = 0;
    949 	char dirName[PATH_MAX];
    950 	rfbClientToServerTightMsg msg;
    951 
    952 	memset(dirName, 0, PATH_MAX);
    953 	memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
    954 
    955 	if(cl == NULL) {
    956 		rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
    957 				__FILE__, __FUNCTION__);
    958 		return;
    959 	}
    960 
    961 	if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileCreateDirRequestMsg-1)) <= 0) {
    962 
    963 		if (n < 0)
    964 			rfbLog("File [%s]: Method [%s]: Error while reading FileCreateDirRequestMsg\n",
    965 					__FILE__, __FUNCTION__);
    966 
    967 	    rfbCloseClient(cl);
    968 	    return;
    969 	}
    970 
    971 	msg.fcdr.dNameLen = Swap16IfLE(msg.fcdr.dNameLen);
    972 
    973 	/* TODO :: chk if the dNameLen is greater than PATH_MAX */
    974 
    975 	if((n = rfbReadExact(cl, dirName, msg.fcdr.dNameLen)) <= 0) {
    976 
    977 		if (n < 0)
    978 			rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
    979 					__FILE__, __FUNCTION__);
    980 
    981 	    rfbCloseClient(cl);
    982 	    return;
    983 	}
    984 
    985 	if(ConvertPath(dirName) == NULL) {
    986     	rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n",
    987     			__FILE__, __FUNCTION__);
    988 
    989     	return;
    990 	}
    991 
    992 	CreateDirectory(dirName);
    993 }
    994