+++ /dev/null
-/*
- * Copyright (c) 2005 Novell, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, contact Novell, Inc.
- *
- * To contact Novell about this file by physical or electronic mail,
- * you may find current contact information at www.novell.com
- *
- * Author : Rohit Kumar
- * Email ID : rokumar@novell.com
- * Date : 14th July 2005
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <utime.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <rfb/rfb.h>
-#include "rfbtightproto.h"
-#include "filelistinfo.h"
-#include "filetransfermsg.h"
-#include "handlefiletransferrequest.h"
-
-#define SZ_RFBBLOCKSIZE 8192
-
-
-void
-FreeFileTransferMsg(FileTransferMsg ftm)
-{
-
- if(ftm.data != NULL) {
- free(ftm.data);
- ftm.data = NULL;
- }
-
- ftm.length = 0;
-
-}
-
-
-/******************************************************************************
- * Methods to handle file list request.
- ******************************************************************************/
-
-int CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag);
-FileTransferMsg CreateFileListErrMsg(char flags);
-FileTransferMsg CreateFileListMsg(FileListInfo fileListInfo, char flags);
-
-
-/*
- * This is the method called by HandleFileListRequest to get the file list
- */
-
-FileTransferMsg
-GetFileListResponseMsg(char* path, char flags)
-{
- FileTransferMsg fileListMsg;
- FileListInfo fileListInfo;
- int status = -1;
-
- memset(&fileListMsg, 0, sizeof(FileTransferMsg));
- memset(&fileListInfo, 0, sizeof(FileListInfo));
-
-
- /* fileListInfo can have null data if the folder is Empty
- or if some error condition has occured.
- The return value is 'failure' only if some error condition has occured.
- */
- status = CreateFileListInfo(&fileListInfo, path, !(flags & 0x10));
-
- if(status == FAILURE) {
- fileListMsg = CreateFileListErrMsg(flags);
- }
- else {
- /* DisplayFileList(fileListInfo); For Debugging */
-
- fileListMsg = CreateFileListMsg(fileListInfo, flags);
- FreeFileListInfo(fileListInfo);
- }
-
- return fileListMsg;
-}
-
-#ifndef __GNUC__
-#define __FUNCTION__ "unknown"
-#endif
-
-int
-CreateFileListInfo(FileListInfoPtr pFileListInfo, char* path, int flag)
-{
- DIR* pDir = NULL;
- struct dirent* pDirent = NULL;
-
- if((path == NULL) || (strlen(path) == 0)) {
- /* In this case we will send the list of entries in ftp root*/
- sprintf(path, "%s%s", GetFtpRoot(), "/");
- }
-
- if((pDir = opendir(path)) == NULL) {
- rfbLog("File [%s]: Method [%s]: not able to open the dir\n",
- __FILE__, __FUNCTION__);
- return FAILURE;
- }
-
- while((pDirent = readdir(pDir))) {
- if(strcmp(pDirent->d_name, ".") && strcmp(pDirent->d_name, "..")) {
- struct stat stat_buf;
- /*
- int fpLen = sizeof(char)*(strlen(pDirent->d_name)+strlen(path)+2);
- */
- char fullpath[PATH_MAX];
-
- memset(fullpath, 0, PATH_MAX);
-
- strcpy(fullpath, path);
- if(path[strlen(path)-1] != '/')
- strcat(fullpath, "/");
- strcat(fullpath, pDirent->d_name);
-
- if(stat(fullpath, &stat_buf) < 0) {
- rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n",
- __FILE__, __FUNCTION__, fullpath);
- continue;
- }
-
- if(S_ISDIR(stat_buf.st_mode)) {
- if(AddFileListItemInfo(pFileListInfo, pDirent->d_name, -1, 0) == 0) {
- rfbLog("File [%s]: Method [%s]: Add directory %s in the"
- " list failed\n", __FILE__, __FUNCTION__, fullpath);
- continue;
- }
- }
- else {
- if(flag) {
- if(AddFileListItemInfo(pFileListInfo, pDirent->d_name,
- stat_buf.st_size,
- stat_buf.st_mtime) == 0) {
- rfbLog("File [%s]: Method [%s]: Add file %s in the "
- "list failed\n", __FILE__, __FUNCTION__, fullpath);
- continue;
- }
- }
- }
- }
- }
- if(closedir(pDir) < 0) {
- rfbLog("File [%s]: Method [%s]: ERROR Couldn't close dir\n",
- __FILE__, __FUNCTION__);
- }
-
- return SUCCESS;
-}
-
-
-FileTransferMsg
-CreateFileListErrMsg(char flags)
-{
- FileTransferMsg fileListMsg;
- rfbFileListDataMsg* pFLD = NULL;
- char* data = NULL;
- unsigned int length = 0;
-
- memset(&fileListMsg, 0, sizeof(FileTransferMsg));
-
- data = (char*) calloc(sizeof(rfbFileListDataMsg), sizeof(char));
- if(data == NULL) {
- return fileListMsg;
- }
- length = sizeof(rfbFileListDataMsg) * sizeof(char);
- pFLD = (rfbFileListDataMsg*) data;
-
- pFLD->type = rfbFileListData;
- pFLD->numFiles = Swap16IfLE(0);
- pFLD->dataSize = Swap16IfLE(0);
- pFLD->compressedSize = Swap16IfLE(0);
- pFLD->flags = flags | 0x80;
-
- fileListMsg.data = data;
- fileListMsg.length = length;
-
- return fileListMsg;
-}
-
-
-FileTransferMsg
-CreateFileListMsg(FileListInfo fileListInfo, char flags)
-{
- FileTransferMsg fileListMsg;
- rfbFileListDataMsg* pFLD = NULL;
- char *data = NULL, *pFileNames = NULL;
- unsigned int length = 0, dsSize = 0, i = 0;
- FileListItemSizePtr pFileListItemSize = NULL;
-
- memset(&fileListMsg, 0, sizeof(FileTransferMsg));
- dsSize = fileListInfo.numEntries * 8;
- length = sz_rfbFileListDataMsg + dsSize +
- GetSumOfFileNamesLength(fileListInfo) +
- fileListInfo.numEntries;
-
- data = (char*) calloc(length, sizeof(char));
- if(data == NULL) {
- return fileListMsg;
- }
- pFLD = (rfbFileListDataMsg*) data;
- pFileListItemSize = (FileListItemSizePtr) &data[sz_rfbFileListDataMsg];
- pFileNames = &data[sz_rfbFileListDataMsg + dsSize];
-
- pFLD->type = rfbFileListData;
- pFLD->flags = flags & 0xF0;
- pFLD->numFiles = Swap16IfLE(fileListInfo.numEntries);
- pFLD->dataSize = Swap16IfLE(GetSumOfFileNamesLength(fileListInfo) +
- fileListInfo.numEntries);
- pFLD->compressedSize = pFLD->dataSize;
-
- for(i =0; i <fileListInfo.numEntries; i++) {
- pFileListItemSize[i].size = Swap32IfLE(GetFileSizeAt(fileListInfo, i));
- pFileListItemSize[i].data = Swap32IfLE(GetFileDataAt(fileListInfo, i));
- strcpy(pFileNames, GetFileNameAt(fileListInfo, i));
-
- if(i+1 < fileListInfo.numEntries)
- pFileNames += strlen(pFileNames) + 1;
- }
-
- fileListMsg.data = data;
- fileListMsg.length = length;
-
- return fileListMsg;
-}
-
-
-/******************************************************************************
- * Methods to handle File Download Request.
- ******************************************************************************/
-
-FileTransferMsg CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen);
-FileTransferMsg CreateFileDownloadZeroSizeDataMsg(unsigned long mTime);
-FileTransferMsg CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile);
-
-FileTransferMsg
-GetFileDownLoadErrMsg()
-{
- FileTransferMsg fileDownloadErrMsg;
-
- char reason[] = "An internal error on the server caused download failure";
- int reasonLen = strlen(reason);
-
- memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
-
- fileDownloadErrMsg = CreateFileDownloadErrMsg(reason, reasonLen);
-
- return fileDownloadErrMsg;
-}
-
-
-FileTransferMsg
-GetFileDownloadReadDataErrMsg()
-{
- char reason[] = "Cannot open file, perhaps it is absent or is a directory";
- int reasonLen = strlen(reason);
-
- return CreateFileDownloadErrMsg(reason, reasonLen);
-
-}
-
-
-FileTransferMsg
-GetFileDownloadLengthErrResponseMsg()
-{
- char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
- int reasonLen = strlen(reason);
-
- return CreateFileDownloadErrMsg(reason, reasonLen);
-}
-
-
-FileTransferMsg
-GetFileDownloadResponseMsgInBlocks(rfbClientPtr cl, rfbTightClientPtr rtcp)
-{
- /* const unsigned int sz_rfbBlockSize = SZ_RFBBLOCKSIZE; */
- int numOfBytesRead = 0;
- char pBuf[SZ_RFBBLOCKSIZE];
- char* path = rtcp->rcft.rcfd.fName;
-
- memset(pBuf, 0, SZ_RFBBLOCKSIZE);
-
- if((rtcp->rcft.rcfd.downloadInProgress == FALSE) && (rtcp->rcft.rcfd.downloadFD == -1)) {
- if((rtcp->rcft.rcfd.downloadFD = open(path, O_RDONLY)) == -1) {
- rfbLog("File [%s]: Method [%s]: Error: Couldn't open file\n",
- __FILE__, __FUNCTION__);
- return GetFileDownloadReadDataErrMsg();
- }
- rtcp->rcft.rcfd.downloadInProgress = TRUE;
- }
- if((rtcp->rcft.rcfd.downloadInProgress == TRUE) && (rtcp->rcft.rcfd.downloadFD != -1)) {
- if( (numOfBytesRead = read(rtcp->rcft.rcfd.downloadFD, pBuf, SZ_RFBBLOCKSIZE)) <= 0) {
- close(rtcp->rcft.rcfd.downloadFD);
- rtcp->rcft.rcfd.downloadFD = -1;
- rtcp->rcft.rcfd.downloadInProgress = FALSE;
- if(numOfBytesRead == 0) {
- return CreateFileDownloadZeroSizeDataMsg(rtcp->rcft.rcfd.mTime);
- }
- return GetFileDownloadReadDataErrMsg();
- }
- return CreateFileDownloadBlockSizeDataMsg(numOfBytesRead, pBuf);
- }
- return GetFileDownLoadErrMsg();
-}
-
-
-FileTransferMsg
-ChkFileDownloadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
-{
- FileTransferMsg fileDownloadMsg;
- struct stat stat_buf;
- int sz_rfbFileSize = 0;
- char* path = rtcp->rcft.rcfd.fName;
-
- memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
-
- if( (path == NULL) || (strlen(path) == 0) ||
- (stat(path, &stat_buf) < 0) || (!(S_ISREG(stat_buf.st_mode))) ) {
-
- char reason[] = "Cannot open file, perhaps it is absent or is not a regular file";
- int reasonLen = strlen(reason);
-
- rfbLog("File [%s]: Method [%s]: Reading stat for path %s failed\n",
- __FILE__, __FUNCTION__, path);
-
- fileDownloadMsg = CreateFileDownloadErrMsg(reason, reasonLen);
- }
- else {
- rtcp->rcft.rcfd.mTime = stat_buf.st_mtime;
- sz_rfbFileSize = stat_buf.st_size;
- if(sz_rfbFileSize <= 0) {
- fileDownloadMsg = CreateFileDownloadZeroSizeDataMsg(stat_buf.st_mtime);
- }
-
- }
- return fileDownloadMsg;
-}
-
-
-FileTransferMsg
-CreateFileDownloadErrMsg(char* reason, unsigned int reasonLen)
-{
- FileTransferMsg fileDownloadErrMsg;
- int length = sz_rfbFileDownloadFailedMsg + reasonLen + 1;
- rfbFileDownloadFailedMsg *pFDF = NULL;
- char *pFollow = NULL;
-
- char *pData = (char*) calloc(length, sizeof(char));
- memset(&fileDownloadErrMsg, 0, sizeof(FileTransferMsg));
- if(pData == NULL) {
- rfbLog("File [%s]: Method [%s]: pData is NULL\n",
- __FILE__, __FUNCTION__);
- return fileDownloadErrMsg;
- }
-
- pFDF = (rfbFileDownloadFailedMsg *) pData;
- pFollow = &pData[sz_rfbFileDownloadFailedMsg];
-
- pFDF->type = rfbFileDownloadFailed;
- pFDF->reasonLen = Swap16IfLE(reasonLen);
- memcpy(pFollow, reason, reasonLen);
-
- fileDownloadErrMsg.data = pData;
- fileDownloadErrMsg.length = length;
-
- return fileDownloadErrMsg;
-}
-
-
-FileTransferMsg
-CreateFileDownloadZeroSizeDataMsg(unsigned long mTime)
-{
- FileTransferMsg fileDownloadZeroSizeDataMsg;
- int length = sz_rfbFileDownloadDataMsg + sizeof(int);
- rfbFileDownloadDataMsg *pFDD = NULL;
- char *pFollow = NULL;
-
- char *pData = (char*) calloc(length, sizeof(char));
- memset(&fileDownloadZeroSizeDataMsg, 0, sizeof(FileTransferMsg));
- if(pData == NULL) {
- rfbLog("File [%s]: Method [%s]: pData is NULL\n",
- __FILE__, __FUNCTION__);
- return fileDownloadZeroSizeDataMsg;
- }
-
- pFDD = (rfbFileDownloadDataMsg *) pData;
- pFollow = &pData[sz_rfbFileDownloadDataMsg];
-
- pFDD->type = rfbFileDownloadData;
- pFDD->compressLevel = 0;
- pFDD->compressedSize = Swap16IfLE(0);
- pFDD->realSize = Swap16IfLE(0);
-
- memcpy(pFollow, &mTime, sizeof(unsigned long));
-
- fileDownloadZeroSizeDataMsg.data = pData;
- fileDownloadZeroSizeDataMsg.length = length;
-
- return fileDownloadZeroSizeDataMsg;
-
-}
-
-
-FileTransferMsg
-CreateFileDownloadBlockSizeDataMsg(unsigned short sizeFile, char *pFile)
-{
- FileTransferMsg fileDownloadBlockSizeDataMsg;
- int length = sz_rfbFileDownloadDataMsg + sizeFile;
- rfbFileDownloadDataMsg *pFDD = NULL;
- char *pFollow = NULL;
-
- char *pData = (char*) calloc(length, sizeof(char));
- memset(&fileDownloadBlockSizeDataMsg, 0, sizeof(FileTransferMsg));
- if(NULL == pData) {
- rfbLog("File [%s]: Method [%s]: pData is NULL\n",
- __FILE__, __FUNCTION__);
- return fileDownloadBlockSizeDataMsg;
- }
-
- pFDD = (rfbFileDownloadDataMsg *) pData;
- pFollow = &pData[sz_rfbFileDownloadDataMsg];
-
- pFDD->type = rfbFileDownloadData;
- pFDD->compressLevel = 0;
- pFDD->compressedSize = Swap16IfLE(sizeFile);
- pFDD->realSize = Swap16IfLE(sizeFile);
-
- memcpy(pFollow, pFile, sizeFile);
-
- fileDownloadBlockSizeDataMsg.data = pData;
- fileDownloadBlockSizeDataMsg.length = length;
-
- return fileDownloadBlockSizeDataMsg;
-
-}
-
-
-/******************************************************************************
- * Methods to handle file upload request
- ******************************************************************************/
-
-FileTransferMsg CreateFileUploadErrMsg(char* reason, unsigned int reasonLen);
-
-FileTransferMsg
-GetFileUploadLengthErrResponseMsg()
-{
- char reason [] = "Path length exceeds PATH_MAX (4096) bytes";
- int reasonLen = strlen(reason);
-
- return CreateFileUploadErrMsg(reason, reasonLen);
-}
-
-
-FileTransferMsg
-ChkFileUploadErr(rfbClientPtr cl, rfbTightClientPtr rtcp)
-{
- FileTransferMsg fileUploadErrMsg;
-
- memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
- if( (rtcp->rcft.rcfu.fName == NULL) ||
- (strlen(rtcp->rcft.rcfu.fName) == 0) ||
- ((rtcp->rcft.rcfu.uploadFD = creat(rtcp->rcft.rcfu.fName,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1)) {
-
- char reason[] = "Could not create file";
- int reasonLen = strlen(reason);
- fileUploadErrMsg = CreateFileUploadErrMsg(reason, reasonLen);
- }
- else
- rtcp->rcft.rcfu.uploadInProgress = TRUE;
-
- return fileUploadErrMsg;
-}
-
-
-FileTransferMsg
-GetFileUploadCompressedLevelErrMsg()
-{
- char reason[] = "Server does not support data compression on upload";
- int reasonLen = strlen(reason);
-
- return CreateFileUploadErrMsg(reason, reasonLen);
-}
-
-
-FileTransferMsg
-ChkFileUploadWriteErr(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf)
-{
- FileTransferMsg ftm;
- unsigned long numOfBytesWritten = 0;
-
- memset(&ftm, 0, sizeof(FileTransferMsg));
-
- numOfBytesWritten = write(rtcp->rcft.rcfu.uploadFD, pBuf, rtcp->rcft.rcfu.fSize);
-
- if(numOfBytesWritten != rtcp->rcft.rcfu.fSize) {
- char reason[] = "Error writing file data";
- int reasonLen = strlen(reason);
- ftm = CreateFileUploadErrMsg(reason, reasonLen);
- CloseUndoneFileTransfer(cl, rtcp);
- }
- return ftm;
-}
-
-
-void
-FileUpdateComplete(rfbClientPtr cl, rfbTightClientPtr rtcp)
-{
- /* Here we are settimg the modification and access time of the file */
- /* Windows code stes mod/access/creation time of the file */
- struct utimbuf utb;
-
- utb.actime = utb.modtime = rtcp->rcft.rcfu.mTime;
- if(utime(rtcp->rcft.rcfu.fName, &utb) == -1) {
- rfbLog("File [%s]: Method [%s]: Setting the modification/access"
- " time for the file <%s> failed\n", __FILE__,
- __FUNCTION__, rtcp->rcft.rcfu.fName);
- }
-
- if(rtcp->rcft.rcfu.uploadFD != -1) {
- close(rtcp->rcft.rcfu.uploadFD);
- rtcp->rcft.rcfu.uploadFD = -1;
- rtcp->rcft.rcfu.uploadInProgress = FALSE;
- }
-}
-
-
-FileTransferMsg
-CreateFileUploadErrMsg(char* reason, unsigned int reasonLen)
-{
- FileTransferMsg fileUploadErrMsg;
- int length = sz_rfbFileUploadCancelMsg + reasonLen;
- rfbFileUploadCancelMsg *pFDF = NULL;
- char *pFollow = NULL;
-
- char *pData = (char*) calloc(length, sizeof(char));
- memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
- if(pData == NULL) {
- rfbLog("File [%s]: Method [%s]: pData is NULL\n",
- __FILE__, __FUNCTION__);
- return fileUploadErrMsg;
- }
-
- pFDF = (rfbFileUploadCancelMsg *) pData;
- pFollow = &pData[sz_rfbFileUploadCancelMsg];
-
- pFDF->type = rfbFileUploadCancel;
- pFDF->reasonLen = Swap16IfLE(reasonLen);
- memcpy(pFollow, reason, reasonLen);
-
- fileUploadErrMsg.data = pData;
- fileUploadErrMsg.length = length;
-
- return fileUploadErrMsg;
-}
-
-
-/******************************************************************************
- * Method to cancel File Transfer operation.
- ******************************************************************************/
-
-void
-CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr rtcp)
-{
- /* TODO :: File Upload case is not handled currently */
- /* TODO :: In case of concurrency we need to use Critical Section */
-
- if(cl == NULL)
- return;
-
-
- if(rtcp->rcft.rcfu.uploadInProgress == TRUE) {
- rtcp->rcft.rcfu.uploadInProgress = FALSE;
-
- if(rtcp->rcft.rcfu.uploadFD != -1) {
- close(rtcp->rcft.rcfu.uploadFD);
- rtcp->rcft.rcfu.uploadFD = -1;
- }
-
- if(unlink(rtcp->rcft.rcfu.fName) == -1) {
- rfbLog("File [%s]: Method [%s]: Delete operation on file <%s> failed\n",
- __FILE__, __FUNCTION__, rtcp->rcft.rcfu.fName);
- }
-
- memset(rtcp->rcft.rcfu.fName, 0 , PATH_MAX);
- }
-
- if(rtcp->rcft.rcfd.downloadInProgress == TRUE) {
- rtcp->rcft.rcfd.downloadInProgress = FALSE;
-
- if(rtcp->rcft.rcfd.downloadFD != -1) {
- close(rtcp->rcft.rcfd.downloadFD);
- rtcp->rcft.rcfd.downloadFD = -1;
- }
- memset(rtcp->rcft.rcfd.fName, 0 , PATH_MAX);
- }
-}
-
-
-/******************************************************************************
- * Method to handle create directory request.
- ******************************************************************************/
-
-void
-CreateDirectory(char* dirName)
-{
- if(dirName == NULL) return;
-
- if(mkdir(dirName, 0700) == -1) {
- rfbLog("File [%s]: Method [%s]: Create operation for directory <%s> failed\n",
- __FILE__, __FUNCTION__, dirName);
- }
-}
-