From d6d051037752ac3b2e844a3645186bd09260bb9c Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Tue, 25 Aug 2020 18:53:42 +0300 Subject: [PATCH 01/16] Xcode progect was added. --- loggedfs.entitlements | 5 + loggedfs.xcodeproj/project.pbxproj | 355 ++++++++++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/loggedfs.xcscheme | 100 +++++ 4 files changed, 468 insertions(+) create mode 100644 loggedfs.entitlements create mode 100644 loggedfs.xcodeproj/project.pbxproj create mode 100644 loggedfs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme diff --git a/loggedfs.entitlements b/loggedfs.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/loggedfs.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/loggedfs.xcodeproj/project.pbxproj b/loggedfs.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b75e426 --- /dev/null +++ b/loggedfs.xcodeproj/project.pbxproj @@ -0,0 +1,355 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + DA690C3424F5635E00BFE910 /* easylogging++.cc in Sources */ = {isa = PBXBuildFile; fileRef = DA690C3324F5635E00BFE910 /* easylogging++.cc */; }; + DA690C3724F564BB00BFE910 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA690C3624F564BB00BFE910 /* libxml2.tbd */; }; + DACAD53924F53B4600BDB0FF /* Config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53424F53B4600BDB0FF /* Config.cpp */; }; + DACAD53A24F53B4600BDB0FF /* loggedfs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53524F53B4600BDB0FF /* loggedfs.cpp */; }; + DACAD53B24F53B4600BDB0FF /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53624F53B4600BDB0FF /* Filter.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + DA690C3224F5635E00BFE910 /* easylogging++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "easylogging++.h"; sourceTree = ""; }; + DA690C3324F5635E00BFE910 /* easylogging++.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "easylogging++.cc"; sourceTree = ""; }; + DA690C3624F564BB00BFE910 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; + DA690C3824F5655A00BFE910 /* loggedfs.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = loggedfs.entitlements; sourceTree = ""; }; + DACAD52924F53AF700BDB0FF /* loggedfs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = loggedfs; sourceTree = BUILT_PRODUCTS_DIR; }; + DACAD53424F53B4600BDB0FF /* Config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Config.cpp; sourceTree = ""; }; + DACAD53524F53B4600BDB0FF /* loggedfs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loggedfs.cpp; sourceTree = ""; }; + DACAD53624F53B4600BDB0FF /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = ""; }; + DACAD53724F53B4600BDB0FF /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; + DACAD53824F53B4600BDB0FF /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DACAD52624F53AF700BDB0FF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DA690C3724F564BB00BFE910 /* libxml2.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + DA690C3124F5634B00BFE910 /* src */ = { + isa = PBXGroup; + children = ( + DA690C3324F5635E00BFE910 /* easylogging++.cc */, + DA690C3224F5635E00BFE910 /* easylogging++.h */, + ); + path = src; + sourceTree = ""; + }; + DA690C3524F564BA00BFE910 /* Frameworks */ = { + isa = PBXGroup; + children = ( + DA690C3624F564BB00BFE910 /* libxml2.tbd */, + ); + name = Frameworks; + sourceTree = ""; + }; + DACAD52024F53AF700BDB0FF = { + isa = PBXGroup; + children = ( + DA690C3824F5655A00BFE910 /* loggedfs.entitlements */, + DACAD53C24F53B4D00BDB0FF /* vendor */, + DACAD53324F53B2900BDB0FF /* src */, + DACAD52A24F53AF700BDB0FF /* Products */, + DA690C3524F564BA00BFE910 /* Frameworks */, + ); + sourceTree = ""; + }; + DACAD52A24F53AF700BDB0FF /* Products */ = { + isa = PBXGroup; + children = ( + DACAD52924F53AF700BDB0FF /* loggedfs */, + ); + name = Products; + sourceTree = ""; + }; + DACAD53324F53B2900BDB0FF /* src */ = { + isa = PBXGroup; + children = ( + DACAD53424F53B4600BDB0FF /* Config.cpp */, + DACAD53724F53B4600BDB0FF /* Config.h */, + DACAD53624F53B4600BDB0FF /* Filter.cpp */, + DACAD53824F53B4600BDB0FF /* Filter.h */, + DACAD53524F53B4600BDB0FF /* loggedfs.cpp */, + ); + path = src; + sourceTree = ""; + }; + DACAD53C24F53B4D00BDB0FF /* vendor */ = { + isa = PBXGroup; + children = ( + DACAD53D24F53B6200BDB0FF /* github.com */, + ); + path = vendor; + sourceTree = ""; + }; + DACAD53D24F53B6200BDB0FF /* github.com */ = { + isa = PBXGroup; + children = ( + DACAD53E24F53B7500BDB0FF /* muflihun */, + ); + path = github.com; + sourceTree = ""; + }; + DACAD53E24F53B7500BDB0FF /* muflihun */ = { + isa = PBXGroup; + children = ( + DACAD53F24F53B8B00BDB0FF /* easyloggingpp */, + ); + path = muflihun; + sourceTree = ""; + }; + DACAD53F24F53B8B00BDB0FF /* easyloggingpp */ = { + isa = PBXGroup; + children = ( + DA690C3124F5634B00BFE910 /* src */, + ); + path = easyloggingpp; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DACAD52824F53AF700BDB0FF /* loggedfs */ = { + isa = PBXNativeTarget; + buildConfigurationList = DACAD53024F53AF700BDB0FF /* Build configuration list for PBXNativeTarget "loggedfs" */; + buildPhases = ( + DACAD52524F53AF700BDB0FF /* Sources */, + DACAD52624F53AF700BDB0FF /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = loggedfs; + productName = loggedfs; + productReference = DACAD52924F53AF700BDB0FF /* loggedfs */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DACAD52124F53AF700BDB0FF /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1160; + ORGANIZATIONNAME = DanilKorotenko; + TargetAttributes = { + DACAD52824F53AF700BDB0FF = { + CreatedOnToolsVersion = 11.6; + }; + }; + }; + buildConfigurationList = DACAD52424F53AF700BDB0FF /* Build configuration list for PBXProject "loggedfs" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DACAD52024F53AF700BDB0FF; + productRefGroup = DACAD52A24F53AF700BDB0FF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DACAD52824F53AF700BDB0FF /* loggedfs */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + DACAD52524F53AF700BDB0FF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DACAD53A24F53B4600BDB0FF /* loggedfs.cpp in Sources */, + DACAD53B24F53B4600BDB0FF /* Filter.cpp in Sources */, + DACAD53924F53B4600BDB0FF /* Config.cpp in Sources */, + DA690C3424F5635E00BFE910 /* easylogging++.cc in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + DACAD52E24F53AF700BDB0FF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "_FILE_OFFSET_BITS=64", + "FUSE_USE_VERSION=26", + ELPP_NO_DEFAULT_LOG_FILE, + ELPP_THREAD_SAFE, + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + DACAD52F24F53AF700BDB0FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + }; + name = Release; + }; + DACAD53124F53AF700BDB0FF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = loggedfs.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XS293XGL58; + ENABLE_HARDENED_RUNTIME = NO; + HEADER_SEARCH_PATHS = /usr/local/include/osxfuse; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + OTHER_LDFLAGS = "-losxfuse"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/vendor/github.com/muflihun/easyloggingpp/src"; + }; + name = Debug; + }; + DACAD53224F53AF700BDB0FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = loggedfs.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XS293XGL58; + ENABLE_HARDENED_RUNTIME = NO; + HEADER_SEARCH_PATHS = /usr/local/include/osxfuse; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + OTHER_LDFLAGS = "-losxfuse"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/vendor/github.com/muflihun/easyloggingpp/src"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DACAD52424F53AF700BDB0FF /* Build configuration list for PBXProject "loggedfs" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DACAD52E24F53AF700BDB0FF /* Debug */, + DACAD52F24F53AF700BDB0FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DACAD53024F53AF700BDB0FF /* Build configuration list for PBXNativeTarget "loggedfs" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DACAD53124F53AF700BDB0FF /* Debug */, + DACAD53224F53AF700BDB0FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DACAD52124F53AF700BDB0FF /* Project object */; +} diff --git a/loggedfs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/loggedfs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/loggedfs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme b/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme new file mode 100644 index 0000000..0956a96 --- /dev/null +++ b/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f899d805709bfbb497ef59189675575e8c434bcf Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Tue, 25 Aug 2020 18:54:33 +0300 Subject: [PATCH 02/16] Reworked Filter.cpp to use std::regex. --- src/Filter.cpp | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/src/Filter.cpp b/src/Filter.cpp index 6984973..48e8ed5 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -22,7 +22,7 @@ * */ #include "Filter.h" -#include +#include #define OVECCOUNT 30 @@ -37,43 +37,15 @@ Filter::~Filter() bool Filter::matches( const char* str,const char* pattern) { - pcre *re; - const char *error; - int ovector[OVECCOUNT]; - int erroffset; + std::regex re(pattern); + std::smatch match; - re = pcre_compile( - pattern, - 0, - &error, - &erroffset, - NULL); + std::string strstr(str); - - if (re == NULL) - { - printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); - return false; - } - - int rc = pcre_exec( - re, /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - str, /* the subject string */ - strlen(str), /* the length of the subject */ - 0, /* start at offset 0 in the subject */ - 0, /* default options */ - ovector, /* output vector for substring information */ - OVECCOUNT); /* number of elements in the output vector */ - - pcre_free(re); - return (rc >= 0); + return std::regex_match(strstr, match, re); } - - - bool Filter::matches(const char* path,int uid, const char *action, const char* retname) { bool a= (matches(path,this->extension) && (uid==this->uid || this->uid==-1) && matches(action,this->action) && matches(retname,this->retname)); From 916032d6548ab3443b07beccaa6fe3fc98b108fb Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Tue, 25 Aug 2020 18:56:52 +0300 Subject: [PATCH 03/16] Excluded sys/statfs.h because it is absent on osx. --- src/loggedfs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index 55a2dc6..ad362f2 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -34,7 +34,9 @@ #include #include #include +#ifdef _linux #include +#endif #ifdef HAVE_SETXATTR #include #endif @@ -854,7 +856,6 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) int main(int argc, char *argv[]) { - el::Configurations defaultConf; defaultConf.setToDefault(); defaultConf.setGlobally(el::ConfigurationType::ToFile, std::string("false")); From 7cd0580fff851895e463ae1a58e2c4bd9174fac2 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Tue, 25 Aug 2020 18:57:22 +0300 Subject: [PATCH 04/16] "nonempty" parameter is not supported on osx. --- src/loggedfs.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index ad362f2..9a91a55 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -765,7 +765,11 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) // logging the ~/.kde/share/config directory, in which hard links for lock // files are verified by their inode equivalency. +#ifdef _linux #define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" +#else +#define COMMON_OPTS "use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" +#endif while ((res = getopt(argc, argv, "hpfec:l:")) != -1) { From 3b6fba509799259e6a81ab96dc51200915d20bec Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 11:42:51 +0300 Subject: [PATCH 05/16] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 90dfe6b..0207804 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/rflament/loggedfs.svg?branch=feature%2Feasylogging%2B%2B)](https://travis-ci.org/rflament/loggedfs) Donate Ethereum: 0x83FBC94FBca4e2f10Bede63e16C5b0Bb31a1Fed1 +For OSX version: 0x3dF505eC53620Df8F0bc1895bcBF53a990BEc7Bb ## Description From 86000cfcc9f118512345b61bb21758227868a83a Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 11:43:23 +0300 Subject: [PATCH 06/16] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0207804..7b3e629 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/rflament/loggedfs.svg?branch=feature%2Feasylogging%2B%2B)](https://travis-ci.org/rflament/loggedfs) Donate Ethereum: 0x83FBC94FBca4e2f10Bede63e16C5b0Bb31a1Fed1 + For OSX version: 0x3dF505eC53620Df8F0bc1895bcBF53a990BEc7Bb ## Description From 9c106c3e25343d0d584e9065b5d01782e44122b4 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 12:06:36 +0300 Subject: [PATCH 07/16] Define was edited as it is already above. --- src/loggedfs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index 9a91a55..0c30eb9 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -34,7 +34,7 @@ #include #include #include -#ifdef _linux +#ifdef linux #include #endif #ifdef HAVE_SETXATTR @@ -765,7 +765,7 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) // logging the ~/.kde/share/config directory, in which hard links for lock // files are verified by their inode equivalency. -#ifdef _linux +#ifdef linux #define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" #else #define COMMON_OPTS "use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" From e1404d374084bf9d53d9c993a72a4c4f6d04b0dd Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 12:06:58 +0300 Subject: [PATCH 08/16] Readme file added to the osx project. --- loggedfs.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/loggedfs.xcodeproj/project.pbxproj b/loggedfs.xcodeproj/project.pbxproj index b75e426..095d8f8 100644 --- a/loggedfs.xcodeproj/project.pbxproj +++ b/loggedfs.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ DA690C3324F5635E00BFE910 /* easylogging++.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "easylogging++.cc"; sourceTree = ""; }; DA690C3624F564BB00BFE910 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; DA690C3824F5655A00BFE910 /* loggedfs.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = loggedfs.entitlements; sourceTree = ""; }; + DA690C3924F5704F00BFE910 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; DACAD52924F53AF700BDB0FF /* loggedfs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = loggedfs; sourceTree = BUILT_PRODUCTS_DIR; }; DACAD53424F53B4600BDB0FF /* Config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Config.cpp; sourceTree = ""; }; DACAD53524F53B4600BDB0FF /* loggedfs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loggedfs.cpp; sourceTree = ""; }; @@ -59,6 +60,7 @@ DACAD52024F53AF700BDB0FF = { isa = PBXGroup; children = ( + DA690C3924F5704F00BFE910 /* README.md */, DA690C3824F5655A00BFE910 /* loggedfs.entitlements */, DACAD53C24F53B4D00BDB0FF /* vendor */, DACAD53324F53B2900BDB0FF /* src */, From ce3e1af5694774dd4305da29bc097e742c4fa223 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 12:40:45 +0300 Subject: [PATCH 09/16] A comment was added about nonempty option. --- src/loggedfs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index 0c30eb9..b536e08 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -760,6 +760,8 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) // We need the "nonempty" option to mount the directory in recent FUSE's // because it's non empty and contains the files that will be logged. // + // "nonempty" is linux-only option + // // We need "use_ino" so the files will use their original inode numbers, // instead of all getting 0xFFFFFFFF . For example, this is required for // logging the ~/.kde/share/config directory, in which hard links for lock From c4a3ac49b9126a671dc40c86cbe3b7102cf7d19c Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Wed, 26 Aug 2020 13:19:31 +0300 Subject: [PATCH 10/16] Scheme arguments and debug option was added. --- .../xcshareddata/xcschemes/loggedfs.xcscheme | 10 +++++++++- src/loggedfs.cpp | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme b/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme index 0956a96..e094606 100644 --- a/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme +++ b/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme @@ -65,11 +65,19 @@ + + + + + isEnabled = "NO"> diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index b536e08..29a2023 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -656,6 +656,7 @@ static int loggedFS_statfs(const char *orig_path, struct statvfs *stbuf) int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); + res = statvfs(path, stbuf); loggedfs_log(aPath, "statfs", res, "statfs %s", aPath); delete[] aPath; @@ -770,7 +771,7 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) #ifdef linux #define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" #else -#define COMMON_OPTS "use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" +#define COMMON_OPTS "debug,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" #endif while ((res = getopt(argc, argv, "hpfec:l:")) != -1) @@ -915,7 +916,6 @@ int main(int argc, char *argv[]) if (processArgs(argc, argv, loggedfsArgs)) { - if (loggedfsArgs->isDaemon) { dispatchAction = el::base::DispatchAction::SysLog; @@ -961,5 +961,8 @@ int main(int argc, char *argv[]) #endif defaultLogger->info("LoggedFS closing."); + + + } } From 04e8bc9dba4b8b99e9fc0b5d8ed57e57f481ece7 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Thu, 8 Apr 2021 10:48:42 +0300 Subject: [PATCH 11/16] Fixed review issues. --- .../xcshareddata/xcschemes/loggedfs.xcscheme | 108 ------------------ src/loggedfs.cpp | 2 +- 2 files changed, 1 insertion(+), 109 deletions(-) delete mode 100644 loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme diff --git a/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme b/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme deleted file mode 100644 index e094606..0000000 --- a/loggedfs.xcodeproj/xcshareddata/xcschemes/loggedfs.xcscheme +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/loggedfs.cpp b/src/loggedfs.cpp index 29a2023..e14851e 100644 --- a/src/loggedfs.cpp +++ b/src/loggedfs.cpp @@ -771,7 +771,7 @@ static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) #ifdef linux #define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" #else -#define COMMON_OPTS "debug,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" +#define COMMON_OPTS "use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" #endif while ((res = getopt(argc, argv, "hpfec:l:")) != -1) From 8df9af7530aab1b4e1dc9a43cbe0cd64b8aa4348 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Thu, 8 Apr 2021 11:17:18 +0300 Subject: [PATCH 12/16] Added osx implementation. --- README.md | 19 + loggedfs.xcodeproj/project.pbxproj | 6 +- src/loggedfs_osx.cpp | 998 +++++++++++++++++++++++++++++ 3 files changed, 1021 insertions(+), 2 deletions(-) create mode 100644 src/loggedfs_osx.cpp diff --git a/README.md b/README.md index 7b3e629..5ef56e8 100644 --- a/README.md +++ b/README.md @@ -112,4 +112,23 @@ If you have a configuration file to use you should use this command : If you want to log what other users do on your filesystem, you should use the -p option to allow them to see your mounted files. For a complete documentation see the manual page +## About OSX implementation + +The main implementation of loggedfs is working with the one path specified in arguments. +It mounts the fuse volume to the path specified and intercepts operations by splitting pathes +to realPath and absolutePath. + +On OSX, all volumes should be mounted to /Volumes directory. + +Only root can mount to the other directory. But if you mount fuse volume as root, the regular +user will not have access to it. So this way is not appropriate. + +That is why OSX version is needed to deal with two pathes: the one where is fuse volume +mounted (/Volumes/LoggedFS), and the one specified in program arguments. + + + + Rémi Flament - remipouak at gmail.com + +OSX imeplementation - Danil Korotenko \ No newline at end of file diff --git a/loggedfs.xcodeproj/project.pbxproj b/loggedfs.xcodeproj/project.pbxproj index 095d8f8..4177afc 100644 --- a/loggedfs.xcodeproj/project.pbxproj +++ b/loggedfs.xcodeproj/project.pbxproj @@ -10,8 +10,8 @@ DA690C3424F5635E00BFE910 /* easylogging++.cc in Sources */ = {isa = PBXBuildFile; fileRef = DA690C3324F5635E00BFE910 /* easylogging++.cc */; }; DA690C3724F564BB00BFE910 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA690C3624F564BB00BFE910 /* libxml2.tbd */; }; DACAD53924F53B4600BDB0FF /* Config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53424F53B4600BDB0FF /* Config.cpp */; }; - DACAD53A24F53B4600BDB0FF /* loggedfs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53524F53B4600BDB0FF /* loggedfs.cpp */; }; DACAD53B24F53B4600BDB0FF /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DACAD53624F53B4600BDB0FF /* Filter.cpp */; }; + DAF7D1F4261EED870035C543 /* loggedfs_osx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DAF7D1F3261EED870035C543 /* loggedfs_osx.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -26,6 +26,7 @@ DACAD53624F53B4600BDB0FF /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = ""; }; DACAD53724F53B4600BDB0FF /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; DACAD53824F53B4600BDB0FF /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; + DAF7D1F3261EED870035C543 /* loggedfs_osx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loggedfs_osx.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +86,7 @@ DACAD53624F53B4600BDB0FF /* Filter.cpp */, DACAD53824F53B4600BDB0FF /* Filter.h */, DACAD53524F53B4600BDB0FF /* loggedfs.cpp */, + DAF7D1F3261EED870035C543 /* loggedfs_osx.cpp */, ); path = src; sourceTree = ""; @@ -177,7 +179,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DACAD53A24F53B4600BDB0FF /* loggedfs.cpp in Sources */, + DAF7D1F4261EED870035C543 /* loggedfs_osx.cpp in Sources */, DACAD53B24F53B4600BDB0FF /* Filter.cpp in Sources */, DACAD53924F53B4600BDB0FF /* Config.cpp in Sources */, DA690C3424F5635E00BFE910 /* easylogging++.cc in Sources */, diff --git a/src/loggedfs_osx.cpp b/src/loggedfs_osx.cpp new file mode 100644 index 0000000..9e58dca --- /dev/null +++ b/src/loggedfs_osx.cpp @@ -0,0 +1,998 @@ +/***************************************************************************** + * Author: Remi Flament + ***************************************************************************** + * Copyright (c) 2005 - 2018, Remi Flament + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#ifdef linux +/* For pread()/pwrite() */ +#define _X_SOURCE 500 +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef linux +#include +#endif +#ifdef HAVE_SETXATTR +#include +#endif +#include "easylogging++.h" +#include +#include +#include +#include +#include +#include "Config.h" +#include +#include + +INITIALIZE_EASYLOGGINGPP + +#define STR(X) #X +#define rAssert(cond) \ + do \ + { \ + if ((cond) == false) \ + { \ + LOG(ERROR) << "Assert failed: " << STR(cond); \ + throw std::runtime_error(STR(cond)); \ + } \ + } while (false) + +#define PUSHARG(ARG) \ + rAssert(out->fuseArgc < MaxFuseArgs); \ + out->fuseArgv[out->fuseArgc++] = ARG + +using namespace std; +static Config config; +static int savefd; +static el::base::DispatchAction dispatchAction = el::base::DispatchAction::NormalLog; +static const char *loggerId = "default"; +static const char *additionalInfoFormat = " {%s} [ pid = %d %s uid = %d ]"; +static el::Logger *defaultLogger; + +const int MaxFuseArgs = 32; +struct LoggedFS_Args +{ + char *realPath; // where to get files + char *mountPoint; // where to mount + char *configFilename; + bool isDaemon; // true == spawn in background, log to syslog + const char *fuseArgv[MaxFuseArgs]; + int fuseArgc; +}; + +static LoggedFS_Args *loggedfsArgs = new LoggedFS_Args; + +static bool isAbsolutePath(const char *fileName) +{ + if (fileName && fileName[0] != '\0' && fileName[0] == '/') + return true; + else + return false; +} + +static char *getRealPath(const char *path) +{ + char *realPath = new char[strlen(path) + strlen(loggedfsArgs->realPath) + 1]; + + strcpy(realPath, loggedfsArgs->realPath); + if (realPath[strlen(realPath) - 1] == '/') + realPath[strlen(realPath) - 1] = '\0'; + strcat(realPath, path); + return realPath; +} + +static char *getFusePath(const char *path) +{ + char *fusePath = new char[strlen(path) + strlen(loggedfsArgs->mountPoint) + 1]; + + strcpy(fusePath, loggedfsArgs->mountPoint); + + if (fusePath[strlen(fusePath) - 1] == '/') + { + fusePath[strlen(fusePath) - 1] = '\0'; + } + + strcat(fusePath, path); + return fusePath; +} + +/* + * Returns the name of the process which accessed the file system. + */ +static char *getcallername() +{ + char filename[100]; + sprintf(filename, "/proc/%d/cmdline", fuse_get_context()->pid); + FILE *proc; + char cmdline[256] = ""; + + if ((proc = fopen(filename, "rt")) == NULL) + return NULL; + else + { + fread(cmdline, sizeof(cmdline), 1, proc); + fclose(proc); + } + + return strdup(cmdline); +} + +static void loggedfs_log(const char *path, const char *action, const int returncode, const char *format, ...) +{ + const char *retname; + + if (returncode >= 0) + retname = "SUCCESS"; + else + retname = "FAILURE"; + + if (config.shouldLog(path, fuse_get_context()->uid, action, retname)) + { + va_list args; + char *buf = NULL; + char *additionalInfo = NULL; + + char *caller_name = getcallername(); + asprintf(&additionalInfo, additionalInfoFormat, retname, fuse_get_context()->pid, config.isPrintProcessNameEnabled() ? caller_name : "", fuse_get_context()->uid); + + va_start(args, format); + vasprintf(&buf, format, args); + va_end(args); + + if (returncode >= 0) + { + ELPP_WRITE_LOG(el::base::Writer, el::Level::Info, dispatchAction, "default") << buf << additionalInfo; + } + else + { + ELPP_WRITE_LOG(el::base::Writer, el::Level::Error, dispatchAction, "default") << buf << additionalInfo; + } + + free(buf); + free(additionalInfo); + free(caller_name); + } +} + +static void *loggedFS_init(struct fuse_conn_info *info) +{ + fchdir(savefd); + close(savefd); + return NULL; +} + +static int loggedFS_getattr(const char *orig_path, struct stat *stbuf) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = lstat(realPath, stbuf); + loggedfs_log(fusePath, "getattr", res, "getattr %s", fusePath); + delete[] realPath; + delete[] fusePath; + if (res == -1) + return -errno; + + return 0; +} + +static int loggedFS_access(const char *orig_path, int mask) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = access(realPath, mask); + loggedfs_log(fusePath, "access", res, "access %s", fusePath); + delete[] realPath; + delete[] fusePath; + if (res == -1) + { + return -errno; + } + + return 0; +} + +static int loggedFS_readlink(const char *orig_path, char *buf, size_t size) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = readlink(realPath, buf, size - 1); + loggedfs_log(fusePath, "readlink", res, "readlink %s", fusePath); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + buf[res] = '\0'; + + return 0; +} + +static int loggedFS_readdir(const char *orig_path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi) +{ + DIR *dp; + struct dirent *de; + int res; + + (void)offset; + (void)fi; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + dp = opendir(realPath); + if (dp == NULL) + { + res = -errno; + loggedfs_log(fusePath, "readdir", -1, "readdir %s", fusePath); + delete[] realPath; + delete[] fusePath; + return res; + } + + while ((de = readdir(dp)) != NULL) + { + struct stat st; + memset(&st, 0, sizeof(st)); + st.st_ino = de->d_ino; + st.st_mode = de->d_type << 12; + if (filler(buf, de->d_name, &st, 0)) + break; + } + + closedir(dp); + loggedfs_log(fusePath, "readdir", 0, "readdir %s", fusePath); + delete[] realPath; + delete[] fusePath; + + return 0; +} + +static int loggedFS_mknod(const char *orig_path, mode_t mode, dev_t rdev) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + if (S_ISREG(mode)) + { + res = open(realPath, O_CREAT | O_EXCL | O_WRONLY, mode); + loggedfs_log(fusePath, "mknod", res, "mknod %s %o S_IFREG (normal file creation)", fusePath, mode); + if (res >= 0) + { + res = close(res); + } + } + else if (S_ISFIFO(mode)) + { + res = mkfifo(realPath, mode); + loggedfs_log(fusePath, "mkfifo", res, "mkfifo %s %o S_IFFIFO (fifo creation)", fusePath, mode); + } + else + { + res = mknod(realPath, mode, rdev); + if (S_ISCHR(mode)) + { + loggedfs_log(fusePath, "mknod", res, "mknod %s %o (character device creation)", fusePath, mode); + } + /*else if (S_IFBLK(mode)) + { + loggedfs_log(fusePath,"mknod",res,"mknod %s %o (block device creation)",fusePath, mode); + }*/ + else + { + loggedfs_log(fusePath, "mknod", res, "mknod %s %o", fusePath, mode); + } + } + + delete[] realPath; + + if (res == -1) + { +// free(path); + return -errno; + } + else + { + lchown(realPath, fuse_get_context()->uid, fuse_get_context()->gid); + } + + delete[] fusePath; + + return 0; +} + +static int loggedFS_mkdir(const char *orig_path, mode_t mode) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = mkdir(realPath, mode); + loggedfs_log(fusePath, "mkdir", res, "mkdir %s %o", fusePath, mode); + delete[] realPath; + + if (res == -1) + { +// free(path); + return -errno; + } + else + lchown(realPath, fuse_get_context()->uid, fuse_get_context()->gid); + + delete[] fusePath; + return 0; +} + +static int loggedFS_unlink(const char *orig_path) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = unlink(realPath); + loggedfs_log(fusePath, "unlink", res, "unlink %s", fusePath); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + return 0; +} + +static int loggedFS_rmdir(const char *orig_path) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = rmdir(realPath); + loggedfs_log(fusePath, "rmdir", res, "rmdir %s", fusePath); + delete[] realPath; + delete[] fusePath; + if (res == -1) + return -errno; + return 0; +} + +static int loggedFS_symlink(const char *from, const char *orig_to) +{ + int res; + + char *aTo = getRealPath(orig_to); + char *to = getRealPath(orig_to); + + res = symlink(from, to); + + loggedfs_log(aTo, "symlink", res, "symlink from %s to %s", aTo, from); + delete[] aTo; + + if (res == -1) + { + free(to); + return -errno; + } + else + lchown(to, fuse_get_context()->uid, fuse_get_context()->gid); + + free(to); + return 0; +} + +static int loggedFS_rename(const char *orig_from, const char *orig_to) +{ + int res; + char *aFrom = getFusePath(orig_from); + char *aTo = getFusePath(orig_to); + + char *from = getRealPath(orig_from); + char *to = getRealPath(orig_to); + + res = rename(from, to); + + loggedfs_log(aFrom, "rename", res, "rename %s to %s", aFrom, aTo); + + delete[] aFrom; + delete[] aTo; + + delete[] from; + delete[] to; + + if (res == -1) + return -errno; + + return 0; +} + +static int loggedFS_link(const char *orig_from, const char *orig_to) +{ + int res; + + char *aFrom = getFusePath(orig_from); + char *aTo = getFusePath(orig_to); + + char *from = getRealPath(orig_from); + char *to = getRealPath(orig_to); + + res = link(from, to); + + loggedfs_log(aTo, "link", res, "hard link from %s to %s", aTo, aFrom); + delete[] aFrom; + delete[] aTo; + delete[] from; + + if (res == -1) + { + delete[] to; + return -errno; + } + else + lchown(to, fuse_get_context()->uid, fuse_get_context()->gid); + + delete[] to; + + return 0; +} + +static int loggedFS_chmod(const char *orig_path, mode_t mode) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + res = chmod(realPath, mode); + + loggedfs_log(fusePath, "chmod", res, "chmod %s to %o", fusePath, mode); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + return 0; +} + +static char *getusername(uid_t uid) +{ + struct passwd *p = getpwuid(uid); + if (p != NULL) + return p->pw_name; + return NULL; +} + +static char *getgroupname(gid_t gid) +{ + struct group *g = getgrgid(gid); + if (g != NULL) + return g->gr_name; + return NULL; +} + +static int loggedFS_chown(const char *orig_path, uid_t uid, gid_t gid) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + res = lchown(realPath, uid, gid); + + char *username = getusername(uid); + char *groupname = getgroupname(gid); + + if (username != NULL && groupname != NULL) + { + loggedfs_log(fusePath, "chown", res, "chown %s to %d:%d %s:%s", fusePath, uid, gid, username, groupname); + } + else + { + loggedfs_log(fusePath, "chown", res, "chown %s to %d:%d", fusePath, uid, gid); + } + + delete[] realPath; + delete[] fusePath; + + if (res == -1) + { + return -errno; + } + + return 0; +} + +static int loggedFS_truncate(const char *orig_path, off_t size) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + res = truncate(realPath, size); + + loggedfs_log(fusePath, "truncate", res, "truncate %s to %d bytes", fusePath, size); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + return 0; +} + +#if (FUSE_USE_VERSION == 25) +static int loggedFS_utime(const char *orig_path, struct utimbuf *buf) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = utime(path, buf); + loggedfs_log(fusePath, "utime", res, "utime %s", fusePath); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + return 0; +} + +#else + +static int loggedFS_utimens(const char *orig_path, const struct timespec ts[2]) +{ + int res; + + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + res = utimensat(AT_FDCWD, realPath, ts, AT_SYMLINK_NOFOLLOW); + + loggedfs_log(fusePath, "utimens", res, "utimens %s", fusePath); + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + return 0; +} + +#endif + +static int loggedFS_open(const char *orig_path, struct fuse_file_info *fi) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + res = open(realPath, fi->flags); + + // what type of open ? read, write, or read-write ? + if (fi->flags & O_RDONLY) + { + loggedfs_log(fusePath, "open-readonly", res, "open readonly %s", fusePath); + } + else if (fi->flags & O_WRONLY) + { + loggedfs_log(fusePath, "open-writeonly", res, "open writeonly %s", fusePath); + } + else if (fi->flags & O_RDWR) + { + loggedfs_log(fusePath, "open-readwrite", res, "open readwrite %s", fusePath); + } + else + loggedfs_log(fusePath, "open", res, "open %s", fusePath); + + delete[] realPath; + delete[] fusePath; + + if (res == -1) + return -errno; + + fi->fh = res; + return 0; +} + +static int loggedFS_read(const char *orig_path, char *buf, size_t size, off_t offset, + struct fuse_file_info *fi) +{ + char *realPath = getRealPath(orig_path); + int res; + + loggedfs_log(realPath, "read", 0, "read %d bytes from %s at offset %d", size, realPath, offset); + res = pread(fi->fh, buf, size, offset); + if (res == -1) + { + res = -errno; + loggedfs_log(realPath, "read", -1, "read %d bytes from %s at offset %d", size, realPath, offset); + } + else + { + loggedfs_log(realPath, "read", 0, "%d bytes read from %s at offset %d", res, realPath, offset); + } + delete[] realPath; + return res; +} + +static int loggedFS_write(const char *orig_path, const char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) +{ + int fd; + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + (void)fi; + + fd = open(realPath, O_WRONLY); + if (fd == -1) + { + res = -errno; + loggedfs_log(fusePath, "write", -1, "write %d bytes to %s at offset %d", size, fusePath, offset); + delete[] realPath; + delete[] fusePath; + + return res; + } + else + { + loggedfs_log(fusePath, "write", 0, "write %d bytes to %s at offset %d", size, fusePath, offset); + } + + res = pwrite(fd, buf, size, offset); + + if (res == -1) + res = -errno; + else + loggedfs_log(fusePath, "write", 0, "%d bytes written to %s at offset %d", res, fusePath, offset); + + close(fd); + delete[] realPath; + delete[] fusePath; + + return res; +} + +static int loggedFS_statfs(const char *orig_path, struct statvfs *stbuf) +{ + int res; + char *realPath = getRealPath(orig_path); + char *fusePath = getFusePath(orig_path); + + res = statvfs(realPath, stbuf); + + loggedfs_log(fusePath, "statfs", res, "statfs %s", fusePath); + delete[] realPath; + delete[] fusePath; + if (res == -1) + return -errno; + + return 0; +} + +static int loggedFS_release(const char *orig_path, struct fuse_file_info *fi) +{ + char *realPath = getRealPath(orig_path); + (void)orig_path; + + loggedfs_log(realPath, "release", 0, "release %s", realPath); + delete[] realPath; + + close(fi->fh); + return 0; +} + +static int loggedFS_fsync(const char *orig_path, int isdatasync, + struct fuse_file_info *fi) +{ + char *realPath = getRealPath(orig_path); + (void)orig_path; + (void)isdatasync; + (void)fi; + loggedfs_log(realPath, "fsync", 0, "fsync %s", realPath); + delete[] realPath; + return 0; +} + +#ifdef HAVE_SETXATTR +/* xattr operations are optional and can safely be left unimplemented */ +static int loggedFS_setxattr(const char *orig_path, const char *name, const char *value, + size_t size, int flags) +{ + int res = lsetxattr(orig_path, name, value, size, flags); + if (res == -1) + return -errno; + return 0; +} + +static int loggedFS_getxattr(const char *orig_path, const char *name, char *value, + size_t size) +{ + int res = lgetxattr(orig_path, name, value, size); + if (res == -1) + return -errno; + return res; +} + +static int loggedFS_listxattr(const char *orig_path, char *list, size_t size) +{ + int res = llistxattr(orig_path, list, size); + if (res == -1) + return -errno; + return res; +} + +static int loggedFS_removexattr(const char *orig_path, const char *name) +{ + int res = lremovexattr(orig_path, name); + if (res == -1) + return -errno; + return 0; +} +#endif /* HAVE_SETXATTR */ + +static void usage(char *name) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "%s [-h] | [-l log-file] [-c config-file] [-f] [-p] [-e] /directory-to-map-on-loggedfs\n", name); + fprintf(stderr, "Type 'man loggedfs' for more details\n"); + return; +} + +static bool processArgs(int argc, char *argv[], LoggedFS_Args *out) +{ + // set defaults + out->isDaemon = true; + + out->fuseArgc = 0; + out->configFilename = NULL; + + // pass executable name through + out->fuseArgv[0] = argv[0]; + ++out->fuseArgc; + + // leave a space for mount point, as FUSE expects the mount point before + // any flags + out->fuseArgv[1] = NULL; + ++out->fuseArgc; + opterr = 0; + + int res; + + bool got_p = false; + + // We need the "nonempty" option to mount the directory in recent FUSE's + // because it's non empty and contains the files that will be logged. + // + // "nonempty" is linux-only option + // + // We need "use_ino" so the files will use their original inode numbers, + // instead of all getting 0xFFFFFFFF . For example, this is required for + // logging the ~/.kde/share/config directory, in which hard links for lock + // files are verified by their inode equivalency. + +#ifdef linux +#define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" +#else +#define COMMON_OPTS "use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0,allow_other,kill_on_unmount,volname=LoggedFS" +#endif + + while ((res = getopt(argc, argv, "hpfec:l:")) != -1) + { + switch (res) + { + case 'h': + usage(argv[0]); + return false; + case 'f': + out->isDaemon = false; + // this option was added in fuse 2.x + PUSHARG("-f"); + defaultLogger->info("LoggedFS not running as a daemon"); + break; + case 'p': + PUSHARG("-o"); + PUSHARG("allow_other,default_permissions," COMMON_OPTS); + got_p = true; + defaultLogger->info("LoggedFS running as a public filesystem"); + break; + case 'e': + PUSHARG("-o"); + PUSHARG("nonempty"); + defaultLogger->info("Using existing directory"); + break; + case 'c': + out->configFilename = optarg; + defaultLogger->info("Configuration file : %v", optarg); + break; + case 'l': + { + defaultLogger->info("LoggedFS log file : %v", optarg); + el::Configurations defaultConf; + defaultConf.setToDefault(); + defaultConf.setGlobally(el::ConfigurationType::ToFile, std::string("true")); + defaultConf.setGlobally(el::ConfigurationType::ToStandardOutput, std::string("false")); + defaultConf.setGlobally(el::ConfigurationType::Filename, std::string(optarg)); + el::Loggers::reconfigureLogger("default", defaultConf); + defaultLogger = el::Loggers::getLogger("default"); + break; + } + default: + break; + } + } + + if (!got_p) + { + PUSHARG("-o"); + PUSHARG(COMMON_OPTS); + } +#undef COMMON_OPTS + + if (optind + 1 <= argc) + { + out->realPath = argv[optind++]; + out->mountPoint = "/Volumes/LoggedFS"; + out->fuseArgv[1] = out->mountPoint; + } + else + { + fprintf(stderr, "Missing real path\n"); + usage(argv[0]); + return false; + } + + // If there are still extra unparsed arguments, pass them onto FUSE.. + if (optind < argc) + { + rAssert(out->fuseArgc < MaxFuseArgs); + + while (optind < argc) + { + rAssert(out->fuseArgc < MaxFuseArgs); + out->fuseArgv[out->fuseArgc++] = argv[optind]; + ++optind; + } + } + + if (!isAbsolutePath(out->realPath)) + { + fprintf(stderr, "You must use absolute paths " + "(beginning with '/') for %s\n", + out->realPath); + return false; + } + return true; +} + +int main(int argc, char *argv[]) +{ + el::Configurations defaultConf; + defaultConf.setToDefault(); + defaultConf.setGlobally(el::ConfigurationType::ToFile, std::string("false")); + el::Loggers::reconfigureLogger("default", defaultConf); + defaultLogger = el::Loggers::getLogger("default"); + + char *input = new char[2048]; // 2ko MAX input for configuration + + umask(0); + fuse_operations loggedFS_oper; + // in case this code is compiled against a newer FUSE library and new + // members have been added to fuse_operations, make sure they get set to + // 0.. + memset(&loggedFS_oper, 0, sizeof(fuse_operations)); + loggedFS_oper.init = loggedFS_init; + loggedFS_oper.getattr = loggedFS_getattr; + loggedFS_oper.access = loggedFS_access; + loggedFS_oper.readlink = loggedFS_readlink; + loggedFS_oper.readdir = loggedFS_readdir; + loggedFS_oper.mknod = loggedFS_mknod; + loggedFS_oper.mkdir = loggedFS_mkdir; + loggedFS_oper.symlink = loggedFS_symlink; + loggedFS_oper.unlink = loggedFS_unlink; + loggedFS_oper.rmdir = loggedFS_rmdir; + loggedFS_oper.rename = loggedFS_rename; + loggedFS_oper.link = loggedFS_link; + loggedFS_oper.chmod = loggedFS_chmod; + loggedFS_oper.chown = loggedFS_chown; + loggedFS_oper.truncate = loggedFS_truncate; +#if (FUSE_USE_VERSION == 25) + loggedFS_oper.utime = loggedFS_utime; +#else + loggedFS_oper.utimens = loggedFS_utimens; + loggedFS_oper.flag_utime_omit_ok = 1; +#endif + loggedFS_oper.open = loggedFS_open; + loggedFS_oper.read = loggedFS_read; + loggedFS_oper.write = loggedFS_write; + loggedFS_oper.statfs = loggedFS_statfs; + loggedFS_oper.release = loggedFS_release; + loggedFS_oper.fsync = loggedFS_fsync; +#ifdef HAVE_SETXATTR + loggedFS_oper.setxattr = loggedFS_setxattr; + loggedFS_oper.getxattr = loggedFS_getxattr; + loggedFS_oper.listxattr = loggedFS_listxattr; + loggedFS_oper.removexattr = loggedFS_removexattr; +#endif + + for (int i = 0; i < MaxFuseArgs; ++i) + loggedfsArgs->fuseArgv[i] = NULL; // libfuse expects null args.. + + if (processArgs(argc, argv, loggedfsArgs)) + { + if (loggedfsArgs->isDaemon) + { + dispatchAction = el::base::DispatchAction::SysLog; + loggerId = "syslog"; + } + + defaultLogger->info("LoggedFS starting at %v.", loggedfsArgs->realPath); + + if (loggedfsArgs->configFilename != NULL) + { + + if (strcmp(loggedfsArgs->configFilename, "-") == 0) + { + defaultLogger->info("Using stdin configuration"); + memset(input, 0, 2048); + char *ptr = input; + + int size = 0; + do + { + size = fread(ptr, 1, 1, stdin); + ptr++; + } while (!feof(stdin) && size > 0); + config.loadFromXmlBuffer(input); + } + else + { + defaultLogger->info("Using configuration file %v.", loggedfsArgs->configFilename); + config.loadFromXmlFile(loggedfsArgs->configFilename); + } + } + delete[] input; + defaultLogger->info("chdir to %v", loggedfsArgs->mountPoint); + chdir(loggedfsArgs->mountPoint); + savefd = open(".", 0); + +#if (FUSE_USE_VERSION == 25) + fuse_main(loggedfsArgs->fuseArgc, + const_cast(loggedfsArgs->fuseArgv), &loggedFS_oper); +#else + fuse_main(loggedfsArgs->fuseArgc, + const_cast(loggedfsArgs->fuseArgv), &loggedFS_oper, NULL); +#endif + defaultLogger->info("LoggedFS closing."); + } +} From 61b43f4a74d57bc730f12d6638df600e8f48158d Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Thu, 8 Apr 2021 11:21:58 +0300 Subject: [PATCH 13/16] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ef56e8..e291480 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ If you want to log what other users do on your filesystem, you should use the -p ## About OSX implementation The main implementation of loggedfs is working with the one path specified in arguments. -It mounts the fuse volume to the path specified and intercepts operations by splitting pathes +It mounts the fuse volume to the path specified and intercepts operations by splitting paths to realPath and absolutePath. On OSX, all volumes should be mounted to /Volumes directory. @@ -130,5 +130,4 @@ mounted (/Volumes/LoggedFS), and the one specified in program arguments. Rémi Flament - remipouak at gmail.com - -OSX imeplementation - Danil Korotenko \ No newline at end of file +OSX imeplementation - Danil Korotenko From 914bc21c9c81567d65e385ffee023c80d48071dd Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Thu, 8 Apr 2021 11:22:47 +0300 Subject: [PATCH 14/16] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e291480..c401a2a 100644 --- a/README.md +++ b/README.md @@ -130,4 +130,5 @@ mounted (/Volumes/LoggedFS), and the one specified in program arguments. Rémi Flament - remipouak at gmail.com + OSX imeplementation - Danil Korotenko From 01a4259a9275e959fa2d658a46dc21586c6fde30 Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Thu, 8 Apr 2021 11:23:29 +0300 Subject: [PATCH 15/16] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c401a2a..f58cdf8 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ That is why OSX version is needed to deal with two pathes: the one where is fuse mounted (/Volumes/LoggedFS), and the one specified in program arguments. - +## Authors Rémi Flament - remipouak at gmail.com From 08179f4bac476b2c64e7bc6754e9c30db6f49f0e Mon Sep 17 00:00:00 2001 From: Danil Korotenko Date: Fri, 30 Apr 2021 11:26:54 +0300 Subject: [PATCH 16/16] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f58cdf8..fa3c2fe 100644 --- a/README.md +++ b/README.md @@ -131,4 +131,4 @@ mounted (/Volumes/LoggedFS), and the one specified in program arguments. Rémi Flament - remipouak at gmail.com -OSX imeplementation - Danil Korotenko +OSX implementation - Danil Korotenko