diff options
Diffstat (limited to 'lib/common/ExcludeList.cpp')
-rw-r--r-- | lib/common/ExcludeList.cpp | 117 |
1 files changed, 100 insertions, 17 deletions
diff --git a/lib/common/ExcludeList.cpp b/lib/common/ExcludeList.cpp index 17026c6c..70a2243a 100644 --- a/lib/common/ExcludeList.cpp +++ b/lib/common/ExcludeList.cpp @@ -1,4 +1,4 @@ -// distribution boxbackup-0.10 (svn version: 494) +// distribution boxbackup-0.11rc1 (svn version: 2023_2024) // // Copyright (c) 2003 - 2006 // Ben Summers and contributors. All rights reserved. @@ -47,8 +47,12 @@ #include "Box.h" -#ifdef HAVE_REGEX_H - #include <regex.h> +#ifdef HAVE_REGEX_SUPPORT + #ifdef HAVE_PCREPOSIX_H + #include <pcreposix.h> + #else + #include <regex.h> + #endif #define EXCLUDELIST_IMPLEMENTATION_REGEX_T_DEFINED #endif @@ -56,6 +60,7 @@ #include "Utils.h" #include "Configuration.h" #include "Archive.h" +#include "Logging.h" #include "MemLeakFindOn.h" @@ -83,7 +88,7 @@ ExcludeList::ExcludeList() // -------------------------------------------------------------------------- ExcludeList::~ExcludeList() { -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT // free regex memory while(mRegex.size() > 0) { @@ -103,6 +108,45 @@ ExcludeList::~ExcludeList() } } +#ifdef WIN32 +std::string ExcludeList::ReplaceSlashesDefinite(const std::string& input) const +{ + std::string output = input; + + for (std::string::size_type pos = output.find("/"); + pos != std::string::npos; + pos = output.find("/")) + { + output.replace(pos, 1, DIRECTORY_SEPARATOR); + } + + for (std::string::iterator i = output.begin(); i != output.end(); i++) + { + *i = tolower(*i); + } + + return output; +} + +std::string ExcludeList::ReplaceSlashesRegex(const std::string& input) const +{ + std::string output = input; + + for (std::string::size_type pos = output.find("/"); + pos != std::string::npos; + pos = output.find("/")) + { + output.replace(pos, 1, "\\" DIRECTORY_SEPARATOR); + } + + for (std::string::iterator i = output.begin(); i != output.end(); i++) + { + *i = tolower(*i); + } + + return output; +} +#endif // -------------------------------------------------------------------------- // @@ -126,7 +170,24 @@ void ExcludeList::AddDefiniteEntries(const std::string &rEntries) { if(i->size() > 0) { - mDefinite.insert(*i); + std::string entry = *i; + + // Convert any forward slashes in the string + // to backslashes + + #ifdef WIN32 + entry = ReplaceSlashesDefinite(entry); + #endif + + if (entry.size() > 0 && entry[entry.size() - 1] == + DIRECTORY_SEPARATOR_ASCHAR) + { + BOX_WARNING("Exclude entry ends in path " + "separator, will never match: " + << entry); + } + + mDefinite.insert(entry); } } } @@ -145,7 +206,7 @@ void ExcludeList::AddDefiniteEntries(const std::string &rEntries) // -------------------------------------------------------------------------- void ExcludeList::AddRegexEntries(const std::string &rEntries) { -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT // Split strings up std::vector<std::string> ens; @@ -161,16 +222,32 @@ void ExcludeList::AddRegexEntries(const std::string &rEntries) try { + std::string entry = *i; + + // Convert any forward slashes in the string + // to appropriately escaped backslashes + + #ifdef WIN32 + entry = ReplaceSlashesRegex(entry); + #endif + // Compile - if(::regcomp(pregex, i->c_str(), REG_EXTENDED | REG_NOSUB) != 0) + int errcode = ::regcomp(pregex, entry.c_str(), + REG_EXTENDED | REG_NOSUB); + + if (errcode != 0) { + char buf[1024]; + regerror(errcode, pregex, buf, sizeof(buf)); + BOX_ERROR("Invalid regular expression: " << + entry << ": " << buf); THROW_EXCEPTION(CommonException, BadRegularExpression) } // Store in list of regular expressions mRegex.push_back(pregex); // Store in list of regular expression string for Serialize - mRegexStr.push_back(i->c_str()); + mRegexStr.push_back(entry.c_str()); } catch(...) { @@ -196,10 +273,16 @@ void ExcludeList::AddRegexEntries(const std::string &rEntries) // -------------------------------------------------------------------------- bool ExcludeList::IsExcluded(const std::string &rTest) const { + std::string test = rTest; + + #ifdef WIN32 + test = ReplaceSlashesDefinite(test); + #endif + // Check against the always include list if(mpAlwaysInclude != 0) { - if(mpAlwaysInclude->IsExcluded(rTest)) + if(mpAlwaysInclude->IsExcluded(test)) { // Because the "always include" list says it's 'excluded' // this means it should actually be included. @@ -208,17 +291,17 @@ bool ExcludeList::IsExcluded(const std::string &rTest) const } // Is it in the set of definite entries? - if(mDefinite.find(rTest) != mDefinite.end()) + if(mDefinite.find(test) != mDefinite.end()) { return true; } // Check against regular expressions -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT for(std::vector<regex_t *>::const_iterator i(mRegex.begin()); i != mRegex.end(); ++i) { // Test against this expression - if(regexec(*i, rTest.c_str(), 0, 0 /* no match information required */, 0 /* no flags */) == 0) + if(regexec(*i, test.c_str(), 0, 0 /* no match information required */, 0 /* no flags */) == 0) { // match happened return true; @@ -270,7 +353,7 @@ void ExcludeList::Deserialize(Archive & rArchive) // mDefinite.clear(); -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT // free regex memory while(mRegex.size() > 0) { @@ -311,7 +394,7 @@ void ExcludeList::Deserialize(Archive & rArchive) // // // -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT rArchive.Read(iCount); if (iCount > 0) @@ -348,7 +431,7 @@ void ExcludeList::Deserialize(Archive & rArchive) } } } -#endif // HAVE_REGEX_H +#endif // HAVE_REGEX_SUPPORT // // @@ -403,7 +486,7 @@ void ExcludeList::Serialize(Archive & rArchive) const // // // -#ifdef HAVE_REGEX_H +#ifdef HAVE_REGEX_SUPPORT // don't even try to save compiled regular expressions, // use string copies instead. ASSERT(mRegex.size() == mRegexStr.size()); @@ -416,7 +499,7 @@ void ExcludeList::Serialize(Archive & rArchive) const { rArchive.Write(*i); } -#endif // HAVE_REGEX_H +#endif // HAVE_REGEX_SUPPORT // // |