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