- got my plumbers suit on and added the plumbing for FTP file xfers

This commit is contained in:
Mark Vejvoda
2010-12-29 01:10:53 +00:00
parent ba995d1131
commit 6e88e4be4c
32 changed files with 5333 additions and 1386 deletions

View File

@@ -0,0 +1,205 @@
// ==============================================================
// 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/types.h>
#include <curl/easy.h>
using namespace Shared::Util;
using namespace Shared::PlatformCommon;
namespace Shared { namespace PlatformCommon {
/*
* 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 *filename;
FILE *stream;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */
out->stream=fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
FTPClientThread::FTPClientThread(string serverUrl, std::pair<string,string> mapsPath, FTPClientCallbackInterface *pCBObject) : BaseThread() {
this->serverUrl = serverUrl;
this->mapsPath = mapsPath;
this->pCBObject = pCBObject;
}
void FTPClientThread::signalQuit() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client: signalQuit\n");
BaseThread::signalQuit();
}
bool FTPClientThread::shutdownAndWait() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client: shutdownAndWait\n");
signalQuit();
return BaseThread::shutdownAndWait();
}
void FTPClientThread::getMapFromServer(string mapFileName) {
CURLcode res;
FTP_Client_ResultType result = ftp_crt_FAIL;
string destFile = this->mapsPath.second + mapFileName;
struct FtpFile ftpfile = {
destFile.c_str(), /* name to store the file as if succesful */
NULL
};
//curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if(curl) {
/*
* You better replace the URL with one that works!
*/
char szBuf[1024]="";
sprintf(szBuf,"ftp://maps:mg_ftp_server@%s/maps/%s",serverUrl.c_str(),mapFileName.c_str());
curl_easy_setopt(curl, CURLOPT_URL,szBuf);
/* 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);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* always cleanup */
//curl_easy_cleanup(curl);
if(CURLE_OK != res) {
/* we failed */
fprintf(stderr, "curl told us %d\n", res);
sprintf(szBuf,"ftp://maps_custom:mg_ftp_server@%s/maps/%s",serverUrl.c_str(),mapFileName.c_str());
curl_easy_setopt(curl, CURLOPT_URL,szBuf);
/* 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);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* always cleanup */
//curl_easy_cleanup(curl);
if(CURLE_OK != res) {
/* we failed */
fprintf(stderr, "curl told us %d\n", res);
}
else {
result = ftp_crt_SUCCESS;
}
}
else {
result = ftp_crt_SUCCESS;
}
curl_easy_cleanup(curl);
}
if(ftpfile.stream) {
fclose(ftpfile.stream); /* close the local file */
}
//curl_global_cleanup();
if(this->pCBObject != NULL) {
this->pCBObject->FTPClient_CallbackEvent(mapFileName,result);
}
}
void FTPClientThread::addMapToRequests(string mapFilename) {
MutexSafeWrapper safeMutex(&mutexMapFileList);
mapFileList.push_back(mapFilename);
}
void FTPClientThread::execute() {
{
RunningStatusSafeWrapper runningStatus(this);
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");
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FTP Client thread is running\n");
try {
while(this->getQuitStatus() == false) {
MutexSafeWrapper safeMutex(&mutexMapFileList);
if(mapFileList.size() > 0) {
string mapFilename = mapFileList[0];
mapFileList.erase(mapFileList.begin() + 0);
safeMutex.ReleaseLock();
getMapFromServer(mapFilename);
}
else {
safeMutex.ReleaseLock();
}
sleep(25);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> 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());
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__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
}
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
//delete this;
}
}}//end namespace

View File

@@ -0,0 +1,102 @@
// ==============================================================
// 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 "miniftpserver.h"
#include "util.h"
#include "platform_common.h"
#include "ftpIfc.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
using namespace Shared::Util;
using namespace Shared::PlatformCommon;
namespace Shared { namespace PlatformCommon {
FTPServerThread::FTPServerThread(std::pair<string,string> mapsPath) : BaseThread() {
this->mapsPath = mapsPath;
}
void FTPServerThread::signalQuit() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server: signalQuit\n");
BaseThread::signalQuit();
}
bool FTPServerThread::shutdownAndWait() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server: shutdownAndWait\n");
signalQuit();
return BaseThread::shutdownAndWait();
}
void FTPServerThread::execute() {
{
RunningStatusSafeWrapper runningStatus(this);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(getQuitStatus() == true) {
return;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread is running\n");
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FTP Server thread is running\n");
try {
//ftpCreateAccount("anonymous", "", mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
if(mapsPath.first != "") {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapsPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,mapsPath.first.c_str());
ftpCreateAccount("maps", "mg_ftp_server", mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
}
if(mapsPath.second != "") {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapsPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,mapsPath.second.c_str());
ftpCreateAccount("maps_custom", "mg_ftp_server", mapsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
}
/*
ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
ftpCreateAccount("nothing", "", "./", 0);
ftpCreateAccount("reader", "", "./", FTP_ACC_RD);
ftpCreateAccount("writer", "", "./", FTP_ACC_WR);
ftpCreateAccount("lister", "", "./", FTP_ACC_LS);
ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR);
*/
ftpStart();
while(this->getQuitStatus() == false) {
ftpExecute();
sleep(25);
}
ftpShutdown();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server exiting!\n");
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
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__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] FTP Server 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
//delete this;
}
}}//end namespace