00001
00002 #ifndef MDistributedFileSystemH
00003 #define MDistributedFileSystemH
00004
00005 #include <string>
00006 #include <map>
00007 #include <vector>
00008 #include <list>
00009 #include <tinyxml/tinyxml.h>
00010 #include "MThread.h"
00011 #include "MUtils.h"
00012 #include "FSUtils.h"
00013 #include "MPNLBase.h"
00014
00015 namespace mdfs {
00016
00017
00018 class MDFSPeerBase;
00019 class MDFS;
00020 class MDFSDB;
00021 class MServer;
00022 class MShare;
00023 class MFile;
00024 class MDownload;
00025 class MDFSUpdate;
00026 struct MUser;
00027
00028 typedef std::vector<MServer*> MServerList;
00029 typedef std::vector<MShare*> MShareList;
00030 typedef std::vector<std::string> MStringList;
00031 typedef std::list<MDFSUpdate*> MUpdateList;
00032 typedef std::list<MDownload> MDownloadList;
00033
00034
00035 struct MUser {
00036 MUser() {ID = Group = -1;}
00037 long ID;
00038 long Group;
00039 std::string Name;
00040 };
00041
00042
00043 struct MConnection {
00044 MConnection() : Port(0), IsServerLocal(false) {}
00045 std::string Host;
00046 int Port;
00047 std::string LocalIP;
00048 bool IsServerLocal;
00049 MUser User;
00050 TIME ConDate;
00051 struct MInfos {
00052 std::string Name;
00053 } Infos;
00054 };
00055
00056
00057 enum MUserType {utOWNER=0,utGROUP=1,utOTHER=2};
00058
00059
00060 enum MFileType {ftUNK=0, ftDIR=1, ftFILE=2};
00061
00062
00063 enum MMode {mREAD=0,mWRITE=1};
00064
00065
00066 struct MStats {
00067 MPNL::MTCPServer::MStats Server;
00068 };
00069
00070 struct MOptions {
00071 unsigned long ConnectInterval;
00072 unsigned long QueryInterval;
00073 unsigned long DownloadQueryInterval;
00074 };
00075
00076
00077 class MPermission {
00078 public:
00079 MPermission() {Set("------");}
00080 MPermission(const std::string& perm) {Set(perm);}
00081 bool HasAccess(MMode m, MUserType u) const {return Perm[u*2+m] != '-';}
00082 void Set(const std::string& perm) {Perm = perm;}
00083 private:
00084 std::string Perm;
00085 };
00086
00087
00088
00089
00090
00091
00092 struct MShare {
00093 MShare() {}
00095 std::string URL;
00097 std::string LocalPath;
00098
00099 MUser Owner;
00100 MPermission Perm;
00101 };
00102
00103
00106 class MDFSPeerBase {
00107
00108 public:
00109 MConnection Connection;
00110 std::string Msg;
00111 void* Data;
00112
00113 MDFSPeerBase() {Data = NULL;}
00114 virtual ~MDFSPeerBase() {}
00115 virtual int Send(const std::string& msg)=0;
00116
00117 };
00118
00119
00123 class MPeerClient : public MDFSPeerBase {
00124 public:
00125 MPeerClient() : MDFSPeerBase() {}
00126 ~MPeerClient() {}
00127
00128 int Send(const std::string& msg) {
00129 return static_cast<MPNL::MSocket*>(Data)->Send(msg);
00130 }
00131 };
00132
00133
00134
00135 class MDFSTCPClient : public MPNL::MTCPClient {
00136
00137 public:
00138 MDFSTCPClient(MDFS* dfs) : MPNL::MTCPClient(), DFS(dfs) {}
00139 ~MDFSTCPClient(){}
00140
00141 bool OnConnection(MPNL::MSocket* s);
00142 void OnDisconnection(MPNL::MSocket* s);
00143 private:
00144 MDFS* DFS;
00145 };
00146
00147
00148
00149 class MDFSTCPServer : public MPNL::MTCPServer {
00150
00151 public:
00152 MDFSTCPServer(MDFS* dfs) : MPNL::MTCPServer(), DFS(dfs) {}
00153 ~MDFSTCPServer(){}
00154
00155 bool OnConnection(MPNL::MSocket* s);
00156 void OnDisconnection(MPNL::MSocket* s);
00157 private:
00158 MDFS* DFS;
00159 };
00160
00161
00162
00167 class MServer : public MDFSPeerBase {
00168 friend class MDFS;
00169 public:
00170 TIME LastConnection;
00171
00172 MServer(const std::string& host, int port, MDFS* dfs);
00173 ~MServer();
00174 int Send(const std::string& msg);
00175 bool Connect(int timeout=1000);
00176
00177 protected:
00178 MDFS* DFS;
00179 MDFSTCPClient* TCPClient;
00180 TIME LastFailedConnection;
00181 };
00182
00183
00184
00200 class MFile {
00201
00202 public:
00203 std::string MD5;
00204 std::string LocalPath;
00205 MUtils::MDate Date;
00206 MUtils::MDate LastUpdate;
00207 unsigned long Size;
00208
00209
00210
00211 MFile() : Size(0), Type(ftUNK) { }
00212 MFile(const std::string& url)
00213 : Size(0), Type(ftUNK) {SetURL(url);}
00214 ~MFile() {}
00215
00216 void SetURL (const std::string& url);
00217 void SetType(const MFileType& t);
00218 std::string GetURL() const {return URL;}
00219 MFileType GetType() const {return Type;}
00220 void Reset() {Type=ftUNK;URL="";}
00221 std::string ExtractFileName() const ;
00222 std::string ExtractFilePath() const;
00223
00224 private:
00225 MFileType Type;
00226 std::string URL;
00227 void VerifyType();
00228
00229 };
00230
00231
00232 class MDFSTransfer {
00233
00234 public:
00235
00236 enum MType {ttDOWNLOAD, ttUPLOAD} Type;
00237 MFile File;
00238 std::string Msg;
00239 int ID;
00240
00241
00242 MDFSTransfer() {}
00243
00244 };
00245
00246
00247 class MDFSUpdate {
00248
00249 public:
00250
00251 MDFSUpdate() : Stamp(0) {}
00252
00253 enum MType {utFILE, utCONNECT, utTRANSFER} Type;
00254 enum MAction {uaADD, uaUPDATE, uaREMOVE} Action;
00255 enum MResult {urOK, urFAILED} Result;
00256
00257 MFile File;
00258 MConnection Connection;
00259 MDFSTransfer Transfer;
00260
00261 unsigned char GetStamp() {
00262 boost::mutex::scoped_lock lock(Mutex);
00263 return Stamp;
00264 }
00265 void SetStamp(unsigned char s) {
00266 boost::mutex::scoped_lock lock(Mutex);
00267 Stamp |= s;
00268 }
00269
00270 private:
00271 boost::mutex Mutex;
00272 unsigned char Stamp;
00273
00274 };
00275
00276
00279 typedef std::vector<MFile> MFileList;
00280
00281
00284 class MQuery {
00285 public:
00286
00287 enum MQType {qtUPDATE, qtDOWNLOAD}
00288 QueryType;
00289 int FileType;
00290 int Depth;
00291 MURL URL;
00292 int URLParsingResult;
00293
00294
00295 MQuery(const std::string& url, int t, int r) : QueryType(qtUPDATE), FileType(t), Depth(r) {
00296 URLParsingResult = ParseURL(url,URL);
00297 }
00298
00299 bool URLIsValid() const {return URLParsingResult==0;}
00300
00301 private:
00302
00303 };
00304
00305
00306
00307 class MDownload {
00308 public:
00309 std::string URL;
00310 unsigned long LastQuery;
00311
00312 MDownload(const std::string& url) : URL(url), Active(false) {RESETTIME(LastQuery);}
00313 MDownload(const MDownload& d) {
00314
00315
00316
00317
00318 Active = d.Active;
00319 URL = d.URL;
00320 LastQuery = d.LastQuery;
00321 }
00322 ~MDownload() {}
00323
00324 bool IsActive() {
00325 boost::mutex::scoped_lock lock(Mutex);
00326 return Active;
00327 }
00328 void SetActive(bool b) {
00329 boost::mutex::scoped_lock lock(Mutex);
00330 Active = b;
00331 }
00332
00333 private:
00334 boost::mutex Mutex;
00335 bool Active;
00336
00337 };
00338
00339
00340
00345 class MUpdateScanner : public MThread {
00346 public:
00347 MUpdateScanner(MDFS* dfs) {DFS=dfs;}
00348 virtual ~MUpdateScanner() {};
00349 protected:
00350 MDFS* DFS;
00351 };
00352
00353
00354
00365 class MDFS : public MThread {
00366 public:
00367
00368 MDFSDB* DB;
00369 MShareList Shares;
00370 MOptions Options;
00371 MPNL::MTransferManager* TransferManager;
00372 unsigned char ClearStamp;
00373
00374 MDFS();
00375 virtual ~MDFS();
00376
00378 void Init(const std::string& initfilepath);
00379
00381 MServer* AddServer(const std::string& host, int port=5050);
00382
00384 int SendMsg(const std::string& host, const std::string& msg);
00385
00387 void BroadcastMsg(const std::string& msg);
00388
00390 void SendConnections(const std::string& ip);
00391
00393 bool IsConnected(const std::string& ip);
00394
00395 void GetStats(MStats& s);
00396
00398 MUpdateList* LockUpdates() {
00399 UpdateLock->lock();
00400 return &Updates;
00401 }
00402 void UnlockUpdates() {
00403 UpdateLock->unlock();
00404 }
00405
00407 void operator()();
00408
00409 void Download(const std::string& url);
00410
00411 void AddUpdate(MDFSUpdate* u);
00412 void AddConnection(MConnection& c);
00413 void RemoveConnection(const std::string& ip);
00414 void SaveConnections();
00415
00416 protected:
00417
00418 std::string Base;
00419 std::string DownloadPath;
00420 MStringList Errors;
00421 MServerList Servers;
00422 MDFSTCPServer* TCPServer;
00423 std::string Name;
00424 MStringList ServerHosts;
00425 MStats Stats;
00426 MUpdateList Updates;
00427 MDownloadList Downloads;
00428 MUpdateScanner* UpdateScanner;
00429
00430 typedef std::vector<MConnection> MConnectionList;
00431 MConnectionList Connections;
00432
00433 void Listen(TiXmlElement* cur);
00434 void NewServer(TiXmlElement* cur);
00436 void ParseNetMsg(MDFSPeerBase* c, std::string& rv);
00437 void Init(TiXmlElement* cur);
00438 void NewShare(TiXmlElement* cur);
00439 void ParseNetMsg(MDFSPeerBase* c, TiXmlElement* cur, std::string& rv);
00440 void ParseQuery(MDFSPeerBase* c, TiXmlElement* cur, std::string& rv);
00441 void ParseDLQuery(MDFSPeerBase* c, TiXmlElement* cur, std::string& rv);
00442 void ParseDLResponse(MDFSPeerBase* c, TiXmlElement* cur, std::string& rv);
00443 void CancelDL(MDFSPeerBase* c, TiXmlElement* cur, std::string& rv);
00444 void ParseUpdate(TiXmlElement* cur, std::string& rv);
00445 void ParseFile(MFileType ft, TiXmlElement* cur, std::string& rv);
00446 void SendInfos(const std::string& ip, const std::string& localip);
00447 void NewInfo(MDFSPeerBase* c, TiXmlElement* cur);
00448
00456 virtual void BuildFileQueryResponse(MDFSPeerBase* c, const MQuery& q, std::string& rv)=0;
00457
00458 virtual bool Login(const std::string& login, const std::string& pwd, MUser& rv)=0;
00459 void AddErrors(std::string& rv);
00460 void DeleteDownload(const std::string& url);
00461
00462 private:
00463 boost::mutex UpdateMutex;
00464 boost::mutex::scoped_lock* UpdateLock;
00465 boost::mutex ConnectionMutex;
00466 boost::mutex ServerMutex;
00467 boost::mutex StatMutex;
00468 boost::mutex DownloadMutex;
00469
00470 TIME LastQuery;
00471
00472 };
00473
00474
00475
00476 }
00477
00478 #endif
00479