diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rwxr-xr-x | change | 1 | ||||
-rw-r--r-- | src/change_log.cc | 28 | ||||
-rw-r--r-- | src/tracking/change_tracker.cc | 2 | ||||
-rw-r--r-- | src/tracking/path_matcher.cc | 39 | ||||
-rw-r--r-- | src/tracking/path_matcher.h | 22 |
6 files changed, 88 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eef9ff4..be9e91e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ add_library( SHARED src/change_log.cc src/utility/logger.cc + src/tracking/path_matcher.cc src/tracking/change_tracker.cc ) @@ -1,6 +1,7 @@ #!/usr/bin/bash export CHANGE_LOG_TARGET="/tmp/$(basename $0).$$.tmp" +export CHANGE_LOG_IGNORE_PATTERN_PATH=".change_log_ignore" LD_PRELOAD=libChangeLog.so eval "$@" diff --git a/src/change_log.cc b/src/change_log.cc index a00a26f..f1279d2 100644 --- a/src/change_log.cc +++ b/src/change_log.cc @@ -2,6 +2,7 @@ #include "utility/io.h" #include "utility/logger.h" +#include "tracking/path_matcher.h" #include "tracking/change_tracker.h" // `true` signals the interposed functions to execute tracking logic @@ -10,6 +11,7 @@ static bool enabled = false; static std::unique_ptr<utility::FileDescriptorGuard> fd_guard; static std::unique_ptr<utility::Logger> logger; +static std::unique_ptr<tracking::PathMatcher> matcher; static std::unique_ptr<tracking::ChangeTracker> tracker; void init() __attribute__ ((constructor)); @@ -31,6 +33,14 @@ void init() { tracker = std::make_unique<tracking::ChangeTracker>(logger.get()); } + if ( getenv("CHANGE_LOG_IGNORE_PATTERN_PATH") != NULL ) { + matcher = std::make_unique<tracking::PathMatcher>( + getenv("CHANGE_LOG_IGNORE_PATTERN_PATH") + ); + } else { + matcher = std::make_unique<tracking::PathMatcher>(); + } + // tracking is only enabled when everything is initialized as both // the actual tracking and the decision if a event should be tracked // depend on `logger` and `tracker` being fully instantiated. @@ -42,22 +52,32 @@ void init() { inline void track_write(const int fd) { if ( enabled && fd != *fd_guard && utility::is_regular_file(fd) ) { - tracker->track(utility::get_file_path(fd)); + const auto path = utility::get_file_path(fd); + + if ( !matcher->isMatching(path) ) { + tracker->track(path); + } } } inline void track_rename( const std::string& old_path, const std::string& new_path) { if ( enabled ) { - tracker->track(old_path); + if ( !matcher->isMatching(old_path) ) { + tracker->track(old_path); - logger->append("renamed '", old_path, "' to '", new_path, "'"); + if ( !matcher->isMatching(new_path) ) { + logger->append("renamed '", old_path, "' to '", new_path, "'"); + } + } } } inline void track_remove(const std::string& path) { if ( enabled && utility::is_regular_file(path.c_str()) ) { - logger->append("removed '", path, "'"); + if ( !matcher->isMatching(path) ) { + logger->append("removed '", path, "'"); + } } } diff --git a/src/tracking/change_tracker.cc b/src/tracking/change_tracker.cc index df91be0..9eab5a2 100644 --- a/src/tracking/change_tracker.cc +++ b/src/tracking/change_tracker.cc @@ -125,7 +125,7 @@ void ChangeTracker::track(const std::string& file_path) { if ( std::get<EMPLACE_SUCCESS>(result) ) { read_file_to_stream( - full_path, + full_path, std::get<FILE_CONTENT>(*result.first).get() ); } diff --git a/src/tracking/path_matcher.cc b/src/tracking/path_matcher.cc new file mode 100644 index 0000000..e754586 --- /dev/null +++ b/src/tracking/path_matcher.cc @@ -0,0 +1,39 @@ +#include "path_matcher.h" + +#include <algorithm> + +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> + +namespace tracking { + +PathMatcher::PathMatcher(const std::string& source_file_path) { + try { + boost::filesystem::ifstream file(source_file_path); + + if ( file.is_open() ) { + std::string current_line; + + while ( std::getline(file, current_line) ) { + try { + this->patterns_.emplace_back(current_line); + } catch ( const std::regex_error& ) { } + } + } + } catch ( boost::filesystem::filesystem_error& ) { + // invalid source path is not relevant as we can easily fall back to declining + // all candidate paths. + } +} + +bool PathMatcher::isMatching(const std::string& candidate) const { + return std::any_of( + this->patterns_.begin(), + this->patterns_.end(), + [&candidate](const std::regex& pattern) -> bool { + return std::regex_match(candidate, pattern); + } + ); +} + +} diff --git a/src/tracking/path_matcher.h b/src/tracking/path_matcher.h new file mode 100644 index 0000000..64337c0 --- /dev/null +++ b/src/tracking/path_matcher.h @@ -0,0 +1,22 @@ +#ifndef CHANGE_SRC_TRACKING_PATH_MATCHER_H_ +#define CHANGE_SRC_TRACKING_PATH_MATCHER_H_ + +#include <regex> +#include <vector> + +namespace tracking { + +class PathMatcher { + public: + PathMatcher() = default; + PathMatcher(const std::string&); + + bool isMatching(const std::string&) const; + + private: + std::vector<std::regex> patterns_; +}; + +} + +#endif // CHANGE_SRC_TRACKING_PATH_MATCHER_H_ |