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@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
FreeFileTransferMsg(FileTransferMsg ftm)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
GetFileListResponseMsg(char * path,char flags)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
CreateFileListInfo(FileListInfoPtr pFileListInfo,char * path,int flag)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
CreateFileListErrMsg(char flags)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
CreateFileListMsg(FileListInfo fileListInfo,char flags)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
GetFileDownLoadErrMsg()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
GetFileDownloadReadDataErrMsg()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
GetFileDownloadLengthErrResponseMsg()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
GetFileDownloadResponseMsgInBlocks(rfbClientPtr cl,rfbTightClientPtr rtcp)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
ChkFileDownloadErr(rfbClientPtr cl,rfbTightClientPtr rtcp)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
CreateFileDownloadErrMsg(char * reason,unsigned int reasonLen)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
CreateFileDownloadZeroSizeDataMsg(unsigned long mTime)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
CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile,char * pFile)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
GetFileUploadLengthErrResponseMsg()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
ChkFileUploadErr(rfbClientPtr cl,rfbTightClientPtr rtcp)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
GetFileUploadCompressedLevelErrMsg()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
ChkFileUploadWriteErr(rfbClientPtr cl,rfbTightClientPtr rtcp,char * pBuf)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
FileUpdateComplete(rfbClientPtr cl,rfbTightClientPtr rtcp)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
CreateFileUploadErrMsg(char * reason,unsigned int reasonLen)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
CloseUndoneFileTransfer(rfbClientPtr cl,rfbTightClientPtr rtcp)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
CreateDirectory(char * dirName)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