added an option to follow symbolic links or not, and anti-loop system during directories traversal

This commit is contained in:
mr-alice 2016-11-24 23:42:56 +01:00
parent cf270d73c0
commit 5f69c9ea1f
13 changed files with 218 additions and 126 deletions

View file

@ -43,6 +43,7 @@ LocalDirectoryUpdater::LocalDirectoryUpdater(HashStorage *hc,LocalDirectoryStora
mDelayBetweenDirectoryUpdates = DELAY_BETWEEN_DIRECTORY_UPDATES;
mIsEnabled = false ;
mFollowSymLinks = FOLLOW_SYMLINKS_DEFAULT ;
}
bool LocalDirectoryUpdater::isEnabled() const
@ -119,29 +120,42 @@ void LocalDirectoryUpdater::sweepSharedDirectories()
// now for each of them, go recursively and match both files and dirs
std::set<std::string> existing_dirs ;
for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,mSharedDirectories->root()) ; stored_dir_it;++stored_dir_it)
{
#ifdef DEBUG_LOCAL_DIR_UPDATER
std::cerr << "[directory storage] recursing into " << stored_dir_it.name() << std::endl;
#endif
recursUpdateSharedDir(stored_dir_it.name(), *stored_dir_it) ; // here we need to use the list that was stored, instead of the shared dir list, because the two
recursUpdateSharedDir(stored_dir_it.name(), *stored_dir_it,existing_dirs) ; // here we need to use the list that was stored, instead of the shared dir list, because the two
// are not necessarily in the same order.
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx)
void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx,std::set<std::string>& existing_directories)
{
#ifdef DEBUG_LOCAL_DIR_UPDATER
std::cerr << "[directory storage] parsing directory " << cumulated_path << ", index=" << indx << std::endl;
#endif
if(mFollowSymLinks)
{
std::string real_path = RsDirUtil::removeSymLinks(cumulated_path) ;
if(existing_directories.end() != existing_directories.find(real_path))
{
std::cerr << "(EE) Directory " << cumulated_path << " has real path " << real_path << " which already belongs to another shared directory. Ignoring" << std::endl;
return ;
}
existing_directories.insert(real_path) ;
}
// make sure list of subdirs is the same
// make sure list of subfiles is the same
// request all hashes to the hashcache
librs::util::FolderIterator dirIt(cumulated_path,false,false); // disallow symbolic links and files from the future.
librs::util::FolderIterator dirIt(cumulated_path,mFollowSymLinks,false); // disallow symbolic links and files from the future.
time_t dir_local_mod_time ;
if(!mSharedDirectories->getDirectoryLocalModTime(indx,dir_local_mod_time))
@ -213,7 +227,7 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
#ifdef DEBUG_LOCAL_DIR_UPDATER
std::cerr << " recursing into " << stored_dir_it.name() << std::endl;
#endif
recursUpdateSharedDir(cumulated_path + "/" + stored_dir_it.name(), *stored_dir_it) ;
recursUpdateSharedDir(cumulated_path + "/" + stored_dir_it.name(), *stored_dir_it,existing_directories) ;
}
}
@ -244,6 +258,15 @@ uint32_t LocalDirectoryUpdater::fileWatchPeriod() const
return mDelayBetweenDirectoryUpdates ;
}
void LocalDirectoryUpdater::setFollowSymLinks(bool b)
{
mFollowSymLinks = b ;
}
bool LocalDirectoryUpdater::followSymLinks() const
{
return mFollowSymLinks ;
}

View file

@ -47,6 +47,9 @@ public:
void setFileWatchPeriod(int seconds) ;
uint32_t fileWatchPeriod() const ;
void setFollowSymLinks(bool b) ;
bool followSymLinks() const ;
void setEnabled(bool b) ;
bool isEnabled() const ;
@ -56,7 +59,7 @@ protected:
virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size);
virtual bool hash_confirm(uint32_t client_param) ;
void recursUpdateSharedDir(const std::string& cumulated_path,DirectoryStorage::EntryIndex indx);
void recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx, std::set<std::string>& existing_directories);
void sweepSharedDirectories();
private:
@ -70,5 +73,6 @@ private:
uint32_t mDelayBetweenDirectoryUpdates;
bool mIsEnabled ;
bool mFollowSymLinks;
};

View file

@ -37,6 +37,7 @@ static const uint32_t DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR = 5*24*86400 ;
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 FOLLOW_SYMLINKS_SS = "FOLLOW_SYMLINKS"; // dereference symbolic links, or just ignore them.
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.
@ -53,3 +54,5 @@ static const uint32_t NB_FRIEND_INDEX_BITS = 10 ; // Do not
static const uint32_t NB_ENTRY_INDEX_BITS = 22 ; // Do not change this!
static const uint32_t ENTRY_INDEX_BIT_MASK = 0x003fffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change!
static const uint32_t DELAY_BEFORE_DROP_REQUEST = 600; // every 10 min
static const bool FOLLOW_SYMLINKS_DEFAULT = true;

View file

@ -273,19 +273,22 @@ cleanup = true;
mLocalSharedDirs->getSharedDirectoryList(dirList);
}
for(std::list<SharedDirInfo>::iterator it = dirList.begin(); it != dirList.end(); ++it)
{
RsFileConfigItem *fi = new RsFileConfigItem();
{
RS_STACK_MUTEX(mFLSMtx) ;
for(std::list<SharedDirInfo>::iterator it = dirList.begin(); it != dirList.end(); ++it)
{
RsFileConfigItem *fi = new RsFileConfigItem();
fi->file.path = (*it).filename ;
fi->file.name = (*it).virtualname ;
fi->flags = (*it).shareflags.toUInt32() ;
fi->file.path = (*it).filename ;
fi->file.name = (*it).virtualname ;
fi->flags = (*it).shareflags.toUInt32() ;
for(std::list<RsNodeGroupId>::const_iterator it2( (*it).parent_groups.begin());it2!=(*it).parent_groups.end();++it2)
fi->parent_groups.ids.insert(*it2) ;
for(std::list<RsNodeGroupId>::const_iterator it2( (*it).parent_groups.begin());it2!=(*it).parent_groups.end();++it2)
fi->parent_groups.ids.insert(*it2) ;
sList.push_back(fi);
}
sList.push_back(fi);
}
}
RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet();
@ -314,7 +317,14 @@ cleanup = true;
rskv->tlvkvs.pairs.push_back(kv);
}
{
RsTlvKeyValue kv;
kv.key = FOLLOW_SYMLINKS_SS;
kv.value = followSymLinks()?"YES":"NO" ;
rskv->tlvkvs.pairs.push_back(kv);
}
{
RsTlvKeyValue kv;
@ -373,6 +383,10 @@ bool p3FileDatabase::loadList(std::list<RsItem *>& load)
if(sscanf(kit->value.c_str(),"%d",&t) == 1)
setWatchPeriod(t);
}
else if(kit->key == FOLLOW_SYMLINKS_SS)
{
setFollowSymLinks(kit->value == "YES") ;
}
else if(kit->key == WATCH_FILE_ENABLED_SS)
{
setWatchEnabled(kit->value == "YES") ;
@ -891,6 +905,17 @@ bool p3FileDatabase::inDirectoryCheck()
RS_STACK_MUTEX(mFLSMtx) ;
return mLocalDirWatcher->inDirectoryCheck();
}
void p3FileDatabase::setFollowSymLinks(bool b)
{
RS_STACK_MUTEX(mFLSMtx) ;
mLocalDirWatcher->setFollowSymLinks(b) ;
IndicateConfigChanged();
}
bool p3FileDatabase::followSymLinks() const
{
RS_STACK_MUTEX(mFLSMtx) ;
return mLocalDirWatcher->followSymLinks() ;
}
void p3FileDatabase::setWatchEnabled(bool b)
{
RS_STACK_MUTEX(mFLSMtx) ;

View file

@ -138,6 +138,9 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
void setWatchEnabled(bool b) ;
bool watchEnabled() ;
bool followSymLinks() const;
void setFollowSymLinks(bool b) ;
// interfact for directory parsing
void forceDirectoryCheck(); // Force re-sweep the directories and see what's changed