2016-09-12 18:01:26 -04:00
|
|
|
/*
|
|
|
|
* RetroShare C++ Directory Storage system.
|
|
|
|
*
|
|
|
|
* file_sharing/directory_storage.h
|
|
|
|
*
|
|
|
|
* Copyright 2016 by Mr.Alice
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License Version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare.project@gmail.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-07-24 23:48:22 -04:00
|
|
|
#pragma once
|
|
|
|
|
2016-07-18 21:52:44 -04:00
|
|
|
#include <string>
|
2016-07-20 16:10:51 -04:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <list>
|
|
|
|
|
|
|
|
#include "retroshare/rsids.h"
|
|
|
|
#include "retroshare/rsfiles.h"
|
2016-07-18 21:52:44 -04:00
|
|
|
|
2016-07-31 09:59:58 -04:00
|
|
|
#define NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; }
|
|
|
|
|
2016-08-26 10:29:02 -04:00
|
|
|
class RsTlvBinaryData ;
|
2016-07-21 00:16:12 -04:00
|
|
|
class InternalFileHierarchyStorage ;
|
2016-08-26 10:29:02 -04:00
|
|
|
class RsTlvBinaryData ;
|
2016-07-21 00:16:12 -04:00
|
|
|
|
2016-07-18 21:52:44 -04:00
|
|
|
class DirectoryStorage
|
|
|
|
{
|
|
|
|
public:
|
2016-09-03 07:29:23 -04:00
|
|
|
DirectoryStorage(const RsPeerId& pid) ;
|
2016-07-20 16:10:51 -04:00
|
|
|
virtual ~DirectoryStorage() {}
|
|
|
|
|
2016-09-03 07:29:23 -04:00
|
|
|
typedef uint32_t EntryIndex ;
|
2016-07-24 23:48:22 -04:00
|
|
|
static const EntryIndex NO_INDEX = 0xffffffff;
|
2016-07-18 21:52:44 -04:00
|
|
|
|
|
|
|
void save() const ;
|
|
|
|
|
2016-09-12 17:37:19 -04:00
|
|
|
virtual int searchTerms(const std::list<std::string>& terms, std::list<EntryIndex> &results) const ;
|
|
|
|
virtual int searchBoolExp(Expression * exp, std::list<EntryIndex> &results) const ;
|
2016-08-20 10:23:11 -04:00
|
|
|
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
|
2016-07-18 21:52:44 -04:00
|
|
|
|
2016-08-26 10:29:02 -04:00
|
|
|
bool getDirUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS) ;
|
|
|
|
bool setDirUpdateTS(EntryIndex index,time_t recurs_max_modf_TS,time_t local_update_TS) ;
|
2016-08-23 15:23:58 -04:00
|
|
|
|
2016-08-11 08:07:45 -04:00
|
|
|
uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff.
|
2016-08-16 17:44:48 -04:00
|
|
|
virtual bool extractData(const EntryIndex& indx,DirDetails& d);
|
2016-07-18 21:52:44 -04:00
|
|
|
|
|
|
|
// This class allows to abstractly browse the stored directory hierarchy in a depth-first manner.
|
|
|
|
// It gives access to sub-files and sub-directories below.
|
|
|
|
//
|
|
|
|
class DirIterator
|
|
|
|
{
|
|
|
|
public:
|
2016-07-21 00:16:12 -04:00
|
|
|
DirIterator(const DirIterator& d) ;
|
2016-07-24 23:48:22 -04:00
|
|
|
DirIterator(DirectoryStorage *d,EntryIndex i) ;
|
2016-07-18 21:52:44 -04:00
|
|
|
|
|
|
|
DirIterator& operator++() ;
|
2016-07-24 23:48:22 -04:00
|
|
|
EntryIndex operator*() const ;
|
2016-07-18 21:52:44 -04:00
|
|
|
|
2016-07-23 22:14:43 -04:00
|
|
|
operator bool() const ; // used in for loops. Returns true when the iterator is valid.
|
|
|
|
|
|
|
|
// info about the directory that is pointed by the iterator
|
|
|
|
|
2016-08-11 08:07:45 -04:00
|
|
|
std::string name() const ;
|
2016-08-20 10:23:11 -04:00
|
|
|
time_t last_modif_time() const ; // last time a file in this directory or in the directories below has been modified.
|
|
|
|
time_t last_update_time() const ; // last time this directory was updated
|
2016-07-24 23:48:22 -04:00
|
|
|
private:
|
|
|
|
EntryIndex mParentIndex ; // index of the parent dir.
|
|
|
|
uint32_t mDirTabIndex ; // index in the vector of subdirs.
|
|
|
|
InternalFileHierarchyStorage *mStorage ;
|
|
|
|
|
|
|
|
friend class DirectoryStorage ;
|
2016-07-23 22:14:43 -04:00
|
|
|
};
|
2016-07-18 21:52:44 -04:00
|
|
|
class FileIterator
|
|
|
|
{
|
|
|
|
public:
|
2016-07-24 23:48:22 -04:00
|
|
|
FileIterator(DirIterator& d); // crawls all files in specified directory
|
|
|
|
FileIterator(DirectoryStorage *d,EntryIndex e); // crawls all files in specified directory
|
2016-07-18 21:52:44 -04:00
|
|
|
|
|
|
|
FileIterator& operator++() ;
|
2016-07-24 23:48:22 -04:00
|
|
|
EntryIndex operator*() const ; // current file entry
|
2016-07-18 21:52:44 -04:00
|
|
|
|
2016-07-23 22:14:43 -04:00
|
|
|
operator bool() const ; // used in for loops. Returns true when the iterator is valid.
|
|
|
|
|
|
|
|
// info about the file that is pointed by the iterator
|
|
|
|
|
|
|
|
std::string name() const ;
|
|
|
|
uint64_t size() const ;
|
|
|
|
RsFileHash hash() const ;
|
|
|
|
time_t modtime() const ;
|
2016-07-24 23:48:22 -04:00
|
|
|
|
|
|
|
private:
|
|
|
|
EntryIndex mParentIndex ; // index of the parent dir.
|
|
|
|
uint32_t mFileTabIndex ; // index in the vector of subdirs.
|
|
|
|
InternalFileHierarchyStorage *mStorage ;
|
2016-07-23 22:14:43 -04:00
|
|
|
};
|
2016-07-18 21:52:44 -04:00
|
|
|
|
2016-07-28 03:29:15 -04:00
|
|
|
struct FileTS
|
|
|
|
{
|
|
|
|
uint64_t size ;
|
|
|
|
time_t modtime;
|
|
|
|
};
|
|
|
|
|
2016-07-27 15:22:59 -04:00
|
|
|
EntryIndex root() const ; // returns the index of the root directory entry.
|
2016-08-11 08:07:45 -04:00
|
|
|
const RsPeerId& peerId() const { return mPeerId ; }
|
|
|
|
int parentRow(EntryIndex e) const ;
|
2016-07-21 00:16:12 -04:00
|
|
|
|
2016-09-07 16:31:12 -04:00
|
|
|
bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs) ;
|
2016-07-28 03:29:15 -04:00
|
|
|
bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ;
|
2016-07-27 15:22:59 -04:00
|
|
|
bool removeDirectory(const EntryIndex& indx) ;
|
2016-07-23 22:14:43 -04:00
|
|
|
|
2016-07-27 15:22:59 -04:00
|
|
|
bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ;
|
|
|
|
bool updateHash(const EntryIndex& index,const RsFileHash& hash);
|
2016-07-24 23:48:22 -04:00
|
|
|
|
2016-09-08 17:43:14 -04:00
|
|
|
bool getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const ;
|
|
|
|
bool getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const ;
|
2016-09-07 16:31:12 -04:00
|
|
|
|
2016-07-27 18:48:28 -04:00
|
|
|
void print();
|
2016-07-24 23:48:22 -04:00
|
|
|
void cleanup();
|
|
|
|
|
2016-09-03 07:29:23 -04:00
|
|
|
protected:
|
2016-07-18 21:52:44 -04:00
|
|
|
void load(const std::string& local_file_name) ;
|
|
|
|
void save(const std::string& local_file_name) ;
|
|
|
|
|
2016-09-03 07:29:23 -04:00
|
|
|
private:
|
|
|
|
|
2016-07-21 00:16:12 -04:00
|
|
|
void loadNextTag(const unsigned char *data, uint32_t& offset, uint8_t& entry_tag, uint32_t& entry_size) ;
|
|
|
|
void saveNextTag(unsigned char *data,uint32_t& offset,uint8_t entry_tag,uint32_t entry_size) ;
|
|
|
|
|
2016-08-26 10:29:02 -04:00
|
|
|
// debug
|
|
|
|
void locked_check();
|
|
|
|
|
2016-07-21 00:16:12 -04:00
|
|
|
// storage of internal structure. Totally hidden from the outside. EntryIndex is simply the index of the entry in the vector.
|
|
|
|
|
2016-08-11 08:07:45 -04:00
|
|
|
RsPeerId mPeerId;
|
|
|
|
|
2016-07-27 15:22:59 -04:00
|
|
|
protected:
|
2016-08-11 08:07:45 -04:00
|
|
|
mutable RsMutex mDirStorageMtx ;
|
|
|
|
|
|
|
|
InternalFileHierarchyStorage *mFileHierarchy ;
|
2016-07-18 21:52:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
class RemoteDirectoryStorage: public DirectoryStorage
|
|
|
|
{
|
2016-07-20 16:10:51 -04:00
|
|
|
public:
|
2016-09-03 07:29:23 -04:00
|
|
|
RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) ;
|
2016-07-20 16:10:51 -04:00
|
|
|
virtual ~RemoteDirectoryStorage() {}
|
2016-08-26 10:29:02 -04:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief deserialiseDirEntry
|
|
|
|
* Loads a serialised directory content coming from a friend. The directory entry needs to exist already,
|
|
|
|
* as it is created when updating the parent.
|
|
|
|
*
|
|
|
|
* \param indx index of the directory to update
|
|
|
|
* \param bindata binary data to deserialise from
|
|
|
|
* \return false when the directory cannot be found.
|
|
|
|
*/
|
2016-09-03 07:29:23 -04:00
|
|
|
bool deserialiseUpdateDirEntry(const EntryIndex& indx,const RsTlvBinaryData& data) ;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief checkSave
|
|
|
|
* Checks the time of last saving, last modification time, and saves if needed.
|
|
|
|
*/
|
|
|
|
void checkSave() ;
|
|
|
|
|
|
|
|
private:
|
|
|
|
time_t mLastSavedTime ;
|
|
|
|
bool mChanged ;
|
|
|
|
std::string mFileName;
|
2016-07-18 21:52:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
class LocalDirectoryStorage: public DirectoryStorage
|
|
|
|
{
|
2016-07-20 16:10:51 -04:00
|
|
|
public:
|
2016-09-03 07:29:23 -04:00
|
|
|
LocalDirectoryStorage(const std::string& fname,const RsPeerId& own_id) : DirectoryStorage(own_id),mFileName(fname) {}
|
2016-07-20 16:10:51 -04:00
|
|
|
virtual ~LocalDirectoryStorage() {}
|
2016-07-21 00:16:12 -04:00
|
|
|
|
|
|
|
void setSharedDirectoryList(const std::list<SharedDirInfo>& lst) ;
|
|
|
|
void getSharedDirectoryList(std::list<SharedDirInfo>& lst) ;
|
|
|
|
|
2016-07-31 09:59:58 -04:00
|
|
|
void updateShareFlags(const SharedDirInfo& info) ;
|
|
|
|
bool convertSharedFilePath(const std::string& path_with_virtual_name,std::string& fullpath) ;
|
|
|
|
|
2016-08-22 01:49:45 -04:00
|
|
|
void updateTimeStamps();
|
2016-07-31 09:59:58 -04:00
|
|
|
/*!
|
|
|
|
* \brief getFileInfo Converts an index info a full file info structure.
|
|
|
|
* \param i index in the directory structure
|
|
|
|
* \param info structure to be filled in
|
|
|
|
* \return false if the file does not exist, or is a directory,...
|
|
|
|
*/
|
|
|
|
bool getFileInfo(DirectoryStorage::EntryIndex i,FileInfo& info) ;
|
2016-08-11 08:07:45 -04:00
|
|
|
|
2016-08-30 15:28:32 -04:00
|
|
|
/*!
|
|
|
|
* \brief getFileSharingPermissions
|
|
|
|
* Computes the flags and parent groups for any index.
|
|
|
|
* \param indx index of the entry to compute the flags for
|
|
|
|
* \param flags computed flags
|
|
|
|
* \param parent_groups computed parent groups
|
|
|
|
* \return
|
|
|
|
* false if the index is not valid
|
|
|
|
* false otherwise
|
|
|
|
*/
|
2016-09-01 14:02:47 -04:00
|
|
|
bool getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags &flags, std::list<RsNodeGroupId> &parent_groups);
|
2016-08-30 15:28:32 -04:00
|
|
|
|
2016-08-11 08:07:45 -04:00
|
|
|
virtual bool extractData(const EntryIndex& indx,DirDetails& d) ;
|
|
|
|
|
2016-08-26 10:29:02 -04:00
|
|
|
/*!
|
|
|
|
* \brief serialiseDirEntry
|
|
|
|
* Produced a serialised directory content listing suitable for export to friends.
|
|
|
|
*
|
2016-08-31 16:47:05 -04:00
|
|
|
* \param indx index of the directory to serialise
|
|
|
|
* \param bindata binary data created by serialisation
|
|
|
|
* \param client_id Peer id to be serialised to. Depending on permissions, some subdirs can be removed.
|
|
|
|
* \return false when the directory cannot be found.
|
2016-08-26 10:29:02 -04:00
|
|
|
*/
|
2016-08-31 16:47:05 -04:00
|
|
|
bool serialiseDirEntry(const EntryIndex& indx, RsTlvBinaryData& bindata, const RsPeerId &client_id) ;
|
2016-08-26 10:29:02 -04:00
|
|
|
|
2016-07-21 00:16:12 -04:00
|
|
|
private:
|
2016-09-10 07:57:05 -04:00
|
|
|
std::string locked_getVirtualPath(EntryIndex indx) const ;
|
|
|
|
std::string locked_getVirtualDirName(EntryIndex indx) const ;
|
|
|
|
|
2016-09-01 14:02:47 -04:00
|
|
|
bool locked_getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags &flags, std::list<RsNodeGroupId>& parent_groups);
|
2016-07-31 09:59:58 -04:00
|
|
|
std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const;
|
2016-07-21 00:16:12 -04:00
|
|
|
|
2016-07-31 09:59:58 -04:00
|
|
|
std::map<std::string,SharedDirInfo> mLocalDirs ; // map is better for search. it->first=it->second.filename
|
2016-09-03 07:29:23 -04:00
|
|
|
std::string mFileName;
|
2016-07-18 21:52:44 -04:00
|
|
|
};
|
|
|
|
|
2016-07-21 00:16:12 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|