MegaGlest/source/shared_lib/sources/platform/posix/miniftpclient.cpp
SoftCoder efa7cb0346 - bugfix for shared team resources
- added some new internal feature code to test auto updates for a future release
2014-12-30 12:16:35 -08:00

1245 lines
50 KiB
C++

// ==============================================================
// This file is part of MegaGlest Shared Library (www.glest.org)
//
// Copyright (C) 2009-2010 Titus Tscharntke (info@titusgames.de) and
// Mark Vejvoda (mark_vejvoda@hotmail.com)
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#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 = " MG_SIZE_T_SPECIFIER ", result = " MG_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 = " MG_SIZE_T_SPECIFIER ", result = " MG_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 = " MG_SIZE_T_SPECIFIER ", result = " MG_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;
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 += + ".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;
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