urbackup_backend/urbackupclient/watchdir/ContinuousWatchEnqueue.cpp

410 lines
9.4 KiB
C++

#include "ContinuousWatchEnqueue.h"
#include "../../Interface/Server.h"
#include <algorithm>
#include "../../stringtools.h"
#include "../ClientService.h"
#include <memory>
#include "../../Interface/SettingsReader.h"
#include "../../urbackupserver/database.h"
ContinuousWatchEnqueue::ContinuousWatchEnqueue()
: update_patterns(true)
{
}
void ContinuousWatchEnqueue::On_FileNameChanged( const std::string & strOldFileName, const std::string & strNewFileName, bool closed )
{
if(!closed)
return;
std::vector<std::pair<std::string, std::string> > dirs =
getWatchDirs(strOldFileName, strNewFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(!dirs[i].first.empty()
&& !dirs[i].second.empty()
&& pathIncluded(strOldFileName, dirs[i].first)
&& pathIncluded(strNewFileName, dirs[i].second) )
{
On_FileNameChangedInt(dirs[i].first, dirs[i].second);
}
else if(!dirs[i].first.empty()
&& pathIncluded(strOldFileName, dirs[i].first) )
{
On_FileRemovedInt(dirs[i].first);
}
else if(!dirs[i].second.empty()
&& pathIncluded(strNewFileName, dirs[i].second) )
{
On_FileAddedInt(dirs[i].second);
}
}
}
void ContinuousWatchEnqueue::On_DirNameChanged( const std::string & strOldFileName, const std::string & strNewFileName, bool closed )
{
if(!closed)
return;
std::vector<std::pair<std::string, std::string> > dirs =
getWatchDirs(strOldFileName, strNewFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(!dirs[i].first.empty()
&& !dirs[i].second.empty()
&& pathIncluded(strOldFileName, dirs[i].first)
&& pathIncluded(strNewFileName, dirs[i].second) )
{
On_DirNameChangedInt(dirs[i].first, dirs[i].second);
}
else if(!dirs[i].first.empty()
&& pathIncluded(strOldFileName, dirs[i].first) )
{
On_DirRemovedInt(dirs[i].first);
}
else if(!dirs[i].second.empty()
&& pathIncluded(strNewFileName, dirs[i].second) )
{
On_DirAddedInt(dirs[i].second);
}
}
}
void ContinuousWatchEnqueue::On_FileRemoved( const std::string & strFileName, bool closed )
{
if(!closed)
return;
std::vector<std::string> dirs =
getWatchDirs(strFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(pathIncluded(strFileName, dirs[i]))
{
On_FileRemovedInt(dirs[i]);
}
}
}
void ContinuousWatchEnqueue::On_FileAdded( const std::string & strFileName, bool closed )
{
if(!closed)
return;
std::vector<std::string> dirs =
getWatchDirs(strFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(pathIncluded(strFileName, dirs[i]))
{
On_FileAddedInt(dirs[i]);
}
}
}
void ContinuousWatchEnqueue::On_DirAdded( const std::string & strFileName, bool closed )
{
if(!closed)
return;
std::vector<std::string> dirs =
getWatchDirs(strFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(pathIncluded(strFileName, dirs[i]))
{
On_DirAddedInt(dirs[i]);
}
}
}
void ContinuousWatchEnqueue::On_FileModified( const std::string & strFileName, bool closed )
{
if(!closed)
return;
std::vector<std::string> dirs =
getWatchDirs(strFileName);
for(size_t i=0;i<dirs.size();++i)
{
if(pathIncluded(strFileName, dirs[i]))
{
On_FileModifiedInt(dirs[i]);
}
}
}
void ContinuousWatchEnqueue::On_ResetAll( const std::string & vol )
{
On_ResetAllInt(vol);
}
void ContinuousWatchEnqueue::On_DirRemoved( const std::string & strDirName, bool closed )
{
if(!closed)
return;
std::vector<std::string> dirs =
getWatchDirs(strDirName);
for(size_t i=0;i<dirs.size();++i)
{
if(pathIncluded(strDirName, dirs[i]))
{
On_DirRemovedInt(dirs[i]);
}
}
}
void ContinuousWatchEnqueue::Commit(const std::vector<IChangeJournalListener::SSequence>& sequences)
{
if(queue.getDataSize()==0)
return;
std::string data(queue.getDataPtr(), queue.getDataPtr()+queue.getDataSize());
CWData header;
header.addChar(CHANGE_HEADER);
header.addUInt(static_cast<unsigned int>(sequences.size()));
for(size_t i=0;i<sequences.size();++i)
{
header.addInt64(sequences[i].id);
std::map<int64, int64>::iterator seq_start_it = sequences_start.find(sequences[i].id);
if(seq_start_it!=sequences_start.end())
{
header.addInt64(seq_start_it->second);
}
else
{
continue;
}
header.addInt64(sequences[i].stop);
sequences_start[sequences[i].id]=sequences[i].stop;
}
data.insert(data.begin(), header.getDataPtr(), header.getDataPtr()+header.getDataSize());
if(ClientConnector::tochannelSendChanges(data.data(), data.size()))
{
queue.clear();
}
}
void ContinuousWatchEnqueue::addWatchdir( SWatchItem item )
{
item.dir = strlower(item.dir);
std::vector<SWatchItem>::iterator iter=std::find(watchdirs.begin(),
watchdirs.end(), item);
if(iter==watchdirs.end())
{
watchdirs.push_back(item);
On_ResetAllInt(item.dir);
}
}
void ContinuousWatchEnqueue::removeWatchdir( SWatchItem item )
{
item.dir = strlower(item.dir);
std::vector<SWatchItem>::iterator iter=std::find(watchdirs.begin(),
watchdirs.end(), item);
if(iter!=watchdirs.end())
{
watchdirs.erase(iter);
On_ResetAllInt(item.dir);
}
}
std::vector<std::string> ContinuousWatchEnqueue::getWatchDirs( const std::string& fn )
{
std::string fn_lower = strlower(fn);
std::vector<std::string> dirs;
for(size_t i=0;i<watchdirs.size();++i)
{
if(next(fn_lower, 0, watchdirs[i].dir))
{
std::string fn_sub = fn.substr(watchdirs[i].dir.size());
dirs.push_back(watchdirs[i].name+fn_sub);
}
}
return dirs;
}
std::vector<std::pair<std::string, std::string> > ContinuousWatchEnqueue::getWatchDirs( const std::string& fn1, const std::string& fn2 )
{
std::string fn1_lower = strlower(fn1);
std::string fn2_lower = strlower(fn1);
std::vector<std::pair<std::string, std::string> > dirs;
for(size_t i=0;i<watchdirs.size();++i)
{
bool fn1_ins = next(fn1_lower, 0, watchdirs[i].dir);
bool fn2_ins = next(fn2_lower, 0, watchdirs[i].dir);
std::string fn1_sub;
if(fn1_ins)
{
fn1_sub = watchdirs[i].name+fn1.substr(watchdirs[i].dir.size());
}
std::string fn2_sub;
if(fn2_ins)
{
fn2_sub = watchdirs[i].name+fn2.substr(watchdirs[i].dir.size());
}
dirs.push_back(std::make_pair(fn1_sub, fn2_sub));
}
return dirs;
}
void ContinuousWatchEnqueue::On_FileNameChangedInt( const std::string & strOldFileName, const std::string & strNewFileName )
{
queue.addChar(CHANGE_REN_FILE);
queue.addString((strOldFileName));
queue.addString((strNewFileName));
}
void ContinuousWatchEnqueue::On_DirNameChangedInt( const std::string & strOldFileName, const std::string & strNewFileName )
{
queue.addChar(CHANGE_REN_DIR);
queue.addString((strOldFileName));
queue.addString((strNewFileName));
}
void ContinuousWatchEnqueue::On_FileRemovedInt( const std::string & strFileName )
{
queue.addChar(CHANGE_DEL_FILE);
queue.addString((strFileName));
}
void ContinuousWatchEnqueue::On_FileAddedInt( const std::string & strFileName )
{
queue.addChar(CHANGE_ADD_FILE);
queue.addString((strFileName));
}
void ContinuousWatchEnqueue::On_DirAddedInt( const std::string & strFileName )
{
queue.addChar(CHANGE_ADD_DIR);
queue.addString((strFileName));
}
void ContinuousWatchEnqueue::On_FileModifiedInt( const std::string & strFileName )
{
queue.addChar(CHANGE_MOD);
queue.addString((strFileName));
}
void ContinuousWatchEnqueue::On_ResetAllInt( const std::string & vol )
{
queue.addChar(CHANGE_MOD_ALL);
queue.addString((vol));
}
void ContinuousWatchEnqueue::On_DirRemovedInt( const std::string & strDirName )
{
readIncludeExcludePatterns();
queue.addChar(CHANGE_DEL_DIR);
queue.addString((strDirName));
}
void ContinuousWatchEnqueue::readIncludeExcludePatterns()
{
if(!update_patterns)
return;
update_patterns=false;
std::unique_ptr<ISettingsReader> curr_settings(Server->createFileSettingsReader("urbackup/data/settings.cfg"));
if(curr_settings.get())
{
std::string val;
if(curr_settings->getValue("continuous_exclude_files", &val)
|| curr_settings->getValue("continuous_exclude_files_def", &val) )
{
exclude_dirs = IndexThread::buildExcludeList(val);
}
else
{
exclude_dirs = IndexThread::buildExcludeList(std::string());
}
if(curr_settings->getValue("continuous_include_files", &val)
|| curr_settings->getValue("continuous_include_files_def", &val) )
{
include_dirs = IndexThread::parseIncludePatterns(val);
}
}
else
{
IndexThread::buildExcludeList(std::string());
}
}
bool ContinuousWatchEnqueue::pathIncluded( const std::string& path, const std::string& named_path )
{
if( IndexThread::isExcluded(exclude_dirs, path)
|| IndexThread::isExcluded(exclude_dirs, named_path) )
{
return false;
}
if( !IndexThread::isIncluded(include_dirs, path, NULL)
&& !IndexThread::isIncluded(include_dirs, named_path, NULL) )
{
return false;
}
return true;
}
void ContinuousWatchEnqueue::setupDatabaseAccess()
{
if(journal_dao.get()==NULL)
{
journal_dao.reset(new JournalDAO(Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER)));
}
}
int64 ContinuousWatchEnqueue::getStartUsn( int64 sequence_id )
{
return sequences_start[sequence_id];
}
void ContinuousWatchEnqueue::setStartUsn( int64 sequence_id, int64 seq_start )
{
sequences_start[sequence_id]=seq_start;
}
void ContinuousWatchEnqueue::On_FileOpen( const std::string & strFileName )
{
}