From 0379b7284d0ee46d6e1312b4282b4b95f8671b82 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Sun, 20 Mar 2011 00:11:00 +0000 Subject: [PATCH] - removed requirement to have a newer libcurl, now most platform, should be able to build mg more easily (only require 7.16.4 or newer instead of 7.21.0) --- source/glest_game/graphics/renderer.cpp | 16 + .../menu/menu_state_connected_game.cpp | 13 +- .../menu/menu_state_custom_game.cpp | 8 +- source/glest_game/world/world.cpp | 2 +- source/shared_lib/CMakeLists.txt | 6 +- .../include/platform/posix/miniftpclient.h | 4 + .../sources/platform/posix/miniftpclient.cpp | 319 +++++++++++++++++- 7 files changed, 341 insertions(+), 27 deletions(-) diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index a2ba7fff..5ddce848 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -4840,6 +4840,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, texture->init(textureFilter,maxAnisotropy); texture->setup_FBO_RBO(); + assertGl(); + if(texture->checkFrameBufferStatus() == false) { //printf("******************** WARNING CANNOT Attach to FBO!\n"); texture->end(); @@ -4885,6 +4887,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, glPushMatrix(); glLoadIdentity(); + assertGl(); + GLint viewport[4]; // Where The original Viewport Values Will Be Stored if(supportFBOs == true && renderToTexture != NULL) { @@ -4905,6 +4909,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, glTranslatef(static_cast(screenPosX),static_cast(screenPosY)-clientH,0.0f); } + assertGl(); + glPushAttrib(GL_CURRENT_BIT); glLineWidth(1); glColor3f(0, 0, 0); @@ -5054,6 +5060,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, //start locations glLineWidth(3); + assertGl(); + if(supportFBOs == true && renderToTexture != NULL) { glLineWidth(14); playerCrossSize = 24; @@ -5068,6 +5076,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, } } + assertGl(); + for (int i = 0; i < map->getMaxFactions(); i++) { switch (i) { case 0: @@ -5103,11 +5113,15 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, glEnd(); } + assertGl(); + glPopMatrix(); glPopAttrib(); glMatrixMode(GL_PROJECTION); glPopMatrix(); + assertGl(); + if(supportFBOs == true && renderToTexture != NULL) { Texture2DGl *texture = static_cast(*renderToTexture); if(texture != NULL) { @@ -5115,6 +5129,8 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, } glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + assertGl(); } assertGl(); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index c60807e4..15ce3383 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -991,7 +991,7 @@ void MenuStateConnectedGame::update() { int32 tilesetCRC = lastCheckedCRCTilesetValue; if(lastCheckedCRCTilesetName != gameSettings->getTileset() && gameSettings->getTileset() != "") { - console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); + //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); // Test data synch //tilesetCRC++; @@ -1002,7 +1002,7 @@ void MenuStateConnectedGame::update() { int32 techCRC = lastCheckedCRCTechtreeValue; if(lastCheckedCRCTechtreeName != gameSettings->getTech() && gameSettings->getTech() != "") { - console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); + //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); // Test data synch //techCRC++; @@ -1021,7 +1021,7 @@ void MenuStateConnectedGame::update() { } factionCRCList.push_back(make_pair(factionName,factionCRC)); } - console.addLine("Found factions: " + intToStr(factionCRCList.size())); + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); } int32 mapCRC = lastCheckedCRCMapValue; @@ -1029,7 +1029,7 @@ void MenuStateConnectedGame::update() { gameSettings->getMap() != "") { Checksum checksum; string file = Map::getMapPath(gameSettings->getMap(),"",false); - console.addLine("Checking map CRC [" + file + "]"); + //console.addLine("Checking map CRC [" + file + "]"); checksum.addFile(file); mapCRC = checksum.getSum(); // Test data synch @@ -2095,9 +2095,10 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client fileFTPProgressList[itemName] = pair(fileProgress,stats->currentFilename); safeMutexFTPProgress.ReleaseLock(); - if((lastProgress.first / 25) < (fileProgress / 25)) { + if(itemName != "" && (lastProgress.first / 25) < (fileProgress / 25)) { char szMsg[1024]=""; - sprintf(szMsg,"Player: %s download progress for %s is %d %%",getHumanPlayerName().c_str(),itemName.c_str(),fileProgress); + sprintf(szMsg,"Player: %s download progress for [%s] is %d %%",getHumanPlayerName().c_str(),itemName.c_str(),fileProgress); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] szMsg [%s] lastProgress.first = %d, fileProgress = %d\n",__FILE__,__FUNCTION__,__LINE__,szMsg,lastProgress.first,fileProgress); NetworkManager &networkManager= NetworkManager::getInstance(); ClientInterface* clientInterface= networkManager.getClientInterface(); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index db22ffa4..3c7f02b3 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -2226,7 +2226,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { if( gameSettings->getTileset() != "") { if(lastCheckedCRCTilesetName != gameSettings->getTileset()) { - console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); + //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); lastCheckedCRCTilesetValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); lastCheckedCRCTilesetName = gameSettings->getTileset(); } @@ -2236,7 +2236,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { if(config.getBool("DisableServerLobbyTechtreeCRCCheck","false") == false) { if(gameSettings->getTech() != "") { if(lastCheckedCRCTechtreeName != gameSettings->getTech()) { - console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); + //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); lastCheckedCRCTechtreeValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/*", ".xml", NULL); reloadFactions(true); @@ -2250,7 +2250,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { } factionCRCList.push_back(make_pair(factionName,factionCRC)); } - console.addLine("Found factions: " + intToStr(factionCRCList.size())); + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); lastCheckedCRCTechtreeName = gameSettings->getTech(); } @@ -2263,7 +2263,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { if(lastCheckedCRCMapName != gameSettings->getMap()) { Checksum checksum; string file = Map::getMapPath(gameSettings->getMap(),"",false); - console.addLine("Checking map CRC [" + file + "]"); + //console.addLine("Checking map CRC [" + file + "]"); checksum.addFile(file); lastCheckedCRCMapValue = checksum.getSum(); lastCheckedCRCMapName = gameSettings->getMap(); diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index dc2c7f25..184cbd03 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -985,7 +985,7 @@ void World::togglePauseGame(bool pauseStatus) { } void World::addConsoleText(const string &text) { - game->getConsole()->addLine(text); + game->getConsole()->addStdMessage(text); } void World::giveUpgradeCommand(int unitId, const string &upgradeName) { diff --git a/source/shared_lib/CMakeLists.txt b/source/shared_lib/CMakeLists.txt index 4e4731c0..02eb9996 100644 --- a/source/shared_lib/CMakeLists.txt +++ b/source/shared_lib/CMakeLists.txt @@ -64,9 +64,11 @@ include_regular_expression("^.*$") # Setup package meta-data set(CURL_VERSION ${CURL_MAJOR_VERSION}.${CURL_MINOR_VERSION}.${CURL_PATCH_VERSION}) message(STATUS "curl version=[${CURL_VERSION}]") -IF( ${CURL_VERSION} VERSION_LESS 7.21.0) +#IF( ${CURL_VERSION} VERSION_LESS 7.21.0) +IF( ${CURL_VERSION} VERSION_LESS 7.16.4) message(STATUS "(please visit http://curl.haxx.se/libcurl/ to find a newer version)") - message(FATAL_ERROR " CURL version = [${CURL_VERSION}] we require AT LEAST [7.21.0]") + #message(FATAL_ERROR " CURL version = [${CURL_VERSION}] we require AT LEAST [7.21.0]") + message(FATAL_ERROR " CURL version = [${CURL_VERSION}] we require AT LEAST [7.16.4]") ENDIF() diff --git a/source/shared_lib/include/platform/posix/miniftpclient.h b/source/shared_lib/include/platform/posix/miniftpclient.h index 88487e06..c4d8d77c 100644 --- a/source/shared_lib/include/platform/posix/miniftpclient.h +++ b/source/shared_lib/include/platform/posix/miniftpclient.h @@ -88,6 +88,10 @@ protected: string fileArchiveExtractCommand; string fileArchiveExtractCommandParameters; + FTP_Client_ResultType getFileFromServer(string fileNameTitle, + string remotePath, string destFileSaveAs, string ftpUser, + string ftpUserPassword, vector *wantDirListOnly=NULL); + public: FTPClientThread(int portNumber,string serverUrl, diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index c1a3c5e4..941a68b6 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -62,6 +62,8 @@ static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { fullFilePath += out->filename; } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread writing file [%s]\n",fullFilePath.c_str()); + // Abort file xfer and delete partial file if(out && out->ftpServer && out->ftpServer->getQuitStatus() == true) { if(out->stream) { @@ -377,8 +379,9 @@ void FTPClientThread::getTilesetFromServer(string tileSetName) { FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive) { - FTP_Client_ResultType result = ftp_crt_FAIL; +/* + FTP_Client_ResultType result = ftp_crt_FAIL; string destFile = this->tilesetsPath.second; // Root folder for the tileset @@ -409,7 +412,7 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, struct FtpFile ftpfile = { tileSetName.c_str(), - destFile.c_str(), // name to store the file as if succesful + destFile.c_str(), // name to store the file as if successful destFile.c_str(), NULL, this, @@ -421,8 +424,6 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, ftpfile.filepath = destRootArchiveFolder.c_str(); } - //curl_global_init(CURL_GLOBAL_DEFAULT); - CURL *curl = SystemFlags::initHTTP(); if(curl) { ftpfile.stream = NULL; @@ -537,6 +538,121 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName, } } + return result; +*/ + + string destFileSaveAsNewFile = ""; + string destFileSaveAs = ""; + string remotePath = ""; + bool getFolderContents = false; + vector wantDirListOnly; + if(tileSetNameSubfolder == "") { + if(findArchive == true) { + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName + this->fileArchiveExtension; + + remotePath = tileSetName + this->fileArchiveExtension; + //sprintf(szBuf,"ftp://%s:%s@%s:%d/%s%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber, + // tileSetName.c_str(),this->fileArchiveExtension.c_str()); + } + else { + getFolderContents = true; + remotePath = tileSetName + "/"; + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName; + destFileSaveAsNewFile = destFileSaveAs; + endPathWithSlash(destFileSaveAsNewFile); + destFileSaveAs += ".tmp"; + + //sprintf(szBuf,"ftp://%s:%s@%s:%d/%s/*",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,tileSetName.c_str()); + } + } + else { + getFolderContents = true; + remotePath = tileSetName + "/" + tileSetNameSubfolder + "/"; + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName; + endPathWithSlash(destFileSaveAs); + + destFileSaveAs += tileSetNameSubfolder; + destFileSaveAsNewFile = destFileSaveAs; + endPathWithSlash(destFileSaveAsNewFile); + destFileSaveAs += ".tmp"; + + //sprintf(szBuf,"ftp://%s:%s@%s:%d/%s/%s/*",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber, + // tileSetName.c_str(),tileSetNameSubfolder.c_str()); + } + + vector *pWantDirListOnly = NULL; + if(getFolderContents == true) { + pWantDirListOnly = &wantDirListOnly; + } + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d\n",tileSetName.c_str(),remotePath.c_str(),destFileSaveAs.c_str(),getFolderContents); + + FTP_Client_ResultType result = getFileFromServer(tileSetName, + remotePath, destFileSaveAs,ftpUser, ftpUserPassword, pWantDirListOnly); + + // Extract the archive + if(result == ftp_crt_SUCCESS) { + if(findArchive == true) { + string destRootArchiveFolder = this->tilesetsPath.second; + endPathWithSlash(destRootArchiveFolder); + + string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, destRootArchiveFolder, + destRootArchiveFolder + tileSetName + this->fileArchiveExtension); + + if(executeShellCommand(extractCmd) == false) { + result = ftp_crt_FAIL; + } + + 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 [%d]\n",fileFromList.c_str(),i); + + if( fileFromList != "models" && fileFromList != "textures" && + fileFromList != "sounds") { + result = getFileFromServer(tileSetName, + remotePath + fileFromList, + destFileSaveAsNewFile + fileFromList, + ftpUser, ftpUserPassword); + if(result != ftp_crt_SUCCESS) { + break; + } + } + else { + result = getTilesetFromServer(tileSetName, + fileFromList, ftpUser, ftpUserPassword, + findArchive); + if(result != ftp_crt_SUCCESS) { + break; + } + } + } + } + } + } + + if(result != ftp_crt_SUCCESS && findArchive == false) { + string destRootFolder = this->tilesetsPath.second; + endPathWithSlash(destRootFolder); + destRootFolder += tileSetName; + endPathWithSlash(destRootFolder); + + removeFolder(destRootFolder); + } + return result; } @@ -558,6 +674,8 @@ void FTPClientThread::getTechtreeFromServer(string techtreeName) { FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName, string ftpUser, string ftpUserPassword) { + +/* FTP_Client_ResultType result = ftp_crt_FAIL; string destFile = this->techtreesPath.second; @@ -575,23 +693,36 @@ FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName endPathWithSlash(destFile); destFile += techtreeName; + string destFileSaveAs = destFile + this->fileArchiveExtension; endPathWithSlash(destFile); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s]\n",destFileSaveAs.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s]\n",destFileSaveAs.c_str()); + + +// struct FtpFile ftpfile = { +// techtreeName.c_str(), +// destFile.c_str(), // name to store the file as if succesful +// destFile.c_str(), +// NULL, +// this, +// "", +// false +// }; +// +// ftpfile.filepath = destRootArchiveFolder.c_str(); + struct FtpFile ftpfile = { techtreeName.c_str(), - destFile.c_str(), // name to store the file as if succesful - destFile.c_str(), + destFileSaveAs.c_str(), // name to store the file as if succesful + NULL, NULL, this, "", false }; - ftpfile.filepath = destRootArchiveFolder.c_str(); - CURL *curl = SystemFlags::initHTTP(); if(curl) { ftpfile.stream = NULL; @@ -603,14 +734,14 @@ FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); // turn on wildcard matching - curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + //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); + //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_END_FUNCTION, file_is_downloaded); - curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &ftpfile); + //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 @@ -667,9 +798,169 @@ FTP_Client_ResultType FTPClientThread::getTechtreeFromServer(string techtreeName } return result; +*/ + + + // Root folder for the techtree + string destRootFolder = this->techtreesPath.second; + endPathWithSlash(destRootFolder); + string destRootArchiveFolder = destRootFolder; + destRootFolder += techtreeName; + endPathWithSlash(destRootFolder); + + string destFile = this->techtreesPath.second; + endPathWithSlash(destFile); + destFile += techtreeName; + string destFileSaveAs = destFile + this->fileArchiveExtension; + endPathWithSlash(destFile); + + string remotePath = techtreeName + this->fileArchiveExtension; + FTP_Client_ResultType result = getFileFromServer(techtreeName, + remotePath, destFileSaveAs, ftpUser, ftpUserPassword); + + // Extract the archive + if(result == ftp_crt_SUCCESS) { + string extractCmd = getFullFileArchiveExtractCommand(this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, destRootArchiveFolder, + destRootArchiveFolder + techtreeName + this->fileArchiveExtension); + + if(executeShellCommand(extractCmd) == false) { + result = ftp_crt_FAIL; + } + } + + return result; + } +FTP_Client_ResultType FTPClientThread::getFileFromServer(string fileNameTitle, + string remotePath, string destFileSaveAs, + string ftpUser, string ftpUserPassword, vector *wantDirListOnly) { + FTP_Client_ResultType result = 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); + 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.c_str(), + destFileSaveAs.c_str(), // name to store the file as if successful + NULL, + NULL, + this, + "", + false + }; + + CURL *curl = SystemFlags::initHTTP(); + if(curl) { + ftpfile.stream = NULL; + + char szBuf[1024]=""; + sprintf(szBuf,"ftp://%s:%s@%s:%d/%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,remotePath.c_str()); + + 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); + + // 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) { + // 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); + 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 = ftp_crt_PARTIALFAIL; + } + + if(destRootFolder != "") { + if(pathCreated == true) { + removeFolder(destRootFolder); + } + else { + removeFile(destFileSaveAs); + } + } + } + else { + result = ftp_crt_SUCCESS; + + if(wantDirListOnly) { + if(ftpfile.stream) { + fclose(ftpfile.stream); + ftpfile.stream = NULL; + } + + FILE *fp = fopen(destFileSaveAs.c_str(), "rt"); + 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; + } + + return result; +} + + + FTPClientCallbackInterface * FTPClientThread::getCallBackObject() { MutexSafeWrapper safeMutex(this->getProgressMutex(),string(__FILE__) + "_" + intToStr(__LINE__)); return pCBObject;