LibVNCServer/LibVNCClient
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
handlefiletransferrequest.c
Go to the documentation of this file.
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 #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"
40 
41 
42 pthread_mutex_t fileDownloadMutex = PTHREAD_MUTEX_INITIALIZER;
43 
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
67 {
68  char* userHome = NULL;
69  uid_t uid = geteuid();
70 
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 
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
217 {
218  fileTransferEnabled = enable;
219 }
220 
221 
222 rfbBool
224 {
225  return fileTransferEnabled;
226 }
227 
228 
229 char*
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
251 {
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 
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 */
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 
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 
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 
440 }
441 
442 
443 void
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*
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) {
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;
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 */
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 
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__);
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  */
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 
710 }
711 
712 void
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;
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);
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 
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;
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];
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 }