mirror of
https://github.com/glest/glest-source.git
synced 2025-08-14 12:23:59 +02:00
1234 lines
48 KiB
C++
1234 lines
48 KiB
C++
// This file is part of Glest <https://github.com/Glest>
|
|
//
|
|
// Copyright (C) 2018 The Glest team
|
|
//
|
|
// Glest is a fork of MegaGlest <https://megaglest.org/>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// 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, see <https://www.gnu.org/licenses/>
|
|
|
|
#include "miniftpclient.h"
|
|
#include "util.h"
|
|
#include "platform_common.h"
|
|
|
|
#include <curl/curl.h>
|
|
#include <curl/easy.h>
|
|
#include <algorithm>
|
|
#include "conversion.h"
|
|
#include "platform_util.h"
|
|
|
|
using namespace Shared::Util;
|
|
using namespace Shared::PlatformCommon;
|
|
|
|
namespace Shared {
|
|
namespace PlatformCommon {
|
|
|
|
static const char *FTP_MAPS_CUSTOM_USERNAME = "maps_custom";
|
|
static const char *FTP_MAPS_USERNAME = "maps";
|
|
static const char *FTP_TILESETS_CUSTOM_USERNAME = "tilesets_custom";
|
|
static const char *FTP_TILESETS_USERNAME = "tilesets";
|
|
static const char *FTP_TECHTREES_CUSTOM_USERNAME = "techtrees_custom";
|
|
static const char *FTP_TECHTREES_USERNAME = "techtrees";
|
|
|
|
static const char *FTP_TEMPFILES_USERNAME = "temp";
|
|
|
|
static const char *FTP_COMMON_PASSWORD = "mg_ftp_server";
|
|
|
|
/*
|
|
* This is an example showing how to get a single file from an FTP server.
|
|
* It delays the actual destination file creation until the first write
|
|
* callback so that it won't create an empty file in case the remote file
|
|
* doesn't exist or something else fails.
|
|
*/
|
|
|
|
struct FtpFile {
|
|
const char *itemName;
|
|
const char *filename;
|
|
const char *filepath;
|
|
FILE *stream;
|
|
FTPClientThread *ftpServer;
|
|
string currentFilename;
|
|
bool isValidXfer;
|
|
FTP_Client_CallbackType downloadType;
|
|
};
|
|
|
|
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
|
|
struct FtpFile *out = (struct FtpFile *)stream;
|
|
|
|
string fullFilePath = "";
|
|
if (out != NULL && out->filepath != NULL) {
|
|
fullFilePath = out->filepath;
|
|
}
|
|
if (out != NULL && out->filename != NULL) {
|
|
fullFilePath += out->filename;
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread writing to file [%s]\n", fullFilePath.c_str());
|
|
//printf ("===> FTP Client thread writing to file [%s]\n",fullFilePath.c_str());
|
|
|
|
// Abort file xfer and delete partial file
|
|
if (out && out->ftpServer && out->ftpServer->getQuitStatus() == true) {
|
|
if (out->stream) {
|
|
fclose(out->stream);
|
|
out->stream = NULL;
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread CANCELLED, deleting file for writing [%s]\n", fullFilePath.c_str());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread CANCELLED, deleting file for writing [%s]\n", fullFilePath.c_str());
|
|
|
|
|
|
removeFile(fullFilePath);
|
|
return 0;
|
|
}
|
|
|
|
if (out && out->stream == NULL) {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread opening file for writing [%s]\n", fullFilePath.c_str());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread opening file for writing [%s]\n", fullFilePath.c_str());
|
|
|
|
/* open file for writing */
|
|
#ifdef WIN32
|
|
out->stream = _wfopen(utf8_decode(fullFilePath).c_str(), L"wb");
|
|
#else
|
|
out->stream = fopen(fullFilePath.c_str(), "wb");
|
|
#endif
|
|
if (out->stream == NULL) {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, "===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
return 0; /* failure, can't open file to write */
|
|
}
|
|
|
|
out->isValidXfer = true;
|
|
} else if (out == NULL) {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, "===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str());
|
|
return 0; /* failure, can't open file to write */
|
|
}
|
|
|
|
size_t result = fwrite(buffer, size, nmemb, out->stream);
|
|
if (result != nmemb) {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " SIZE_T_SPECIFIER ", result = " SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " SIZE_T_SPECIFIER ", result = " SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result);
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, "===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " SIZE_T_SPECIFIER ", result = " SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result);
|
|
//return -1; /* failure, can't open file to write */
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
static long file_is_comming(struct curl_fileinfo *finfo,void *data,int remains) {
|
|
struct FtpFile *out=(struct FtpFile *)data;
|
|
|
|
string rootFilePath = "";
|
|
string fullFilePath = "";
|
|
if(out != NULL && out->filepath != NULL) {
|
|
rootFilePath = out->filepath;
|
|
}
|
|
if(out != NULL && out->filename != NULL) {
|
|
fullFilePath = rootFilePath + finfo->filename;
|
|
}
|
|
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size);
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size);
|
|
|
|
if(out != NULL) {
|
|
//out->currentFilename = finfo->filename;
|
|
out->currentFilename = fullFilePath;
|
|
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" current filename: [%s] ", fullFilePath.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"current filename: [%s] ", fullFilePath.c_str());
|
|
}
|
|
|
|
switch(finfo->filetype) {
|
|
case CURLFILETYPE_DIRECTORY:
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename);
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork," DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename);
|
|
|
|
rootFilePath += finfo->filename;
|
|
createDirectoryPaths(rootFilePath.c_str());
|
|
break;
|
|
case CURLFILETYPE_FILE:
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" FILE ");
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork," FILE ");
|
|
break;
|
|
default:
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" OTHER\n");
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork," OTHER\n");
|
|
break;
|
|
}
|
|
|
|
if(finfo->filetype == CURLFILETYPE_FILE) {
|
|
// do not transfer files >= 50B
|
|
//if(finfo->size > 50) {
|
|
// printf("SKIPPED\n");
|
|
// return CURL_CHUNK_BGN_FUNC_SKIP;
|
|
//}
|
|
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" opening file [%s] ", fullFilePath.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork," opening file [%s] ", fullFilePath.c_str());
|
|
|
|
out->stream = fopen(fullFilePath.c_str(), "wb");
|
|
if(out->stream == NULL) {
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str());
|
|
|
|
return CURL_CHUNK_BGN_FUNC_FAIL;
|
|
}
|
|
}
|
|
|
|
out->isValidXfer = true;
|
|
return CURL_CHUNK_BGN_FUNC_OK;
|
|
}
|
|
|
|
static long file_is_downloaded(void *data) {
|
|
struct FtpFile *out=(struct FtpFile *)data;
|
|
if(out->stream) {
|
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("DOWNLOAD COMPLETE!\n");
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"DOWNLOAD COMPLETE!\n");
|
|
|
|
fclose(out->stream);
|
|
out->stream = NULL;
|
|
}
|
|
return CURL_CHUNK_END_FUNC_OK;
|
|
}
|
|
*/
|
|
|
|
int file_progress(struct FtpFile *out, double download_total, double download_now, double upload_total, double upload_now) {
|
|
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" download progress [%f][%f][%f][%f] ",download_total,download_now,upload_total,upload_now);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, " download progress [%f][%f][%f][%f] ", download_total, download_now, upload_total, upload_now);
|
|
|
|
if (out != NULL &&
|
|
out->ftpServer != NULL &&
|
|
out->ftpServer->getCallBackObject() != NULL) {
|
|
if (out->ftpServer->getQuitStatus() == true) {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread CANCELLED\n");
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread CANCELLED\n");
|
|
|
|
return -1;
|
|
}
|
|
FTPClientCallbackInterface::FtpProgressStats stats;
|
|
stats.download_total = download_total;
|
|
stats.download_now = download_now;
|
|
stats.upload_total = upload_total;
|
|
stats.upload_now = upload_now;
|
|
stats.currentFilename = out->currentFilename;
|
|
stats.downloadType = out->downloadType;
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex(), mutexOwnerId);
|
|
out->ftpServer->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent(
|
|
out->itemName,
|
|
ftp_cct_DownloadProgress,
|
|
make_pair(ftp_crt_SUCCESS, ""),
|
|
&stats);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
FTPClientThread::FTPClientThread(int portNumber, string serverUrl,
|
|
std::pair<string, string> mapsPath,
|
|
std::pair<string, string> tilesetsPath,
|
|
std::pair<string, string> techtreesPath,
|
|
std::pair<string, string> scenariosPath,
|
|
FTPClientCallbackInterface *pCBObject,
|
|
string fileArchiveExtension,
|
|
string fileArchiveExtractCommand,
|
|
string fileArchiveExtractCommandParameters,
|
|
int fileArchiveExtractCommandSuccessResult,
|
|
string tempFilesPath) : BaseThread() {
|
|
|
|
uniqueID = "FTPClientThread";
|
|
this->portNumber = portNumber;
|
|
this->serverUrl = serverUrl;
|
|
this->mapsPath = mapsPath;
|
|
this->tilesetsPath = tilesetsPath;
|
|
this->techtreesPath = techtreesPath;
|
|
this->scenariosPath = scenariosPath;
|
|
this->pCBObject = pCBObject;
|
|
this->shellCommandCallbackUserData = "";
|
|
|
|
this->fileArchiveExtension = fileArchiveExtension;
|
|
this->fileArchiveExtractCommand = fileArchiveExtractCommand;
|
|
this->fileArchiveExtractCommandParameters = fileArchiveExtractCommandParameters;
|
|
this->fileArchiveExtractCommandSuccessResult = fileArchiveExtractCommandSuccessResult;
|
|
this->tempFilesPath = tempFilesPath;
|
|
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] Using FTP port #: %d, serverUrl [%s]\n", __FILE__, __FUNCTION__, __LINE__, portNumber, serverUrl.c_str());
|
|
}
|
|
|
|
void FTPClientThread::signalQuit() {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: signalQuit\n");
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client: signalQuit\n");
|
|
BaseThread::signalQuit();
|
|
}
|
|
|
|
bool FTPClientThread::shutdownAndWait() {
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: shutdownAndWait\n");
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client: shutdownAndWait\n");
|
|
|
|
signalQuit();
|
|
return BaseThread::shutdownAndWait();
|
|
}
|
|
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getMapFromServer(pair<string, string> mapFileName, string ftpUser, string ftpUserPassword) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
|
|
string destFileExt = "";
|
|
string destFile = this->mapsPath.second;
|
|
|
|
endPathWithSlash(destFile);
|
|
destFile += mapFileName.first;
|
|
|
|
if (mapFileName.second == "") {
|
|
if (EndsWith(destFile, ".mgm") == false && EndsWith(destFile, ".gbm") == false) {
|
|
destFileExt = ".mgm";
|
|
destFile += destFileExt;
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s]\n", destFile.c_str());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread about to try to RETR into [%s]\n", destFile.c_str());
|
|
|
|
struct FtpFile ftpfile = {
|
|
NULL,
|
|
destFile.c_str(), /* name to store the file as if succesful */
|
|
NULL,
|
|
NULL,
|
|
this,
|
|
"",
|
|
false,
|
|
ftp_cct_Map
|
|
};
|
|
|
|
CURL *curl = SystemFlags::initHTTP();
|
|
if (curl) {
|
|
ftpfile.stream = NULL;
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
|
char szBuf[8096] = "";
|
|
if (mapFileName.second != "") {
|
|
snprintf(szBuf, 8096, "%s", mapFileName.second.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
|
} else {
|
|
snprintf(szBuf, 8096, "ftp://%s:%s@%s:%d/%s%s", ftpUser.c_str(), ftpUserPassword.c_str(), serverUrl.c_str(), portNumber, mapFileName.first.c_str(), destFileExt.c_str());
|
|
}
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, szBuf);
|
|
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L);
|
|
|
|
/* Define our callback to get called when there's data to be written */
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
|
/* Set a pointer to our struct to pass to the callback */
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
|
|
|
|
|
// Max 10 minutes to transfer
|
|
//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600);
|
|
// Max 60 minutes to transfer
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L);
|
|
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L);
|
|
|
|
/* Switch on full protocol/debug output */
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
|
|
|
CURLcode res = curl_easy_perform(curl);
|
|
if (res != CURLE_OK) {
|
|
result.second = curl_easy_strerror(res);
|
|
// we failed
|
|
printf("curl FAILED with: %d [%s] szBuf [%s]\n", res, curl_easy_strerror(res), szBuf);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "curl FAILED with: %d [%s] szBuf [%s]\n", res, curl_easy_strerror(res), szBuf);
|
|
|
|
if (res == CURLE_PARTIAL_FILE) {
|
|
result.first = ftp_crt_PARTIALFAIL;
|
|
} else if (res == CURLE_COULDNT_CONNECT) {
|
|
result.first = ftp_crt_HOST_NOT_ACCEPTING;
|
|
}
|
|
} else {
|
|
result.first = ftp_crt_SUCCESS;
|
|
}
|
|
|
|
SystemFlags::cleanupHTTP(&curl);
|
|
}
|
|
|
|
if (ftpfile.stream) {
|
|
fclose(ftpfile.stream);
|
|
ftpfile.stream = NULL;
|
|
}
|
|
if (result.first != ftp_crt_SUCCESS) {
|
|
removeFile(destFile);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void FTPClientThread::getMapFromServer(pair<string, string> mapFileName) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
if (mapFileName.second != "") {
|
|
result = getMapFromServer(mapFileName, "", "");
|
|
} else {
|
|
pair<string, string> findMapFileName = mapFileName;
|
|
findMapFileName.first += +".mgm";
|
|
|
|
result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
findMapFileName = mapFileName;
|
|
findMapFileName.first += +".gbm";
|
|
result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
findMapFileName = mapFileName;
|
|
findMapFileName.first += +".mgm";
|
|
result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
findMapFileName = mapFileName;
|
|
findMapFileName.first += +".mgm";
|
|
result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
findMapFileName = mapFileName;
|
|
findMapFileName.first += +".gbm";
|
|
result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
mapFileName.first,
|
|
ftp_cct_Map,
|
|
result,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addMapToRequests(string mapFilename, string URL) {
|
|
std::pair<string, string> item = make_pair(mapFilename, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexMapFileList, mutexOwnerId);
|
|
mutexMapFileList.setOwnerId(mutexOwnerId);
|
|
if (std::find(mapFileList.begin(), mapFileList.end(), item) == mapFileList.end()) {
|
|
mapFileList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addTilesetToRequests(string tileSetName, string URL) {
|
|
std::pair<string, string> item = make_pair(tileSetName, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexTilesetList, mutexOwnerId);
|
|
mutexTilesetList.setOwnerId(mutexOwnerId);
|
|
if (std::find(tilesetList.begin(), tilesetList.end(), item) == tilesetList.end()) {
|
|
tilesetList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addTechtreeToRequests(string techtreeName, string URL) {
|
|
std::pair<string, string> item = make_pair(techtreeName, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexTechtreeList, mutexOwnerId);
|
|
mutexTechtreeList.setOwnerId(mutexOwnerId);
|
|
if (std::find(techtreeList.begin(), techtreeList.end(), item) == techtreeList.end()) {
|
|
techtreeList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addScenarioToRequests(string fileName, string URL) {
|
|
std::pair<string, string> item = make_pair(fileName, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexScenarioList, mutexOwnerId);
|
|
mutexScenarioList.setOwnerId(mutexOwnerId);
|
|
if (std::find(scenarioList.begin(), scenarioList.end(), item) == scenarioList.end()) {
|
|
scenarioList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addFileToRequests(string fileName, string URL) {
|
|
std::pair<string, string> item = make_pair(fileName, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexFileList, mutexOwnerId);
|
|
mutexFileList.setOwnerId(mutexOwnerId);
|
|
if (std::find(fileList.begin(), fileList.end(), item) == fileList.end()) {
|
|
fileList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::addTempFileToRequests(string fileName, string URL) {
|
|
std::pair<string, string> item = make_pair(fileName, URL);
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexTempFileList, mutexOwnerId);
|
|
mutexTempFileList.setOwnerId(mutexOwnerId);
|
|
if (std::find(tempFileList.begin(), tempFileList.end(), item) == tempFileList.end()) {
|
|
tempFileList.push_back(item);
|
|
}
|
|
}
|
|
|
|
void FTPClientThread::getTilesetFromServer(pair<string, string> tileSetName) {
|
|
bool findArchive = executeShellCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandSuccessResult);
|
|
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
if (findArchive == true) {
|
|
if (tileSetName.second != "") {
|
|
//result = getTilesetFromServer(tileSetName, "", "", "", findArchive);
|
|
result = getTilesetFromServer(tileSetName, "", "", "", true);
|
|
} else {
|
|
//result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, findArchive);
|
|
result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
//if(findArchive == true) {
|
|
//result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, false);
|
|
result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true);
|
|
//}
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
// result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive);
|
|
result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, true);
|
|
|
|
// if(findArchive == true) {
|
|
// result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, false);
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
tileSetName.first,
|
|
ftp_cct_Tileset,
|
|
result,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getTilesetFromServer(
|
|
pair<string, string> tileSetName,
|
|
string tileSetNameSubfolder,
|
|
string ftpUser,
|
|
string ftpUserPassword,
|
|
bool findArchive) {
|
|
|
|
string destFileSaveAsNewFile = "";
|
|
string destFileSaveAs = "";
|
|
string remotePath = "";
|
|
bool getFolderContents = false;
|
|
vector<string> wantDirListOnly;
|
|
|
|
if (tileSetNameSubfolder == "") {
|
|
if (findArchive == true) {
|
|
destFileSaveAs = this->tilesetsPath.second;
|
|
endPathWithSlash(destFileSaveAs);
|
|
destFileSaveAs += tileSetName.first + this->fileArchiveExtension;
|
|
|
|
if (tileSetName.second != "") {
|
|
remotePath = tileSetName.second;
|
|
} else {
|
|
remotePath = tileSetName.first + this->fileArchiveExtension;
|
|
}
|
|
} else {
|
|
getFolderContents = true;
|
|
remotePath = tileSetName.first + "/";
|
|
destFileSaveAs = this->tilesetsPath.second;
|
|
endPathWithSlash(destFileSaveAs);
|
|
destFileSaveAs += tileSetName.first;
|
|
destFileSaveAsNewFile = destFileSaveAs;
|
|
endPathWithSlash(destFileSaveAsNewFile);
|
|
destFileSaveAs += ".tmp";
|
|
}
|
|
} else {
|
|
getFolderContents = true;
|
|
remotePath = tileSetName.first + "/" + tileSetNameSubfolder + "/";
|
|
destFileSaveAs = this->tilesetsPath.second;
|
|
endPathWithSlash(destFileSaveAs);
|
|
destFileSaveAs += tileSetName.first;
|
|
endPathWithSlash(destFileSaveAs);
|
|
|
|
destFileSaveAs += tileSetNameSubfolder;
|
|
destFileSaveAsNewFile = destFileSaveAs;
|
|
endPathWithSlash(destFileSaveAsNewFile);
|
|
destFileSaveAs += ".tmp";
|
|
}
|
|
|
|
vector <string> *pWantDirListOnly = NULL;
|
|
if (getFolderContents == true) {
|
|
pWantDirListOnly = &wantDirListOnly;
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d findArchive = %d\n", tileSetName.first.c_str(), remotePath.c_str(), destFileSaveAs.c_str(), getFolderContents, findArchive);
|
|
|
|
pair<FTP_Client_ResultType, string> result = getFileFromServer(
|
|
ftp_cct_Tileset,
|
|
tileSetName,
|
|
remotePath,
|
|
destFileSaveAs,
|
|
ftpUser,
|
|
ftpUserPassword,
|
|
pWantDirListOnly);
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d result.first = %d [%s] findArchive = %d\n", tileSetName.first.c_str(), remotePath.c_str(), destFileSaveAs.c_str(), getFolderContents, result.first, result.second.c_str(), findArchive);
|
|
|
|
// Extract the archive
|
|
if (result.first == ftp_crt_SUCCESS) {
|
|
if (findArchive == true) {
|
|
string destRootArchiveFolder = this->tilesetsPath.second;
|
|
endPathWithSlash(destRootArchiveFolder);
|
|
|
|
string extractCmd = getFullFileArchiveExtractCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandParameters,
|
|
destRootArchiveFolder,
|
|
destRootArchiveFolder + tileSetName.first + this->fileArchiveExtension);
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
|
|
if (this->pCBObject != NULL) {
|
|
this->shellCommandCallbackUserData = tileSetName.first;
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
tileSetName.first,
|
|
ftp_cct_ExtractProgress,
|
|
make_pair(ftp_crt_SUCCESS, "extracting"), NULL);
|
|
}
|
|
safeMutex.ReleaseLock();
|
|
|
|
if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) {
|
|
result.first = ftp_crt_FAIL;
|
|
result.second = "failed to extract archive!";
|
|
}
|
|
|
|
return result;
|
|
} else {
|
|
if (getFolderContents == true) {
|
|
removeFile(destFileSaveAs);
|
|
|
|
for (unsigned int i = 0; i < wantDirListOnly.size(); ++i) {
|
|
string fileFromList = wantDirListOnly[i];
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("fileFromList [%s] i [%u]\n", fileFromList.c_str(), i);
|
|
|
|
if (fileFromList != "models" && fileFromList != "textures" &&
|
|
fileFromList != "sounds") {
|
|
result = getFileFromServer(ftp_cct_Tileset,
|
|
tileSetName,
|
|
remotePath + fileFromList,
|
|
destFileSaveAsNewFile + fileFromList,
|
|
ftpUser, ftpUserPassword);
|
|
if (result.first != ftp_crt_SUCCESS) {
|
|
break;
|
|
}
|
|
} else {
|
|
result = getTilesetFromServer(tileSetName,
|
|
fileFromList, ftpUser, ftpUserPassword,
|
|
findArchive);
|
|
if (result.first != ftp_crt_SUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result.first != ftp_crt_SUCCESS && findArchive == false) {
|
|
string destRootFolder = this->tilesetsPath.second;
|
|
endPathWithSlash(destRootFolder);
|
|
destRootFolder += tileSetName.first;
|
|
endPathWithSlash(destRootFolder);
|
|
|
|
removeFolder(destRootFolder);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void FTPClientThread::getTechtreeFromServer(pair<string, string> techtreeName) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
bool findArchive = executeShellCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandSuccessResult);
|
|
if (findArchive == true) {
|
|
if (techtreeName.second != "") {
|
|
result = getTechtreeFromServer(techtreeName, "", "");
|
|
} else {
|
|
result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD);
|
|
if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) {
|
|
result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD);
|
|
}
|
|
}
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
techtreeName.first,
|
|
ftp_cct_Techtree,
|
|
result,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getTechtreeFromServer(pair<string, string> techtreeName,
|
|
string ftpUser, string ftpUserPassword) {
|
|
|
|
// Root folder for the techtree
|
|
string destRootFolder = this->techtreesPath.second;
|
|
endPathWithSlash(destRootFolder);
|
|
string destRootArchiveFolder = destRootFolder;
|
|
destRootFolder += techtreeName.first;
|
|
endPathWithSlash(destRootFolder);
|
|
|
|
string destFile = this->techtreesPath.second;
|
|
endPathWithSlash(destFile);
|
|
destFile += techtreeName.first;
|
|
string destFileSaveAs = destFile + this->fileArchiveExtension;
|
|
endPathWithSlash(destFile);
|
|
|
|
string remotePath = techtreeName.first + this->fileArchiveExtension;
|
|
if (techtreeName.second != "") {
|
|
remotePath = techtreeName.second;
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> result = getFileFromServer(ftp_cct_Techtree,
|
|
techtreeName, remotePath, destFileSaveAs, ftpUser, ftpUserPassword);
|
|
|
|
// Extract the archive
|
|
if (result.first == ftp_crt_SUCCESS) {
|
|
string extractCmd = getFullFileArchiveExtractCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandParameters,
|
|
destRootArchiveFolder,
|
|
destRootArchiveFolder + techtreeName.first + this->fileArchiveExtension);
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->shellCommandCallbackUserData = techtreeName.first;
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
techtreeName.first,
|
|
ftp_cct_ExtractProgress,
|
|
make_pair(ftp_crt_SUCCESS, "extracting"), NULL);
|
|
}
|
|
safeMutex.ReleaseLock();
|
|
|
|
if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) {
|
|
result.first = ftp_crt_FAIL;
|
|
result.second = "failed to extract archive!";
|
|
}
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
void FTPClientThread::getScenarioFromServer(pair<string, string> fileName) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
bool findArchive = executeShellCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandSuccessResult);
|
|
if (findArchive == true) {
|
|
result = getScenarioInternalFromServer(fileName);
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
fileName.first,
|
|
ftp_cct_Scenario,
|
|
result,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getScenarioInternalFromServer(pair<string, string> fileName) {
|
|
// Root folder for the techtree
|
|
string destRootFolder = this->scenariosPath.second;
|
|
endPathWithSlash(destRootFolder);
|
|
string destRootArchiveFolder = destRootFolder;
|
|
destRootFolder += fileName.first;
|
|
endPathWithSlash(destRootFolder);
|
|
|
|
string destFile = this->scenariosPath.second;
|
|
endPathWithSlash(destFile);
|
|
destFile += fileName.first;
|
|
string destFileSaveAs = destFile + this->fileArchiveExtension;
|
|
endPathWithSlash(destFile);
|
|
|
|
string remotePath = fileName.first + this->fileArchiveExtension;
|
|
if (fileName.second != "") {
|
|
remotePath = fileName.second;
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> result = getFileFromServer(ftp_cct_Scenario,
|
|
fileName, remotePath, destFileSaveAs, "", "");
|
|
|
|
// Extract the archive
|
|
if (result.first == ftp_crt_SUCCESS) {
|
|
string extractCmd = getFullFileArchiveExtractCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandParameters,
|
|
destRootArchiveFolder,
|
|
destRootArchiveFolder + fileName.first + this->fileArchiveExtension);
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->shellCommandCallbackUserData = fileName.first;
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
fileName.first,
|
|
ftp_cct_ExtractProgress,
|
|
make_pair(ftp_crt_SUCCESS, "extracting"), NULL);
|
|
}
|
|
safeMutex.ReleaseLock();
|
|
|
|
if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) {
|
|
result.first = ftp_crt_FAIL;
|
|
result.second = "failed to extract archive!";
|
|
}
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
void FTPClientThread::getFileFromServer(pair<string, string> fileName) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
|
|
bool findArchive = true;
|
|
string ext = extractExtension(fileName.first);
|
|
if (("." + ext) == this->fileArchiveExtension) {
|
|
findArchive = executeShellCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandSuccessResult);
|
|
}
|
|
if (findArchive == true) {
|
|
result = getFileInternalFromServer(fileName);
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(fileName.first, ftp_cct_File, result, NULL);
|
|
}
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getFileInternalFromServer(pair<string, string> fileName) {
|
|
string destFile = fileName.first;
|
|
string destFileSaveAs = fileName.first;
|
|
|
|
string remotePath = fileName.second;
|
|
|
|
pair<FTP_Client_ResultType, string> result = getFileFromServer(ftp_cct_File,
|
|
fileName, remotePath, destFileSaveAs, "", "");
|
|
|
|
//printf("Got file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first);
|
|
|
|
// Extract the archive
|
|
if (result.first == ftp_crt_SUCCESS) {
|
|
string ext = extractExtension(destFileSaveAs);
|
|
if (("." + ext) == fileArchiveExtension) {
|
|
string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs);
|
|
string extractCmd = getFullFileArchiveExtractCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandParameters,
|
|
destRootArchiveFolder,
|
|
destFileSaveAs);
|
|
|
|
if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult) == false) {
|
|
result.first = ftp_crt_FAIL;
|
|
result.second = "failed to extract archive!";
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void FTPClientThread::getTempFileFromServer(pair<string, string> fileName) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
|
|
bool findArchive = true;
|
|
string ext = extractExtension(fileName.first);
|
|
if (("." + ext) == this->fileArchiveExtension) {
|
|
findArchive = executeShellCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandSuccessResult);
|
|
}
|
|
if (findArchive == true) {
|
|
result = getTempFileInternalFromServer(fileName);
|
|
}
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
if (this->pCBObject != NULL) {
|
|
this->pCBObject->FTPClient_CallbackEvent(fileName.first, ftp_cct_TempFile, result, NULL);
|
|
}
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getTempFileInternalFromServer(pair<string, string> fileName) {
|
|
string destFile = fileName.first;
|
|
//string destFileSaveAs = fileName.first;
|
|
string destFileSaveAs = tempFilesPath;
|
|
|
|
endPathWithSlash(destFileSaveAs);
|
|
destFileSaveAs += fileName.first;
|
|
|
|
string remotePath = fileName.second;
|
|
|
|
//printf("First [%s] Second [%s]\n",fileName.first.c_str(),fileName.second.c_str());
|
|
pair<FTP_Client_ResultType, string> result;
|
|
if (StartsWith(remotePath, "http://")) {
|
|
result = getFileFromServer(ftp_cct_TempFile, fileName, remotePath, destFileSaveAs, "", "");
|
|
} else {
|
|
fileName.second = "";
|
|
result = getFileFromServer(ftp_cct_TempFile, fileName, remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD);
|
|
}
|
|
|
|
//printf("Got temp file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first);
|
|
|
|
// Extract the archive
|
|
if (result.first == ftp_crt_SUCCESS) {
|
|
string ext = extractExtension(destFileSaveAs);
|
|
if (("." + ext) == fileArchiveExtension) {
|
|
string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs);
|
|
string extractCmd = getFullFileArchiveExtractCommand(
|
|
this->fileArchiveExtractCommand,
|
|
this->fileArchiveExtractCommandParameters,
|
|
destRootArchiveFolder,
|
|
destFileSaveAs);
|
|
|
|
if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult) == false) {
|
|
result.first = ftp_crt_FAIL;
|
|
result.second = "failed to extract archive!";
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
pair<FTP_Client_ResultType, string> FTPClientThread::getFileFromServer(FTP_Client_CallbackType downloadType,
|
|
pair<string, string> fileNameTitle,
|
|
string remotePath, string destFileSaveAs,
|
|
string ftpUser, string ftpUserPassword, vector <string> *wantDirListOnly) {
|
|
pair<FTP_Client_ResultType, string> result = make_pair(ftp_crt_FAIL, "");
|
|
if (wantDirListOnly) {
|
|
(*wantDirListOnly).clear();
|
|
}
|
|
string destRootFolder = extractDirectoryPathFromFile(destFileSaveAs);
|
|
bool pathCreated = false;
|
|
if (isdir(destRootFolder.c_str()) == false) {
|
|
createDirectoryPaths(destRootFolder);
|
|
pathCreated = true;
|
|
}
|
|
|
|
bool wantDirList = (wantDirListOnly != NULL);
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n", destFileSaveAs.c_str(), wantDirList);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n", destFileSaveAs.c_str(), wantDirList);
|
|
|
|
struct FtpFile ftpfile = {
|
|
fileNameTitle.first.c_str(),
|
|
destFileSaveAs.c_str(), // name to store the file as if successful
|
|
NULL,
|
|
NULL,
|
|
this,
|
|
"",
|
|
false,
|
|
downloadType
|
|
};
|
|
|
|
CURL *curl = SystemFlags::initHTTP();
|
|
if (curl) {
|
|
ftpfile.stream = NULL;
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
|
char szBuf[8096] = "";
|
|
if (fileNameTitle.second != "") {
|
|
snprintf(szBuf, 8096, "%s", fileNameTitle.second.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
|
} else {
|
|
snprintf(szBuf, 8096, "ftp://%s:%s@%s:%d/%s", ftpUser.c_str(), ftpUserPassword.c_str(), serverUrl.c_str(), portNumber, remotePath.c_str());
|
|
}
|
|
|
|
//printf("===> Getting ftp file: %s\n",szBuf);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, szBuf);
|
|
curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L);
|
|
|
|
// turn on wildcard matching
|
|
//curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L);
|
|
|
|
// callback is called before download of concrete file started
|
|
//curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
|
|
// callback is called after data from the file have been transferred
|
|
//curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
|
|
|
|
//curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &ftpfile);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
|
|
|
// Define our callback to get called when there's data to be written
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
|
// Set a pointer to our struct to pass to the callback
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
|
|
|
if (wantDirListOnly) {
|
|
curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1);
|
|
}
|
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
|
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, file_progress);
|
|
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &ftpfile);
|
|
|
|
// Max 10 minutes to transfer
|
|
//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600);
|
|
// Max 60 minutes to transfer
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L);
|
|
curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L);
|
|
|
|
// Switch on full protocol/debug output
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
|
|
|
CURLcode res = curl_easy_perform(curl);
|
|
|
|
if (res != CURLE_OK) {
|
|
result.second = curl_easy_strerror(res);
|
|
// we failed
|
|
printf("curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res, curl_easy_strerror(res), destRootFolder.c_str(), szBuf, ftpfile.isValidXfer, pathCreated);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res, curl_easy_strerror(res), destRootFolder.c_str(), szBuf, ftpfile.isValidXfer, pathCreated);
|
|
|
|
if (res == CURLE_PARTIAL_FILE || ftpfile.isValidXfer == true) {
|
|
result.first = ftp_crt_PARTIALFAIL;
|
|
} else if (res == CURLE_COULDNT_CONNECT) {
|
|
result.first = ftp_crt_HOST_NOT_ACCEPTING;
|
|
}
|
|
|
|
|
|
if (destRootFolder != "") {
|
|
if (pathCreated == true) {
|
|
removeFolder(destRootFolder);
|
|
} else {
|
|
removeFile(destFileSaveAs);
|
|
}
|
|
}
|
|
} else {
|
|
result.first = ftp_crt_SUCCESS;
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d wantDirListOnly = %p\n", __FILE__, __FUNCTION__, __LINE__, result.first, wantDirListOnly);
|
|
|
|
if (wantDirListOnly) {
|
|
if (ftpfile.stream) {
|
|
fclose(ftpfile.stream);
|
|
ftpfile.stream = NULL;
|
|
}
|
|
|
|
#ifdef WIN32
|
|
FILE *fp = _wfopen(utf8_decode(destFileSaveAs).c_str(), L"rt");
|
|
#else
|
|
FILE *fp = fopen(destFileSaveAs.c_str(), "rt");
|
|
#endif
|
|
if (fp != NULL) {
|
|
char szBuf[4096] = "";
|
|
while (feof(fp) == false) {
|
|
if (fgets(szBuf, 4095, fp) != NULL) {
|
|
string item = szBuf;
|
|
replaceAll(item, "\n", "");
|
|
replaceAll(item, "\r", "");
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Got [%s]\n", item.c_str());
|
|
(*wantDirListOnly).push_back(item);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
}
|
|
}
|
|
|
|
SystemFlags::cleanupHTTP(&curl);
|
|
}
|
|
|
|
if (ftpfile.stream) {
|
|
fclose(ftpfile.stream);
|
|
ftpfile.stream = NULL;
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d\n", __FILE__, __FUNCTION__, __LINE__, result.first);
|
|
|
|
return result;
|
|
}
|
|
|
|
FTPClientCallbackInterface * FTPClientThread::getCallBackObject() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
return pCBObject;
|
|
}
|
|
|
|
void FTPClientThread::setCallBackObject(FTPClientCallbackInterface *value) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId);
|
|
this->getProgressMutex()->setOwnerId(mutexOwnerId);
|
|
pCBObject = value;
|
|
}
|
|
|
|
void FTPClientThread::ShellCommandOutput_CallbackEvent(string cmd, char *output, void *userdata) {
|
|
if (this->pCBObject != NULL) {
|
|
|
|
string &itemName = *static_cast<string *>(userdata);
|
|
this->pCBObject->FTPClient_CallbackEvent(
|
|
itemName,
|
|
ftp_cct_ExtractProgress,
|
|
make_pair(ftp_crt_SUCCESS, "extracting"),
|
|
output);
|
|
}
|
|
}
|
|
|
|
void * FTPClientThread::getShellCommandOutput_UserData(string cmd) {
|
|
return &shellCommandCallbackUserData;
|
|
}
|
|
|
|
void FTPClientThread::execute() {
|
|
{
|
|
RunningStatusSafeWrapper runningStatus(this);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__);
|
|
|
|
if (getQuitStatus() == true) {
|
|
return;
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread is running\n");
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "FTP Client thread is running\n");
|
|
|
|
try {
|
|
while (this->getQuitStatus() == false) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(&mutexMapFileList, mutexOwnerId);
|
|
mutexMapFileList.setOwnerId(mutexOwnerId);
|
|
if (mapFileList.size() > 0) {
|
|
pair<string, string> mapFilename = mapFileList[0];
|
|
mapFileList.erase(mapFileList.begin() + 0);
|
|
safeMutex.ReleaseLock();
|
|
|
|
getMapFromServer(mapFilename);
|
|
} else {
|
|
safeMutex.ReleaseLock();
|
|
}
|
|
|
|
if (this->getQuitStatus() == true) {
|
|
break;
|
|
}
|
|
|
|
static string mutexOwnerId2 = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex2(&mutexTilesetList, mutexOwnerId2);
|
|
mutexTilesetList.setOwnerId(mutexOwnerId2);
|
|
if (tilesetList.size() > 0) {
|
|
pair<string, string> tileset = tilesetList[0];
|
|
tilesetList.erase(tilesetList.begin() + 0);
|
|
safeMutex2.ReleaseLock();
|
|
|
|
getTilesetFromServer(tileset);
|
|
} else {
|
|
safeMutex2.ReleaseLock();
|
|
}
|
|
|
|
static string mutexOwnerId3 = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex3(&mutexTechtreeList, mutexOwnerId3);
|
|
mutexTechtreeList.setOwnerId(mutexOwnerId3);
|
|
if (techtreeList.size() > 0) {
|
|
pair<string, string> techtree = techtreeList[0];
|
|
techtreeList.erase(techtreeList.begin() + 0);
|
|
safeMutex3.ReleaseLock();
|
|
|
|
getTechtreeFromServer(techtree);
|
|
} else {
|
|
safeMutex3.ReleaseLock();
|
|
}
|
|
|
|
static string mutexOwnerId4 = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex4(&mutexScenarioList, mutexOwnerId4);
|
|
mutexScenarioList.setOwnerId(mutexOwnerId4);
|
|
if (scenarioList.size() > 0) {
|
|
pair<string, string> file = scenarioList[0];
|
|
scenarioList.erase(scenarioList.begin() + 0);
|
|
safeMutex4.ReleaseLock();
|
|
|
|
getScenarioFromServer(file);
|
|
} else {
|
|
safeMutex4.ReleaseLock();
|
|
}
|
|
|
|
static string mutexOwnerId5 = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex5(&mutexFileList, mutexOwnerId5);
|
|
mutexFileList.setOwnerId(mutexOwnerId5);
|
|
if (fileList.size() > 0) {
|
|
pair<string, string> file = fileList[0];
|
|
fileList.erase(fileList.begin() + 0);
|
|
safeMutex5.ReleaseLock();
|
|
|
|
getFileFromServer(file);
|
|
} else {
|
|
safeMutex5.ReleaseLock();
|
|
}
|
|
|
|
static string mutexOwnerId6 = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex6(&mutexTempFileList, mutexOwnerId6);
|
|
mutexTempFileList.setOwnerId(mutexOwnerId6);
|
|
if (tempFileList.size() > 0) {
|
|
pair<string, string> file = tempFileList[0];
|
|
tempFileList.erase(tempFileList.begin() + 0);
|
|
safeMutex6.ReleaseLock();
|
|
|
|
getTempFileFromServer(file);
|
|
} else {
|
|
safeMutex6.ReleaseLock();
|
|
}
|
|
|
|
if (this->getQuitStatus() == false) {
|
|
sleep(25);
|
|
}
|
|
}
|
|
|
|
if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client exiting!\n");
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client exiting!\n");
|
|
} catch (const exception &ex) {
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what());
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what());
|
|
} catch (...) {
|
|
SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__);
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] FTP Client thread is exiting\n", __FILE__, __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
// Delete ourself when the thread is done (no other actions can happen after this
|
|
// such as the mutex which modifies the running status of this method
|
|
deleteSelfIfRequired();
|
|
}
|
|
|
|
}
|
|
} //end namespace
|