mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-04 15:15:15 -04:00
fixed conflicts in merging upstream/master to v0.6-FTEncryption
This commit is contained in:
commit
8c7c7647b0
173 changed files with 2701 additions and 13742 deletions
|
@ -149,7 +149,7 @@ bool InternalFileHierarchyStorage::isIndexValid(DirectoryStorage::EntryIndex e)
|
|||
return e < mNodes.size() && mNodes[e] != NULL ;
|
||||
}
|
||||
|
||||
bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,time_t>& subdirs)
|
||||
bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,time_t>& subdirs,const RsFileHash& random_hash_seed)
|
||||
{
|
||||
if(!checkIndex(indx,FileStorageNode::TYPE_DIR))
|
||||
return false;
|
||||
|
@ -188,9 +188,9 @@ bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage
|
|||
|
||||
de->row = mNodes.size();
|
||||
de->parent_index = indx;
|
||||
de->dir_modtime = it->second;
|
||||
de->dir_parent_path = d.dir_parent_path + "/" + d.dir_name ;
|
||||
de->dir_hash = createDirHash(de->dir_name,de->dir_parent_path) ;
|
||||
de->dir_modtime = 0;// forces parsing.it->second;
|
||||
de->dir_parent_path = RsDirUtil::makePath(d.dir_parent_path, d.dir_name) ;
|
||||
de->dir_hash = createDirHash(de->dir_name,d.dir_hash,random_hash_seed) ;
|
||||
|
||||
mDirHashes[de->dir_hash] = mNodes.size() ;
|
||||
|
||||
|
@ -201,7 +201,7 @@ bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage
|
|||
return true;
|
||||
}
|
||||
|
||||
RsFileHash InternalFileHierarchyStorage::createDirHash(const std::string &/*dir_name*/, const std::string &/*dir_parent_path*/)
|
||||
RsFileHash InternalFileHierarchyStorage::createDirHash(const std::string& dir_name, const RsFileHash& dir_parent_hash, const RsFileHash& random_hash_salt)
|
||||
{
|
||||
// What we need here: a unique identifier
|
||||
// - that cannot be bruteforced to find the real directory name and path
|
||||
|
@ -215,7 +215,19 @@ RsFileHash InternalFileHierarchyStorage::createDirHash(const std::string &/*dir_
|
|||
// Option 3: just compute something random, but then we need to store it so as to not
|
||||
// confuse friends when restarting.
|
||||
|
||||
return RsFileHash::random();
|
||||
RsTemporaryMemory mem(dir_name.size() + 2*RsFileHash::SIZE_IN_BYTES) ;
|
||||
|
||||
memcpy( mem, random_hash_salt.toByteArray(),RsFileHash::SIZE_IN_BYTES) ;
|
||||
memcpy(&mem[ RsFileHash::SIZE_IN_BYTES], dir_parent_hash.toByteArray(),RsFileHash::SIZE_IN_BYTES) ;
|
||||
memcpy(&mem[2*RsFileHash::SIZE_IN_BYTES],dir_name.c_str(), dir_name.size()) ;
|
||||
|
||||
RsFileHash res = RsDirUtil::sha1sum( mem,mem.size() ) ;
|
||||
|
||||
#ifdef DEBUG_DIRECTORY_STORAGE
|
||||
std::cerr << "Creating new dir hash for dir " << dir_name << ", parent dir hash=" << dir_parent_hash << " seed=[hidden]" << " result is " << res << std::endl;
|
||||
#endif
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
bool InternalFileHierarchyStorage::removeDirectory(DirectoryStorage::EntryIndex indx) // no reference here! Very important. Otherwise, the messign we do inside can change the value of indx!!
|
||||
|
@ -434,7 +446,7 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
|
|||
|
||||
mNodes[dir_index] = de ;
|
||||
|
||||
de->dir_parent_path = d.dir_parent_path + "/" + dir_name ;
|
||||
de->dir_parent_path = RsDirUtil::makePath(d.dir_parent_path, dir_name) ;
|
||||
de->dir_hash = subdirs_hash[i];
|
||||
|
||||
mDirHashes[subdirs_hash[i]] = dir_index ;
|
||||
|
@ -675,7 +687,7 @@ public:
|
|||
inline virtual uint64_t file_size() const { return mFe.file_size ; }
|
||||
inline virtual const RsFileHash& file_hash() const { return mFe.file_hash ; }
|
||||
inline virtual time_t file_modtime() const { return mFe.file_modtime ; }
|
||||
inline virtual std::string file_parent_path()const { return mDe.dir_parent_path + "/" + mDe.dir_name ; }
|
||||
inline virtual std::string file_parent_path()const { return RsDirUtil::makePath(mDe.dir_parent_path, mDe.dir_name) ; }
|
||||
inline virtual uint32_t file_popularity() const { NOT_IMPLEMENTED() ; return 0; }
|
||||
|
||||
private:
|
||||
|
@ -1123,7 +1135,9 @@ bool InternalFileHierarchyStorage::load(const std::string& fname)
|
|||
}
|
||||
catch(read_error& e)
|
||||
{
|
||||
#ifdef DEBUG_DIRECTORY_STORAGE
|
||||
std::cerr << "Error while reading: " << e.what() << std::endl;
|
||||
#endif
|
||||
|
||||
if(buffer != NULL)
|
||||
free(buffer) ;
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
int parentRow(DirectoryStorage::EntryIndex e);
|
||||
bool isIndexValid(DirectoryStorage::EntryIndex e) const;
|
||||
bool getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const;
|
||||
bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,time_t>& subdirs);
|
||||
bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::map<std::string,time_t>& subdirs, const RsFileHash &random_hash_seed);
|
||||
bool removeDirectory(DirectoryStorage::EntryIndex indx) ;
|
||||
bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const;
|
||||
bool updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,DirectoryStorage::FileTS>& subfiles,std::map<std::string,DirectoryStorage::FileTS>& new_files);
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
private:
|
||||
void recursPrint(int depth,DirectoryStorage::EntryIndex node) const;
|
||||
static bool nodeAccessError(const std::string& s);
|
||||
static RsFileHash createDirHash(const std::string& dir_name,const std::string& dir_parent_path) ;
|
||||
static RsFileHash createDirHash(const std::string& dir_name, const RsFileHash &dir_parent_hash, const RsFileHash &random_hash_salt) ;
|
||||
|
||||
// Allocates a new entry in mNodes, possible re-using an empty slot and returns its index.
|
||||
|
||||
|
|
|
@ -127,10 +127,10 @@ bool DirectoryStorage::setDirectoryUpdateTime (EntryIndex index,time_t update
|
|||
bool DirectoryStorage::setDirectoryRecursModTime(EntryIndex index,time_t rec_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,rec_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_most_recent_time); }
|
||||
bool DirectoryStorage::setDirectoryLocalModTime (EntryIndex index,time_t loc_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,loc_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_modtime ); }
|
||||
|
||||
bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::map<std::string,time_t>& subdirs)
|
||||
bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::map<std::string,time_t>& subdirs,const RsFileHash& hash_salt)
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
bool res = mFileHierarchy->updateSubDirectoryList(indx,subdirs) ;
|
||||
bool res = mFileHierarchy->updateSubDirectoryList(indx,subdirs,hash_salt) ;
|
||||
locked_check() ;
|
||||
return res ;
|
||||
}
|
||||
|
@ -168,10 +168,10 @@ bool DirectoryStorage::updateHash(const EntryIndex& index,const RsFileHash& hash
|
|||
return mFileHierarchy->updateHash(index,hash);
|
||||
}
|
||||
|
||||
void DirectoryStorage::load(const std::string& local_file_name)
|
||||
bool DirectoryStorage::load(const std::string& local_file_name)
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
mFileHierarchy->load(local_file_name);
|
||||
return mFileHierarchy->load(local_file_name);
|
||||
}
|
||||
void DirectoryStorage::save(const std::string& local_file_name)
|
||||
{
|
||||
|
@ -238,7 +238,7 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
|
|||
d.min_age = now - dir_entry->dir_most_recent_time ;
|
||||
d.age = now - dir_entry->dir_modtime ;
|
||||
d.name = dir_entry->dir_name;
|
||||
d.path = dir_entry->dir_parent_path + "/" + dir_entry->dir_name ;
|
||||
d.path = RsDirUtil::makePath(dir_entry->dir_parent_path, dir_entry->dir_name) ;
|
||||
d.parent = (void*)(intptr_t)dir_entry->parent_index ;
|
||||
|
||||
if(indx == 0)
|
||||
|
@ -262,7 +262,7 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
|
|||
const InternalFileHierarchyStorage::DirEntry *parent_dir_entry = mFileHierarchy->getDirEntry(file_entry->parent_index);
|
||||
|
||||
if(parent_dir_entry != NULL)
|
||||
d.path = parent_dir_entry->dir_parent_path + "/" + parent_dir_entry->dir_name + "/" ;
|
||||
d.path = RsDirUtil::makePath(parent_dir_entry->dir_parent_path, parent_dir_entry->dir_name) ;
|
||||
else
|
||||
d.path = "" ;
|
||||
}
|
||||
|
@ -770,6 +770,7 @@ void RemoteDirectoryStorage::checkSave()
|
|||
{
|
||||
save(mFileName);
|
||||
mLastSavedTime = now ;
|
||||
mChanged = false ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ class DirectoryStorage
|
|||
// Sets the subdirectory/subfiles list of entry indx the supplied one, possible adding and removing directories (resp.files). New directories are set empty with
|
||||
// just a name and need to be updated later on. New files are returned in a list so that they can be sent to hash cache.
|
||||
//
|
||||
bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs) ;
|
||||
bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs, const RsFileHash &random_hash_salt) ;
|
||||
bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ;
|
||||
bool removeDirectory(const EntryIndex& indx) ;
|
||||
|
||||
|
@ -153,7 +153,7 @@ class DirectoryStorage
|
|||
void cleanup();
|
||||
|
||||
protected:
|
||||
void load(const std::string& local_file_name) ;
|
||||
bool load(const std::string& local_file_name) ;
|
||||
void save(const std::string& local_file_name) ;
|
||||
|
||||
private:
|
||||
|
|
|
@ -55,7 +55,7 @@ void LocalDirectoryUpdater::setEnabled(bool b)
|
|||
return ;
|
||||
|
||||
if(b)
|
||||
start("fs dir updater") ;
|
||||
start("fs dir updater") ;
|
||||
else
|
||||
shutdown();
|
||||
|
||||
|
@ -88,17 +88,23 @@ void LocalDirectoryUpdater::forceUpdate()
|
|||
|
||||
void LocalDirectoryUpdater::sweepSharedDirectories()
|
||||
{
|
||||
if(mHashSalt.isNull())
|
||||
{
|
||||
std::cerr << "(EE) no salt value in LocalDirectoryUpdater. Is that a bug?" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
RsServer::notify()->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << "[directory storage] LocalDirectoryUpdater::sweep()" << std::endl;
|
||||
#endif
|
||||
|
||||
// recursive update algorithm works that way:
|
||||
// - the external loop starts on the shared directory list and goes through sub-directories
|
||||
// recursive update algorithm works that way:
|
||||
// - the external loop starts on the shared directory list and goes through sub-directories
|
||||
// - at the same time, it updates the local list of shared directories. A single sweep is performed over the whole directory structure.
|
||||
// - the information that is costly to compute (the hash) is store externally into a separate structure.
|
||||
// - doing so, changing directory names or moving files between directories does not cause a re-hash of the content.
|
||||
//
|
||||
// - the information that is costly to compute (the hash) is store externally into a separate structure.
|
||||
// - doing so, changing directory names or moving files between directories does not cause a re-hash of the content.
|
||||
//
|
||||
std::list<SharedDirInfo> shared_directory_list ;
|
||||
mSharedDirectories->getSharedDirectoryList(shared_directory_list);
|
||||
|
||||
|
@ -109,7 +115,7 @@ void LocalDirectoryUpdater::sweepSharedDirectories()
|
|||
|
||||
// make sure that entries in stored_dir_it are the same than paths in real_dir_it, and in the same order.
|
||||
|
||||
mSharedDirectories->updateSubDirectoryList(mSharedDirectories->root(),sub_dir_list) ;
|
||||
mSharedDirectories->updateSubDirectoryList(mSharedDirectories->root(),sub_dir_list,mHashSalt) ;
|
||||
|
||||
// now for each of them, go recursively and match both files and dirs
|
||||
|
||||
|
@ -137,59 +143,71 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
|
|||
|
||||
librs::util::FolderIterator dirIt(cumulated_path);
|
||||
|
||||
// collect subdirs and subfiles
|
||||
|
||||
std::map<std::string,DirectoryStorage::FileTS> subfiles ;
|
||||
std::map<std::string,time_t> subdirs ;
|
||||
|
||||
for(;dirIt.isValid();dirIt.next())
|
||||
time_t dir_local_mod_time ;
|
||||
if(!mSharedDirectories->getDirectoryLocalModTime(indx,dir_local_mod_time))
|
||||
{
|
||||
switch(dirIt.file_type())
|
||||
{
|
||||
case librs::util::FolderIterator::TYPE_FILE: subfiles[dirIt.file_name()].modtime = dirIt.file_modtime() ;
|
||||
subfiles[dirIt.file_name()].size = dirIt.file_size();
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " adding sub-file \"" << dirIt.file_name() << "\"" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case librs::util::FolderIterator::TYPE_DIR: subdirs[dirIt.file_name()] = dirIt.file_modtime();
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " adding sub-dir \"" << dirIt.file_name() << "\"" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
std::cerr << "(EE) Dir entry of unknown type with path \"" << cumulated_path << "/" << dirIt.file_name() << "\"" << std::endl;
|
||||
}
|
||||
std::cerr << "(EE) Cannot get local mod time for dir index " << indx << std::endl;
|
||||
return;
|
||||
}
|
||||
// update folder modificatoin time, which is the only way to detect e.g. removed or renamed files.
|
||||
|
||||
mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()) ;
|
||||
|
||||
// update file and dir lists for current directory.
|
||||
|
||||
mSharedDirectories->updateSubDirectoryList(indx,subdirs) ;
|
||||
|
||||
std::map<std::string,DirectoryStorage::FileTS> new_files ;
|
||||
mSharedDirectories->updateSubFilesList(indx,subfiles,new_files) ;
|
||||
|
||||
// now go through list of subfiles and request the hash to hashcache
|
||||
|
||||
for(DirectoryStorage::FileIterator dit(mSharedDirectories,indx);dit;++dit)
|
||||
if(dirIt.dir_modtime() != dir_local_mod_time)
|
||||
{
|
||||
// ask about the hash. If not present, ask HashCache. If not present, or different, the callback will update it.
|
||||
// collect subdirs and subfiles
|
||||
|
||||
RsFileHash hash ;
|
||||
std::map<std::string,DirectoryStorage::FileTS> subfiles ;
|
||||
std::map<std::string,time_t> subdirs ;
|
||||
|
||||
if(mHashCache->requestHash(cumulated_path + "/" + dit.name(),dit.size(),dit.modtime(),hash,this,*dit) && dit.hash() != hash)
|
||||
mSharedDirectories->updateHash(*dit,hash);
|
||||
for(;dirIt.isValid();dirIt.next())
|
||||
{
|
||||
switch(dirIt.file_type())
|
||||
{
|
||||
case librs::util::FolderIterator::TYPE_FILE: subfiles[dirIt.file_name()].modtime = dirIt.file_modtime() ;
|
||||
subfiles[dirIt.file_name()].size = dirIt.file_size();
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " adding sub-file \"" << dirIt.file_name() << "\"" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case librs::util::FolderIterator::TYPE_DIR: subdirs[dirIt.file_name()] = dirIt.file_modtime();
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " adding sub-dir \"" << dirIt.file_name() << "\"" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
std::cerr << "(EE) Dir entry of unknown type with path \"" << cumulated_path << "/" << dirIt.file_name() << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
// update folder modificatoin time, which is the only way to detect e.g. removed or renamed files.
|
||||
|
||||
mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()) ;
|
||||
|
||||
// update file and dir lists for current directory.
|
||||
|
||||
mSharedDirectories->updateSubDirectoryList(indx,subdirs,mHashSalt) ;
|
||||
|
||||
std::map<std::string,DirectoryStorage::FileTS> new_files ;
|
||||
mSharedDirectories->updateSubFilesList(indx,subfiles,new_files) ;
|
||||
|
||||
// now go through list of subfiles and request the hash to hashcache
|
||||
|
||||
for(DirectoryStorage::FileIterator dit(mSharedDirectories,indx);dit;++dit)
|
||||
{
|
||||
// ask about the hash. If not present, ask HashCache. If not present, or different, the callback will update it.
|
||||
|
||||
RsFileHash hash ;
|
||||
|
||||
if(mHashCache->requestHash(cumulated_path + "/" + dit.name(),dit.size(),dit.modtime(),hash,this,*dit) && dit.hash() != hash)
|
||||
mSharedDirectories->updateHash(*dit,hash);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
else
|
||||
std::cerr << " directory is unchanged. Keeping existing files and subdirs list." << std::endl;
|
||||
#endif
|
||||
|
||||
// go through the list of sub-dirs and recursively update
|
||||
|
||||
DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,indx) ;
|
||||
|
||||
for(std::map<std::string,time_t>::const_iterator real_dir_it(subdirs.begin());real_dir_it!=subdirs.end();++real_dir_it, ++stored_dir_it)
|
||||
for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,indx) ; stored_dir_it; ++stored_dir_it)
|
||||
{
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " recursing into " << stored_dir_it.name() << std::endl;
|
||||
|
|
|
@ -41,6 +41,9 @@ public:
|
|||
void forceUpdate();
|
||||
bool inDirectoryCheck() const ;
|
||||
|
||||
void setHashSalt(const RsFileHash& hash) { mHashSalt = hash; }
|
||||
const RsFileHash& hashSalt() const { return mHashSalt; }
|
||||
|
||||
void setFileWatchPeriod(int seconds) ;
|
||||
uint32_t fileWatchPeriod() const ;
|
||||
|
||||
|
@ -60,6 +63,8 @@ private:
|
|||
HashStorage *mHashCache ;
|
||||
LocalDirectoryStorage *mSharedDirectories ;
|
||||
|
||||
RsFileHash mHashSalt ;
|
||||
|
||||
time_t mLastSweepTime;
|
||||
time_t mLastTSUpdateTime;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 se
|
|||
static const std::string HASH_CACHE_DURATION_SS = "HASH_CACHE_DURATION" ; // key string to store hash remembering time
|
||||
static const std::string WATCH_FILE_DURATION_SS = "WATCH_FILES_DELAY" ; // key to store delay before re-checking for new files
|
||||
static const std::string WATCH_FILE_ENABLED_SS = "WATCH_FILES_ENABLED"; // key to store ON/OFF flags for file whatch
|
||||
static const std::string WATCH_HASH_SALT_SS = "WATCH_HASH_SALT"; // Salt that is used to hash directory names
|
||||
|
||||
static const std::string FILE_SHARING_DIR_NAME = "file_sharing" ; // hard-coded directory name to store friend file lists, hash cache, etc.
|
||||
static const std::string HASH_CACHE_FILE_NAME = "hash_cache.bin" ; // hard-coded directory name to store encrypted hash cache.
|
||||
|
|
|
@ -190,7 +190,9 @@ bool FileListIO::loadEncryptedDataFromFile(const std::string& fname,unsigned cha
|
|||
|
||||
if(!RsDirUtil::checkFile( fname,file_size,false ) )
|
||||
{
|
||||
#ifdef FIM_DEBUG
|
||||
std::cerr << "Encrypted file " << fname << " not available." << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ void HashStorage::data_tick()
|
|||
{
|
||||
FileHashJob job;
|
||||
RsFileHash hash;
|
||||
uint64_t size ;
|
||||
uint64_t size = 0;
|
||||
|
||||
{
|
||||
bool empty ;
|
||||
|
@ -270,7 +270,7 @@ void HashStorage::clean()
|
|||
#endif
|
||||
|
||||
for(std::map<std::string,HashStorageInfo>::iterator it(mFiles.begin());it!=mFiles.end();)
|
||||
if(it->second.time_stamp + duration < (uint64_t)now)
|
||||
if((uint64_t)(it->second.time_stamp + duration) < (uint64_t)now)
|
||||
{
|
||||
#ifdef HASHSTORAGE_DEBUG
|
||||
std::cerr << " Entry too old: " << it->first << ", ts=" << it->second.time_stamp << std::endl ;
|
||||
|
|
|
@ -224,7 +224,7 @@ int p3FileDatabase::tick()
|
|||
|
||||
mLastRemoteDirSweepTS = now;
|
||||
|
||||
// This is a hash to make loaded directories show up in the GUI, because the GUI generally isn't ready at the time they are actually loaded up,
|
||||
// This is a hack to make loaded directories show up in the GUI, because the GUI generally isn't ready at the time they are actually loaded up,
|
||||
// so the first notify is ignored, and no other notify will happen next.
|
||||
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0);
|
||||
|
@ -326,7 +326,14 @@ cleanup = true;
|
|||
|
||||
rskv->tlvkvs.pairs.push_back(kv);
|
||||
}
|
||||
{
|
||||
RsTlvKeyValue kv;
|
||||
|
||||
kv.key = WATCH_HASH_SALT_SS;
|
||||
kv.value = mLocalDirWatcher->hashSalt().toStdString();
|
||||
|
||||
rskv->tlvkvs.pairs.push_back(kv);
|
||||
}
|
||||
/* Add KeyValue to saveList */
|
||||
sList.push_back(rskv);
|
||||
|
||||
|
@ -373,6 +380,11 @@ bool p3FileDatabase::loadList(std::list<RsItem *>& load)
|
|||
{
|
||||
setWatchEnabled(kit->value == "YES") ;
|
||||
}
|
||||
else if(kit->key == WATCH_HASH_SALT_SS)
|
||||
{
|
||||
std::cerr << "Initing directory watcher with saved secret salt..." << std::endl;
|
||||
mLocalDirWatcher->setHashSalt(RsFileHash(kit->value)) ;
|
||||
}
|
||||
delete *it ;
|
||||
continue ;
|
||||
}
|
||||
|
@ -397,6 +409,14 @@ bool p3FileDatabase::loadList(std::list<RsItem *>& load)
|
|||
|
||||
delete *it ;
|
||||
}
|
||||
if(mLocalDirWatcher->hashSalt().isNull())
|
||||
{
|
||||
std::cerr << "(WW) Initialising directory watcher salt to some random value " << std::endl;
|
||||
mLocalDirWatcher->setHashSalt(RsFileHash::random()) ;
|
||||
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
|
||||
|
||||
/* set directories */
|
||||
mLocalSharedDirs->setSharedDirectoryList(dirList);
|
||||
|
@ -620,12 +640,9 @@ void p3FileDatabase::requestDirUpdate(void *ref)
|
|||
}
|
||||
}
|
||||
|
||||
bool p3FileDatabase::findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) const
|
||||
bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result,
|
||||
FileSearchFlags flags ) const
|
||||
{
|
||||
RS_STACK_MUTEX(mFLSMtx) ;
|
||||
|
||||
result = NULL ;
|
||||
|
||||
if (ref == NULL)
|
||||
{
|
||||
if(flags & RS_FILE_HINTS_LOCAL)
|
||||
|
@ -668,8 +685,8 @@ bool p3FileDatabase::findChildPointer(void *ref, int row, void *& result, FileSe
|
|||
|
||||
return res;
|
||||
}
|
||||
// This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files.
|
||||
|
||||
// This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files.
|
||||
int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const
|
||||
{
|
||||
RS_STACK_MUTEX(mFLSMtx) ;
|
||||
|
@ -1130,7 +1147,9 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
|
|||
|
||||
if(!mLocalSharedDirs->getIndexFromDirHash(item->entry_hash,entry_index))
|
||||
{
|
||||
P3FILELISTS_ERROR() << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl;
|
||||
#ifdef DEBUG_P3FILELISTS
|
||||
P3FILELISTS_DEBUG() << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -728,14 +728,13 @@ bool ftController::completeFile(const RsFileHash& hash)
|
|||
std::string path;
|
||||
std::string name;
|
||||
uint64_t size = 0;
|
||||
uint32_t state = 0;
|
||||
uint32_t period = 0;
|
||||
TransferRequestFlags flags ;
|
||||
TransferRequestFlags extraflags ;
|
||||
uint32_t completeCount = 0;
|
||||
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
RS_STACK_MUTEX(ctrlMutex);
|
||||
|
||||
#ifdef CONTROL_DEBUG
|
||||
std::cerr << "ftController:completeFile(" << hash << ")";
|
||||
|
@ -817,7 +816,6 @@ bool ftController::completeFile(const RsFileHash& hash)
|
|||
name = fc->mName;
|
||||
//hash = fc->mHash;
|
||||
size = fc->mSize;
|
||||
state = fc->mState;
|
||||
period = 30 * 24 * 3600; /* 30 days */
|
||||
extraflags.clear() ;
|
||||
|
||||
|
@ -838,7 +836,7 @@ bool ftController::completeFile(const RsFileHash& hash)
|
|||
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
|
||||
mFtServer->activateTunnels(hash_to_suppress,flags,false);
|
||||
|
||||
} /******* UNLOCKED ********/
|
||||
} // UNLOCK: RS_STACK_MUTEX(ctrlMutex);
|
||||
|
||||
|
||||
/******************** NO Mutex from Now ********************
|
||||
|
|
|
@ -1691,7 +1691,7 @@ void RsGenExchange::processMsgMetaChanges()
|
|||
{
|
||||
MsgLocMetaData& m = mit->second;
|
||||
|
||||
int32_t value, mask;
|
||||
int32_t value, mask;
|
||||
bool ok = true;
|
||||
bool changed = false;
|
||||
|
||||
|
@ -1717,7 +1717,7 @@ void RsGenExchange::processMsgMetaChanges()
|
|||
{
|
||||
RsGxsMsgMetaData* meta = *(msgMetaV.begin());
|
||||
value = (meta->mMsgStatus & ~mask) | (mask & value);
|
||||
changed = (meta->mMsgStatus != value);
|
||||
changed = (static_cast<int64_t>(meta->mMsgStatus) != value);
|
||||
m.val.put(RsGeneralDataService::MSG_META_STATUS, value);
|
||||
delete meta;
|
||||
ok = true;
|
||||
|
@ -2822,10 +2822,8 @@ void RsGenExchange::processRecvdMessages()
|
|||
mNetService->rejectMessage(*it) ;
|
||||
}
|
||||
|
||||
bool RsGenExchange::acceptNewGroup(const RsGxsGrpMetaData *grpMeta)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool RsGenExchange::acceptNewGroup(const RsGxsGrpMetaData* /*grpMeta*/ )
|
||||
{ return true; }
|
||||
|
||||
void RsGenExchange::processRecvdGroups()
|
||||
{
|
||||
|
|
|
@ -147,8 +147,7 @@ void RsPluginManager::loadPlugins(const std::vector<std::string>& plugin_directo
|
|||
|
||||
for(;dirIt.isValid();dirIt.next())
|
||||
{
|
||||
std::string fname;
|
||||
dirIt.d_name(fname);
|
||||
std::string fname = dirIt.file_name();
|
||||
|
||||
char lc = plugin_directories[i][plugin_directories[i].length()-1] ; // length cannot be 0 here.
|
||||
|
||||
|
|
|
@ -2841,121 +2841,48 @@ bool p3PeerMgrIMPL::removeBannedIps()
|
|||
bool p3PeerMgrIMPL::removeUnusedLocations()
|
||||
{
|
||||
std::list<RsPeerId> toRemove;
|
||||
|
||||
std::map<RsPgpId, bool> hasRecentLocation;
|
||||
std::map<RsPgpId, time_t> mostRecentTime;
|
||||
std::map<RsPgpId, RsPeerId> mostRecentLocation;
|
||||
|
||||
// init maps
|
||||
{
|
||||
std::list<RsPgpId> pgpList;
|
||||
|
||||
if(!rsPeers->getGPGAcceptedList(pgpList))
|
||||
return false;
|
||||
|
||||
std::list<RsPgpId>::iterator it;
|
||||
for(it = pgpList.begin(); it != pgpList.end(); ++it)
|
||||
{
|
||||
hasRecentLocation[*it] = false;
|
||||
mostRecentTime[*it] = (time_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
const time_t now = time(NULL);
|
||||
RsPgpId pgpID;
|
||||
|
||||
|
||||
std::list<RsPgpId> pgpList;
|
||||
|
||||
if(!rsPeers->getGPGAcceptedList(pgpList))
|
||||
return false;
|
||||
{
|
||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
// First put a sensible number in all PGP ids
|
||||
|
||||
for(std::list<RsPgpId>::const_iterator it = pgpList.begin(); it != pgpList.end(); ++it)
|
||||
mostRecentTime[*it] = (time_t)0;
|
||||
|
||||
#ifdef PEER_DEBUG
|
||||
std::cerr << "p3PeerMgr::removeUnusedLocations()" << std::endl;
|
||||
#endif
|
||||
// Then compute the most recently used location for all PGP ids
|
||||
|
||||
std::map<RsPeerId, peerState>::iterator it;
|
||||
for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
|
||||
{
|
||||
pgpID = it->second.gpg_id;
|
||||
for( std::map<RsPeerId, peerState>::iterator it = mFriendList.begin(); it != mFriendList.end(); ++it)
|
||||
{
|
||||
time_t& bst(mostRecentTime[it->second.gpg_id]) ;
|
||||
bst = std::max(bst,it->second.lastcontact) ;
|
||||
}
|
||||
|
||||
// store some references to speed up accessing
|
||||
RsPeerId &idRef = mostRecentLocation[pgpID];
|
||||
bool &recentRef = hasRecentLocation[pgpID];
|
||||
// And remove all locations that are too old and also older than the most recent location. Doing this we're sure to always keep at least one location per PGP id.
|
||||
|
||||
if (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE)
|
||||
{
|
||||
// location is too old
|
||||
if(recentRef)
|
||||
{
|
||||
// there is already one location that won't get removed
|
||||
// -> we can safely remove this one
|
||||
toRemove.push_back(it->first);
|
||||
for( std::map<RsPeerId, peerState>::iterator it = mFriendList.begin(); it != mFriendList.end(); ++it)
|
||||
{
|
||||
if (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE && it->second.lastcontact < mostRecentTime[it->second.gpg_id])
|
||||
toRemove.push_back(it->first);
|
||||
#ifdef PEER_DEBUG
|
||||
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
|
||||
std::cerr << "Location " << it->first << " PGP id " << it->second.gpg_id << " last contact " << it->second.lastcontact << " remove: " << (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE) << " most recent: " << mostRecentTime[it->second.gpg_id]
|
||||
<< ". Final result remove: " << (it->second.lastcontact < mostRecentTime[it->second.gpg_id] && now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE )<< std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need to take care that the most recent location it not removed
|
||||
time_t &timeRef = mostRecentTime[pgpID];
|
||||
|
||||
if(timeRef > it->second.lastcontact)
|
||||
{
|
||||
// this (it) location is longer offline compared to mostRecentLocation
|
||||
// -> we can remove this one
|
||||
toRemove.push_back(it->first);
|
||||
#ifdef PEER_DEBUG
|
||||
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// this (it) location is more recent compared to mostRecentLocation
|
||||
// -> we can remove mostRecentLocation
|
||||
if(!idRef.isNull())
|
||||
{
|
||||
toRemove.push_back(idRef);
|
||||
#ifdef PEER_DEBUG
|
||||
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
|
||||
#endif
|
||||
}
|
||||
// update maps
|
||||
idRef = it->first;
|
||||
timeRef = it->second.lastcontact;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// found a location that won't get removed
|
||||
recentRef = true;
|
||||
|
||||
// we can remove mostRecentLocation if it is set
|
||||
if(!idRef.isNull())
|
||||
{
|
||||
toRemove.push_back(idRef);
|
||||
#ifdef PEER_DEBUG
|
||||
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// if (isDummyFriend(it->first))
|
||||
// {
|
||||
// toRemove.push_back(it->first);
|
||||
//
|
||||
//#ifdef PEER_DEBUG
|
||||
// std::cerr << "p3PeerMgr::removeUnusedLocations() removing Dummy Id: " << it->first << std::endl;
|
||||
//#endif
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<RsPeerId>::iterator it;
|
||||
for(it = toRemove.begin(); it != toRemove.end(); ++it)
|
||||
{
|
||||
removeFriend(*it, false);
|
||||
}
|
||||
for( std::list<RsPeerId>::iterator it = toRemove.begin(); it != toRemove.end(); ++it)
|
||||
removeFriend(*it, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,19 @@ static uint8_t PACKET_SLICING_PROBE_BYTES[8] = { 0x02, 0xaa, 0xbb, 0xcc, 0x00,
|
|||
#include "util/rsprint.h"
|
||||
#endif
|
||||
|
||||
static double getCurrentTS()
|
||||
{
|
||||
#ifndef WINDOWS_SYS
|
||||
struct timeval cts_tmp;
|
||||
gettimeofday(&cts_tmp, NULL);
|
||||
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
|
||||
#else
|
||||
struct _timeb timebuf;
|
||||
_ftime( &timebuf);
|
||||
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
|
||||
#endif
|
||||
return cts;
|
||||
}
|
||||
|
||||
pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in)
|
||||
:PQInterface(id), mStreamerMtx("pqistreamer"),
|
||||
|
@ -97,7 +110,9 @@ pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bi
|
|||
mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready.
|
||||
mLastSentPacketSlicingProbe = 0 ;
|
||||
|
||||
mAvgLastUpdate = mCurrReadTS = mCurrSentTS = time(NULL);
|
||||
mAvgLastUpdate = time(NULL);
|
||||
mCurrSentTS = mCurrReadTS = getCurrentTS();
|
||||
|
||||
mIncomingSize = 0 ;
|
||||
|
||||
mStatisticsTimeStamp = 0 ;
|
||||
|
@ -540,7 +555,7 @@ int pqistreamer::handleoutgoing_locked()
|
|||
// if so, we enable it for the session. This should be removed (because it's unnecessary) when all users have switched to the new version.
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
if((!mAcceptsPacketSlicing) && now > mLastSentPacketSlicingProbe + PQISTREAM_PACKET_SLICING_PROBE_DELAY)
|
||||
if(now > mLastSentPacketSlicingProbe + PQISTREAM_PACKET_SLICING_PROBE_DELAY)
|
||||
{
|
||||
#ifdef DEBUG_PACKET_SLICING
|
||||
std::cerr << "(II) Inserting packet slicing probe in traffic" << std::endl;
|
||||
|
@ -1099,7 +1114,7 @@ float pqistreamer::outTimeSlice_locked()
|
|||
// very simple.....
|
||||
int pqistreamer::outAllowedBytes_locked()
|
||||
{
|
||||
int t = time(NULL); // get current timestep.
|
||||
double t = getCurrentTS() ; // Grabs today's time in sec, with ms accuracy. Allows a much more accurate allocation of bw
|
||||
|
||||
/* allow a lot if not bandwidthLimited */
|
||||
if (!mBio->bandwidthLimited())
|
||||
|
@ -1109,17 +1124,18 @@ int pqistreamer::outAllowedBytes_locked()
|
|||
return PQISTREAM_ABS_MAX;
|
||||
}
|
||||
|
||||
int dt = t - mCurrSentTS;
|
||||
// limiter -> for when currSentTs -> 0.
|
||||
if (dt > 5)
|
||||
dt = 5;
|
||||
double dt = t - mCurrSentTS;
|
||||
|
||||
// limiter -> for when currSentTs -> 0.
|
||||
if (dt > 5)
|
||||
dt = 5;
|
||||
|
||||
double maxout = getMaxRate(false) * 1024.0;
|
||||
|
||||
mCurrSent -= int(dt * maxout);
|
||||
|
||||
int maxout = (int) (getMaxRate(false) * 1000.0);
|
||||
mCurrSent -= dt * maxout;
|
||||
if (mCurrSent < 0)
|
||||
{
|
||||
mCurrSent = 0;
|
||||
}
|
||||
|
||||
mCurrSentTS = t;
|
||||
|
||||
|
@ -1137,7 +1153,7 @@ int pqistreamer::outAllowedBytes_locked()
|
|||
|
||||
int pqistreamer::inAllowedBytes_locked()
|
||||
{
|
||||
int t = time(NULL); // get current timestep.
|
||||
double t = getCurrentTS(); // in secs, with a ms accuracy
|
||||
|
||||
/* allow a lot if not bandwidthLimited */
|
||||
if (!mBio->bandwidthLimited())
|
||||
|
@ -1147,17 +1163,18 @@ int pqistreamer::inAllowedBytes_locked()
|
|||
return PQISTREAM_ABS_MAX;
|
||||
}
|
||||
|
||||
int dt = t - mCurrReadTS;
|
||||
double dt = t - mCurrReadTS;
|
||||
|
||||
// limiter -> for when currReadTs -> 0.
|
||||
if (dt > 5)
|
||||
dt = 5;
|
||||
|
||||
int maxin = (int) (getMaxRate(true) * 1000.0);
|
||||
mCurrRead -= dt * maxin;
|
||||
double maxin = getMaxRate(true) * 1024.0;
|
||||
|
||||
mCurrRead -= int(dt * maxin);
|
||||
|
||||
if (mCurrRead < 0)
|
||||
{
|
||||
mCurrRead = 0;
|
||||
}
|
||||
|
||||
mCurrReadTS = t;
|
||||
|
||||
|
|
|
@ -159,8 +159,8 @@ class pqistreamer: public PQInterface
|
|||
int mCurrRead;
|
||||
int mCurrSent;
|
||||
|
||||
time_t mCurrReadTS; // TS from which these are measured.
|
||||
time_t mCurrSentTS;
|
||||
double mCurrReadTS; // TS from which these are measured.
|
||||
double mCurrSentTS;
|
||||
|
||||
time_t mAvgLastUpdate; // TS from which these are measured.
|
||||
uint32_t mAvgReadCount;
|
||||
|
|
|
@ -536,8 +536,7 @@ bool RsAccountsDetail::getAvailableAccounts(std::map<RsPeerId, AccountDetails> &
|
|||
for(;dirIt.isValid();dirIt.next())
|
||||
{
|
||||
/* check entry type */
|
||||
std::string fname;
|
||||
dirIt.d_name(fname);
|
||||
std::string fname = dirIt.file_name();
|
||||
std::string fullname = mBaseDirectory + "/" + fname;
|
||||
#ifdef FIM_DEBUG
|
||||
std::cerr << "calling stats on " << fullname <<std::endl;
|
||||
|
@ -1060,7 +1059,7 @@ bool RsAccountsDetail::GenerateSSLCertificate(const RsPgpId& pgp_id, const s
|
|||
|
||||
X509_print_ex(bio_out, x509, nmflag, reqflag);
|
||||
|
||||
BIO_flush(bio_out);
|
||||
(void) BIO_flush(bio_out);
|
||||
BIO_free(bio_out);
|
||||
|
||||
/* Save cert to file */
|
||||
|
|
|
@ -231,7 +231,7 @@ uint32_t getRawStringSize(const std::string &outStr)
|
|||
|
||||
bool getRawString(void *data, uint32_t size, uint32_t *offset, std::string &outStr)
|
||||
{
|
||||
#warning I had to change this. It seems like a bug to not clear the string. Should make sure it's not introducing any side effect.
|
||||
#warning "I had to change this. It seems like a bug to not clear the string. Should make sure it's not introducing any side effect."
|
||||
outStr.clear();
|
||||
|
||||
uint32_t len = 0;
|
||||
|
|
|
@ -206,27 +206,25 @@ void p3BanList::autoFigureOutBanRanges()
|
|||
{
|
||||
RS_STACK_MUTEX(mBanMtx) ;
|
||||
|
||||
bool changed = false ;
|
||||
|
||||
// clear automatic ban ranges
|
||||
|
||||
for(std::map<sockaddr_storage,BanListPeer>::iterator it(mBanRanges.begin());it!=mBanRanges.end();)
|
||||
for(std::map<sockaddr_storage,BanListPeer>::iterator it(mBanRanges.begin());
|
||||
it!=mBanRanges.end(); )
|
||||
{
|
||||
if(it->second.reason == RSBANLIST_REASON_AUTO_RANGE)
|
||||
{
|
||||
std::map<sockaddr_storage,BanListPeer>::iterator it2=it ;
|
||||
++it2 ;
|
||||
mBanRanges.erase(it) ;
|
||||
it=it2 ;
|
||||
|
||||
changed = true ;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
else ++it;
|
||||
}
|
||||
|
||||
IndicateConfigChanged();
|
||||
|
||||
if(!mAutoRangeIps)
|
||||
return ;
|
||||
if(!mAutoRangeIps) return;
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "Automatically figuring out IP ranges from banned IPs." << std::endl;
|
||||
#endif
|
||||
|
|
|
@ -63,7 +63,11 @@ void FolderIterator::next()
|
|||
{
|
||||
while(readdir())
|
||||
{
|
||||
d_name(mFileName);
|
||||
#ifdef WINDOWS_SYS
|
||||
ConvertUtf16ToUtf8(fileInfo.cFileName, mFileName) ;
|
||||
#else
|
||||
mFileName = ent->d_name ;
|
||||
#endif
|
||||
|
||||
if(mFileName == "." || mFileName == "..")
|
||||
continue ;
|
||||
|
@ -145,25 +149,6 @@ bool FolderIterator::readdir()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool FolderIterator::d_name(std::string& dest)
|
||||
{
|
||||
if(!validity)
|
||||
return false;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
if(! ConvertUtf16ToUtf8(fileInfo.cFileName, dest)) {
|
||||
validity = false;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if(ent == 0)
|
||||
return false;
|
||||
dest = ent->d_name;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
time_t FolderIterator::dir_modtime() const { return mFolderModTime ; }
|
||||
|
||||
const std::string& FolderIterator::file_fullpath() { return mFullPath ; }
|
||||
|
|
|
@ -39,8 +39,6 @@ public:
|
|||
bool readdir();
|
||||
void next();
|
||||
|
||||
#warning this one should go, as it reports the same information than file_name()
|
||||
bool d_name(std::string& dest);
|
||||
bool closedir();
|
||||
|
||||
const std::string& file_name() ;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "util/rsstring.h"
|
||||
#include "util/rsrandom.h"
|
||||
#include "util/rsmemory.h"
|
||||
#include "util/folderiterator.h"
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "rsthreads.h"
|
||||
#include <iostream>
|
||||
|
@ -437,200 +438,13 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
|
|||
|
||||
bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::set<std::string> &keepFiles)
|
||||
{
|
||||
for(librs::util::FolderIterator it(cleandir);it.isValid();it.next())
|
||||
if(it.file_type() == librs::util::FolderIterator::TYPE_FILE && (keepFiles.end() == std::find(keepFiles.begin(), keepFiles.end(), it.file_name())))
|
||||
remove( (cleandir + "/" + it.file_name()).c_str() ) ;
|
||||
|
||||
/* check for the dir existance */
|
||||
#ifdef WINDOWS_SYS
|
||||
std::wstring wcleandir;
|
||||
librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir);
|
||||
_WDIR *dir = _wopendir(wcleandir.c_str());
|
||||
#else
|
||||
DIR *dir = opendir(cleandir.c_str());
|
||||
#endif
|
||||
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
struct _wdirent *dent;
|
||||
struct _stat buf;
|
||||
|
||||
while(NULL != (dent = _wreaddir(dir)))
|
||||
#else
|
||||
struct dirent *dent;
|
||||
struct stat buf;
|
||||
|
||||
while(NULL != (dent = readdir(dir)))
|
||||
#endif
|
||||
{
|
||||
/* check entry type */
|
||||
#ifdef WINDOWS_SYS
|
||||
const std::wstring &wfname = dent -> d_name;
|
||||
std::wstring wfullname = wcleandir + L"/" + wfname;
|
||||
#else
|
||||
const std::string &fname = dent -> d_name;
|
||||
std::string fullname = cleandir + "/" + fname;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
if (-1 != _wstat(wfullname.c_str(), &buf))
|
||||
#else
|
||||
if (-1 != stat(fullname.c_str(), &buf))
|
||||
#endif
|
||||
{
|
||||
/* only worry about files */
|
||||
if (S_ISREG(buf.st_mode))
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
std::string fname;
|
||||
librs::util::ConvertUtf16ToUtf8(wfname, fname);
|
||||
#endif
|
||||
/* check if we should keep it */
|
||||
if (keepFiles.end() == std::find(keepFiles.begin(), keepFiles.end(), fname))
|
||||
{
|
||||
/* can remove */
|
||||
#ifdef WINDOWS_SYS
|
||||
_wremove(wfullname.c_str());
|
||||
#else
|
||||
remove(fullname.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close directory */
|
||||
#ifdef WINDOWS_SYS
|
||||
_wclosedir(dir);
|
||||
#else
|
||||
closedir(dir);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* faster cleanup - first construct two sets - then iterate over together */
|
||||
bool RsDirUtil::cleanupDirectoryFaster(const std::string& cleandir, const std::set<std::string> &keepFiles)
|
||||
{
|
||||
|
||||
/* check for the dir existance */
|
||||
#ifdef WINDOWS_SYS
|
||||
std::map<std::string, std::wstring> fileMap;
|
||||
std::map<std::string, std::wstring>::const_iterator fit;
|
||||
|
||||
std::wstring wcleandir;
|
||||
librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir);
|
||||
_WDIR *dir = _wopendir(wcleandir.c_str());
|
||||
#else
|
||||
std::map<std::string, std::string> fileMap;
|
||||
std::map<std::string, std::string>::const_iterator fit;
|
||||
|
||||
DIR *dir = opendir(cleandir.c_str());
|
||||
#endif
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
struct _wdirent *dent;
|
||||
struct _stat buf;
|
||||
|
||||
while(NULL != (dent = _wreaddir(dir)))
|
||||
{
|
||||
const std::wstring &wfname = dent -> d_name;
|
||||
std::wstring wfullname = wcleandir + L"/" + wfname;
|
||||
|
||||
if (-1 != _wstat(wfullname.c_str(), &buf))
|
||||
{
|
||||
/* only worry about files */
|
||||
if (S_ISREG(buf.st_mode))
|
||||
{
|
||||
std::string fname;
|
||||
librs::util::ConvertUtf16ToUtf8(wfname, fname);
|
||||
fileMap[fname] = wfullname;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct dirent *dent;
|
||||
struct stat buf;
|
||||
|
||||
while(NULL != (dent = readdir(dir)))
|
||||
{
|
||||
const std::string &fname = dent -> d_name;
|
||||
std::string fullname = cleandir + "/" + fname;
|
||||
|
||||
if (-1 != stat(fullname.c_str(), &buf))
|
||||
{
|
||||
/* only worry about files */
|
||||
if (S_ISREG(buf.st_mode))
|
||||
{
|
||||
fileMap[fname] = fullname;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
std::set<std::string>::const_iterator kit;
|
||||
|
||||
fit = fileMap.begin();
|
||||
kit = keepFiles.begin();
|
||||
|
||||
while(fit != fileMap.end() && kit != keepFiles.end())
|
||||
{
|
||||
if (fit->first < *kit) // fit is not in keep list;
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
_wremove(fit->second.c_str());
|
||||
#else
|
||||
remove(fit->second.c_str());
|
||||
#endif
|
||||
++fit;
|
||||
}
|
||||
else if (*kit < fit->first) // keepitem doesn't exist.
|
||||
{
|
||||
++kit;
|
||||
}
|
||||
else // in keep list.
|
||||
{
|
||||
++fit;
|
||||
++kit;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup extra that aren't in keep list.
|
||||
while(fit != fileMap.end())
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
_wremove(fit->second.c_str());
|
||||
#else
|
||||
remove(fit->second.c_str());
|
||||
#endif
|
||||
++fit;
|
||||
}
|
||||
|
||||
/* close directory */
|
||||
#ifdef WINDOWS_SYS
|
||||
_wclosedir(dir);
|
||||
#else
|
||||
closedir(dir);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* slightly nicer helper function */
|
||||
bool RsDirUtil::hashFile(const std::string& filepath,
|
||||
std::string &name, RsFileHash &hash, uint64_t &size)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue