pax_global_header00006660000000000000000000000064132561302300014505gustar00rootroot0000000000000052 comment=d37b9405364ef014ce2e966f67bba887cb0fcf01 loggedfs-loggedfs-0.9/000077500000000000000000000000001325613023000147375ustar00rootroot00000000000000loggedfs-loggedfs-0.9/.gitignore000066400000000000000000000000201325613023000167170ustar00rootroot00000000000000build/ loggedfs loggedfs-loggedfs-0.9/.travis.yml000066400000000000000000000005351325613023000170530ustar00rootroot00000000000000language: cpp matrix: include: - os: linux compiler: gcc dist: trusty sudo: required addons: apt: sources: - ubuntu-toolchain-r-test packages: - attr - fuse - libfuse-dev - libpcre3-dev - libxml2-dev script: - make loggedfs-loggedfs-0.9/LICENSE000066400000000000000000000261361325613023000157540ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed 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. loggedfs-loggedfs-0.9/Makefile000066400000000000000000000030431325613023000163770ustar00rootroot00000000000000CC=g++ CFLAGS=-Wall -ansi -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -DELPP_SYSLOG -DELPP_NO_DEFAULT_LOG_FILE -DELPP_THREAD_SAFE -std=c++11 `xml2-config --cflags` LDFLAGS=-Wall -ansi -lpcre -lfuse `xml2-config --libs` -lpthread srcdir=src easyloggingdir=vendor/github.com/muflihun/easyloggingpp/src builddir=build all: $(builddir) loggedfs $(builddir): mkdir $(builddir) loggedfs: $(builddir)/loggedfs.o $(builddir)/Config.o $(builddir)/Filter.o $(builddir)/easylogging.o $(CC) -o loggedfs $(builddir)/loggedfs.o $(builddir)/Config.o $(builddir)/Filter.o $(builddir)/easylogging.o $(LDFLAGS) $(builddir)/loggedfs.o: $(builddir)/Config.o $(builddir)/Filter.o $(srcdir)/loggedfs.cpp $(CC) -o $(builddir)/loggedfs.o -c $(srcdir)/loggedfs.cpp $(CFLAGS) -Ivendor/github.com/muflihun/easyloggingpp/src $(builddir)/Config.o: $(builddir)/Filter.o $(srcdir)/Config.cpp $(srcdir)/Config.h $(CC) -o $(builddir)/Config.o -c $(srcdir)/Config.cpp $(CFLAGS) $(builddir)/Filter.o: $(srcdir)/Filter.cpp $(srcdir)/Filter.h $(CC) -o $(builddir)/Filter.o -c $(srcdir)/Filter.cpp $(CFLAGS) $(builddir)/easylogging.o: $(easyloggingdir)/easylogging++.cc $(easyloggingdir)/easylogging++.h $(CC) -o $(builddir)/easylogging.o -c $(easyloggingdir)/easylogging++.cc $(CFLAGS) clean: rm -rf $(builddir)/ install: gzip --keep loggedfs.1 cp loggedfs.1.gz /usr/share/man/man1/ cp loggedfs /usr/bin/ cp loggedfs.xml /etc/ mrproper: clean rm -rf loggedfs release: tar -c --exclude="CVS" $(srcdir)/ loggedfs.xml LICENSE loggedfs.1.gz Makefile | bzip2 - > loggedfs.tar.bz2 loggedfs-loggedfs-0.9/README.md000066400000000000000000000114321325613023000162170ustar00rootroot00000000000000# LoggedFS - Filesystem monitoring with Fuse [![Build Status](https://travis-ci.org/rflament/loggedfs.svg?branch=feature%2Feasylogging%2B%2B)](https://travis-ci.org/rflament/loggedfs) Donate Ethereum: 0x83FBC94FBca4e2f10Bede63e16C5b0Bb31a1Fed1 ## Description LoggedFS is a fuse-based filesystem which can log every operations that happens in it. How does it work ? Fuse does almost everything. LoggedFS only sends a message to syslog when called by fuse and then let the real filesystem do the rest of the job. ## Installation If loggedfs is included in your distribution you can just install with your package manager : sudo apt-get install loggedfs ## Simplest usage To record access to /tmp/TEST into ~/log.txt, just do: loggedfs -l ~/log.txt /tmp/TEST To stop recording, just unmount as usual: sudo umount /tmp/TEST ~/log.txt will need to be changed to readable by setting permissions: chmod 0666 ~/log.txt ## Installation from source First you have to make sure that fuse is installed on your computer. If you have a recent distribution it should be. Fuse can be downloaded here : https://github.com/libfuse/libfuse. Then you should download the loggedfs archive and install it with the make command : sudo apt-get install libfuse-dev libxml2-dev libpcre3-dev tar xfj loggedfs-X.Y.tar.bz2 cd loggedfs-X.Y make make install LoggedFS has the following dependencies : fuse pcre libxml2 ## Configuration LoggedFS can use an XML configuration file if you want it to log operations only for certain files, for certain users, or for certain operations. Here is a sample configuration file : This configuration can be used to log everything except it if concerns a *.bak file, or if the uid is 1000, or if the operation is getattr. ## Launching LoggedFS If you just want to test LoggedFS you don't need any configuration file. Just use that command : loggedfs -f -p /var You should see logs like these : tail -f /var/log/syslog 2018-03-21 15:32:14,095 INFO [default] LoggedFS not running as a daemon 2018-03-21 15:32:14,095 INFO [default] LoggedFS running as a public filesystem 2018-03-21 15:32:14,095 INFO [default] LoggedFS starting at /var. 2018-03-21 15:32:14,095 INFO [default] chdir to /var 2018-03-21 15:32:15,375 INFO [default] getattr /var/ {SUCCESS} [ pid = 934 /usr/sbin/VBoxService uid = 0 ] 2018-03-21 15:32:15,375 INFO [default] getattr /var/run {SUCCESS} [ pid = 934 /usr/sbin/VBoxService uid = 0 ] 2018-03-21 15:32:15,376 INFO [default] readlink /var/run {SUCCESS} [ pid = 934 /usr/sbin/VBoxService uid = 0 ] 2018-03-21 15:32:15,376 INFO [default] readlink /var/run {SUCCESS} [ pid = 934 /usr/sbin/VBoxService uid = 0 ] 2018-03-21 15:32:15,890 INFO [default] getattr /var/cache {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,891 INFO [default] getattr /var/cache/apt {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,891 INFO [default] getattr /var/cache/apt/archives {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,891 INFO [default] getattr /var/cache/apt/archives/partial {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,891 INFO [default] getattr /var/cache/apt/archives/partial {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,892 INFO [default] getattr /var/lib {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,892 INFO [default] getattr /var/lib/apt {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,892 INFO [default] getattr /var/lib/apt/lists {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,892 INFO [default] getattr /var/lib/apt/lists/partial {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:15,892 INFO [default] getattr /var/lib/apt/lists/partial {SUCCESS} [ pid = 1539 update-notifier uid = 1000 ] 2018-03-21 15:32:17,873 INFO [default] LoggedFS closing. If you have a configuration file to use you should use this command : ./loggedfs -c loggedfs.xml -p /var 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 RĂ©mi Flament - remipouak at gmail.comloggedfs-loggedfs-0.9/loggedfs.1000066400000000000000000000022751325613023000166210ustar00rootroot00000000000000.TH LoggedFS 1 "JANUARY 2007" "User Manuals" .SH NAME LoggedFS \- Filesystem monitoring with Fuse .SH SYNOPSIS .B loggedfs [-fp] [-c .I config-file .B ] [-l .I log-file .B ] .I directory .B ... .SH DESCRIPTION .B LoggedFS is a transparent fuse-filesystem which allows to log every operations that happens in the backend filesystem. Logs can be written to syslog, to a file, or to the standard output. LoggedFS comes with a XML configuration file in which you can choose exactly what you want to log and what you don't want to log. You can add filters on users, operations (open, read, write, chown, chmod, etc.), filenames , and return code. Filename's filters are regular expressions. .SH OPTIONS .IP -f Do not start as a daemon. Write logs to stdout if no log file is specified. .IP "-c config-file" Use the .I config-file to filter what you want to log. .IP "-l log-file" Use the .I log-file to write logs to. If no log file is specified then logs are only written to syslog or to stdout, depending on -f. .IP -p Allow every users to see the new loggedfs. .SH FILES .I /etc/fuse.conf .RS The system wide configuration file. .RE .SH AUTHOR Remi Flament .SH "SEE ALSO" .BR fusermount (1) loggedfs-loggedfs-0.9/loggedfs.spec000066400000000000000000000022261325613023000174070ustar00rootroot00000000000000Summary: Transparent fuse-filesystem which allows to log every operation that happens in the backend filesystem. Name: loggedfs Version: 0.9 Release: 1.fc6 Source: %{name}-%{version}.tar.bz2 Packager: Remi Flament Vendor: Remi Flament License: Apache 2.0 Group: Development/Tools Url: https://github.com/rflament/loggedfs/ Requires: fuse >= 2.6 fuse-libs >= 2.6 rlog >= 1.3 pcre >= 6.6 libxml2 >= 2.6 %description LoggedFS is a transparent fuse-filesystem which allows you to log every operation that happens in the backend filesystem. Logs can be written to syslog, to a file, or to standard output. It comes with an XML configuration file in which you can choose exactly what you want to log. You can add filters on users, operations (open, read, write, chown, chmod, etc.), filenames, and return codes. Filename's filters are regular expressions. Since it is fuse-based, you don't need to change anything in your kernel or hard disk partition to use it. %prep %setup -q %build make %install make install %files %defattr(-,root,root) /usr/bin/loggedfs /etc/loggedfs.xml %doc /usr/share/man/man1/loggedfs.1* loggedfs-loggedfs-0.9/loggedfs.xml000066400000000000000000000007221325613023000172540ustar00rootroot00000000000000 loggedfs-loggedfs-0.9/src/000077500000000000000000000000001325613023000155265ustar00rootroot00000000000000loggedfs-loggedfs-0.9/src/Config.cpp000066400000000000000000000113141325613023000174370ustar00rootroot00000000000000/***************************************************************************** * 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. * */ #include "Config.h" #include #include xmlChar* INCLUDE=xmlCharStrdup("include"); xmlChar* EXCLUDE=xmlCharStrdup("exclude"); xmlChar* USER=xmlCharStrdup("uid"); xmlChar* EXTENSION=xmlCharStrdup("extension"); xmlChar* ACTION=xmlCharStrdup("action"); xmlChar* RETNAME=xmlCharStrdup("retname"); xmlChar* ROOT=xmlCharStrdup("loggedFS"); xmlChar* LOG_ENABLED=xmlCharStrdup("logEnabled"); xmlChar* PNAME_ENABLED=xmlCharStrdup("printProcessName"); Config::Config() { // default values enabled=true; pNameEnabled=true; } Config::~Config() { includes.clear(); excludes.clear(); } void Config::parse(xmlNode * a_node) { xmlNode *cur_node = NULL; for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { xmlAttr *attr=cur_node->properties; if (xmlStrcmp(cur_node->name,ROOT)==0) { while (attr!=NULL) { if (xmlStrcmp(attr->name,LOG_ENABLED)==0) { //enable or disable loggedfs if (xmlStrcmp(attr->children->content,xmlCharStrdup("true"))!=0) { enabled=false; printf("Log disabled\n"); } else { printf("Log enabled\n"); } } else if (xmlStrcmp(attr->name,PNAME_ENABLED)==0) { //enable or disable process name prints in loggedfs if (xmlStrcmp(attr->children->content,xmlCharStrdup("true"))!=0) { pNameEnabled=false; printf("print process name disabled\n"); } else { printf("print process name enabled\n"); } } else printf("unknown attribute : %s\n",attr->name); attr=attr->next; } } if (xmlStrcmp(cur_node->name,INCLUDE)==0 || xmlStrcmp(cur_node->name,EXCLUDE)==0) { Filter* filter=new Filter(); char* buffer=new char[100]; while (attr!=NULL) { sprintf(buffer,"%s",attr->children->content); // I guess there's another way to do that if (xmlStrcmp(attr->name,EXTENSION)==0) { filter->setExtension(buffer); } else if (xmlStrcmp(attr->name,USER)==0) { if (strcmp(buffer,"*")) filter->setUID(atoi(buffer)); else filter->setUID(-1); // every users } else if (xmlStrcmp(attr->name,ACTION)==0) { filter->setAction(buffer); } else if (xmlStrcmp(attr->name,RETNAME)==0) { filter->setRetname(buffer); } else printf("unknown attribute : %s\n",attr->name); attr=attr->next; } if (xmlStrcmp(cur_node->name,INCLUDE)==0) { includes.push_back(*filter); } else excludes.push_back(*filter); delete[] buffer; } } parse(cur_node->children); } } bool Config::loadFromXml(xmlDoc* doc) { xmlNode *root_element = NULL; root_element = xmlDocGetRootElement(doc); parse(root_element); xmlFreeDoc(doc); xmlCleanupParser(); return true; } bool Config::loadFromXmlBuffer(const char* buffer) { xmlDoc *doc = NULL; LIBXML_TEST_VERSION doc=xmlReadMemory(buffer,strlen(buffer),"",NULL, XML_PARSE_NONET); return loadFromXml(doc); } bool Config::loadFromXmlFile(const char* filename) { xmlDoc *doc = NULL; LIBXML_TEST_VERSION doc = xmlReadFile(filename, NULL, 0); return loadFromXml(doc); } bool Config::shouldLog(const char* filename, int uid, const char* action, const char* retname) { bool should=false; if (enabled) { if (includes.size()>0) { for (unsigned int i=0;i ***************************************************************************** * 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. * */ #ifndef LOGGEDFS_CONFIG_H #define LOGGEDFS_CONFIG_H using namespace std; #include #include #include #include "Filter.h" class Config { public: Config(); ~Config(); bool load(const char *fileName); bool loadFromXmlFile(const char *fileName); bool loadFromXmlBuffer(const char *buffer); bool loadFromXml(xmlDoc* doc); bool isEnabled() {return enabled;}; bool isTimeEnabled() {return timeEnabled;}; bool isPrintProcessNameEnabled() {return pNameEnabled;}; bool shouldLog(const char* filename, int uid, const char* action, const char *retname); char* toString(); private: void parse(xmlNode*); std::vector includes; std::vector excludes; bool enabled; bool timeEnabled; bool pNameEnabled; }; #endif loggedfs-loggedfs-0.9/src/Filter.cpp000066400000000000000000000046761325613023000174740ustar00rootroot00000000000000/***************************************************************************** * 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. * */ #include "Filter.h" #include #define OVECCOUNT 30 Filter::Filter() { } Filter::~Filter() { } bool Filter::matches( const char* str,const char* pattern) { pcre *re; const char *error; int ovector[OVECCOUNT]; int erroffset; re = pcre_compile( pattern, 0, &error, &erroffset, NULL); 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); } 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)); return a; } loggedfs-loggedfs-0.9/src/Filter.h000066400000000000000000000034431325613023000171300ustar00rootroot00000000000000/***************************************************************************** * 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. * */ #ifndef LOGGEDFS_FILTER_H #define LOGGEDFS_FILTER_H #include #include class Filter { public: Filter(); ~Filter(); const char* getExtension() {return extension;}; int getUID() {return uid;}; const char* getAction() {return action;}; const char* getRetname() {return retname;}; void setExtension(const char* e) {this->extension=strdup(e);}; void setUID(int u) {this->uid=u;}; void setAction(const char* a) {this->action=strdup(a);}; void setRetname(const char* r) {this->retname=strdup(r);}; bool matches(const char* path, int uid, const char *action, const char* retname); private: const char* extension; int uid; const char* action; const char* retname; bool matches( const char* str,const char* pattern); }; #endif loggedfs-loggedfs-0.9/src/loggedfs.cpp000066400000000000000000000615631325613023000200370ustar00rootroot00000000000000/***************************************************************************** * 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 #include #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 *mountPoint; // where the users read files 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 *getAbsolutePath(const char *path) { char *realPath = new char[strlen(path) + strlen(loggedfsArgs->mountPoint) + 1]; strcpy(realPath, loggedfsArgs->mountPoint); if (realPath[strlen(realPath) - 1] == '/') realPath[strlen(realPath) - 1] = '\0'; strcat(realPath, path); return realPath; } static char *getRelativePath(const char *path) { if (path[0] == '/') { if (strlen(path) == 1) { return strdup("."); } const char *substr = &path[1]; return strdup(substr); } return strdup(path); } /* * 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 *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = lstat(path, stbuf); loggedfs_log(aPath, "getattr", res, "getattr %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_access(const char *orig_path, int mask) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = access(path, mask); loggedfs_log(aPath, "access", res, "access %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_readlink(const char *orig_path, char *buf, size_t size) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = readlink(path, buf, size - 1); loggedfs_log(aPath, "readlink", res, "readlink %s", aPath); delete[] aPath; free(path); 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 *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); dp = opendir(path); if (dp == NULL) { res = -errno; loggedfs_log(aPath, "readdir", -1, "readdir %s", aPath); delete[] aPath; free(path); 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(aPath, "readdir", 0, "readdir %s", aPath); delete[] aPath; free(path); return 0; } static int loggedFS_mknod(const char *orig_path, mode_t mode, dev_t rdev) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); if (S_ISREG(mode)) { res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode); loggedfs_log(aPath, "mknod", res, "mknod %s %o S_IFREG (normal file creation)", aPath, mode); if (res >= 0) res = close(res); } else if (S_ISFIFO(mode)) { res = mkfifo(path, mode); loggedfs_log(aPath, "mkfifo", res, "mkfifo %s %o S_IFFIFO (fifo creation)", aPath, mode); } else { res = mknod(path, mode, rdev); if (S_ISCHR(mode)) { loggedfs_log(aPath, "mknod", res, "mknod %s %o (character device creation)", aPath, mode); } /*else if (S_IFBLK(mode)) { loggedfs_log(aPath,"mknod",res,"mknod %s %o (block device creation)",aPath, mode); }*/ else loggedfs_log(aPath, "mknod", res, "mknod %s %o", aPath, mode); } delete[] aPath; if (res == -1) { free(path); return -errno; } else lchown(path, fuse_get_context()->uid, fuse_get_context()->gid); free(path); return 0; } static int loggedFS_mkdir(const char *orig_path, mode_t mode) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = mkdir(path, mode); loggedfs_log(path, "mkdir", res, "mkdir %s %o", aPath, mode); delete[] aPath; if (res == -1) { free(path); return -errno; } else lchown(path, fuse_get_context()->uid, fuse_get_context()->gid); free(path); return 0; } static int loggedFS_unlink(const char *orig_path) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = unlink(path); loggedfs_log(aPath, "unlink", res, "unlink %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_rmdir(const char *orig_path) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = rmdir(path); loggedfs_log(aPath, "rmdir", res, "rmdir %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_symlink(const char *from, const char *orig_to) { int res; char *aTo = getAbsolutePath(orig_to); char *to = getRelativePath(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 = getAbsolutePath(orig_from); char *aTo = getAbsolutePath(orig_to); char *from = getRelativePath(orig_from); char *to = getRelativePath(orig_to); res = rename(from, to); loggedfs_log(aFrom, "rename", res, "rename %s to %s", aFrom, aTo); delete[] aFrom; delete[] aTo; free(from); free(to); if (res == -1) return -errno; return 0; } static int loggedFS_link(const char *orig_from, const char *orig_to) { int res; char *aFrom = getAbsolutePath(orig_from); char *aTo = getAbsolutePath(orig_to); char *from = getRelativePath(orig_from); char *to = getRelativePath(orig_to); res = link(from, to); loggedfs_log(aTo, "link", res, "hard link from %s to %s", aTo, aFrom); delete[] aFrom; delete[] aTo; free(from); if (res == -1) { delete[] to; return -errno; } else lchown(to, fuse_get_context()->uid, fuse_get_context()->gid); free(to); return 0; } static int loggedFS_chmod(const char *orig_path, mode_t mode) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = chmod(path, mode); loggedfs_log(aPath, "chmod", res, "chmod %s to %o", aPath, mode); delete[] aPath; free(path); 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 *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = lchown(path, uid, gid); char *username = getusername(uid); char *groupname = getgroupname(gid); if (username != NULL && groupname != NULL) loggedfs_log(aPath, "chown", res, "chown %s to %d:%d %s:%s", aPath, uid, gid, username, groupname); else loggedfs_log(aPath, "chown", res, "chown %s to %d:%d", aPath, uid, gid); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_truncate(const char *orig_path, off_t size) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = truncate(path, size); loggedfs_log(aPath, "truncate", res, "truncate %s to %d bytes", aPath, size); delete[] aPath; free(path); 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 *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = utime(path, buf); loggedfs_log(aPath, "utime", res, "utime %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } #else static int loggedFS_utimens(const char *orig_path, const struct timespec ts[2]) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = utimensat(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW); loggedfs_log(aPath, "utimens", res, "utimens %s", aPath); delete[] aPath; free(path); if (res == -1) return -errno; return 0; } #endif static int loggedFS_open(const char *orig_path, struct fuse_file_info *fi) { int res; char *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); res = open(path, fi->flags); // what type of open ? read, write, or read-write ? if (fi->flags & O_RDONLY) { loggedfs_log(aPath, "open-readonly", res, "open readonly %s", aPath); } else if (fi->flags & O_WRONLY) { loggedfs_log(aPath, "open-writeonly", res, "open writeonly %s", aPath); } else if (fi->flags & O_RDWR) { loggedfs_log(aPath, "open-readwrite", res, "open readwrite %s", aPath); } else loggedfs_log(aPath, "open", res, "open %s", aPath); delete[] aPath; free(path); 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 *aPath = getAbsolutePath(orig_path); int res; loggedfs_log(aPath, "read", 0, "read %d bytes from %s at offset %d", size, aPath, offset); res = pread(fi->fh, buf, size, offset); if (res == -1) { res = -errno; loggedfs_log(aPath, "read", -1, "read %d bytes from %s at offset %d", size, aPath, offset); } else { loggedfs_log(aPath, "read", 0, "%d bytes read from %s at offset %d", res, aPath, offset); } delete[] aPath; 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 *aPath = getAbsolutePath(orig_path); char *path = getRelativePath(orig_path); (void)fi; fd = open(path, O_WRONLY); if (fd == -1) { res = -errno; loggedfs_log(aPath, "write", -1, "write %d bytes to %s at offset %d", size, aPath, offset); delete[] aPath; free(path); return res; } else { loggedfs_log(aPath, "write", 0, "write %d bytes to %s at offset %d", size, aPath, offset); } res = pwrite(fd, buf, size, offset); if (res == -1) res = -errno; else loggedfs_log(aPath, "write", 0, "%d bytes written to %s at offset %d", res, aPath, offset); close(fd); delete[] aPath; free(path); return res; } 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; free(path); if (res == -1) return -errno; return 0; } static int loggedFS_release(const char *orig_path, struct fuse_file_info *fi) { char *aPath = getAbsolutePath(orig_path); (void)orig_path; loggedfs_log(aPath, "release", 0, "release %s", aPath); delete[] aPath; close(fi->fh); return 0; } static int loggedFS_fsync(const char *orig_path, int isdatasync, struct fuse_file_info *fi) { char *aPath = getAbsolutePath(orig_path); (void)orig_path; (void)isdatasync; (void)fi; loggedfs_log(aPath, "fsync", 0, "fsync %s", aPath); delete[] aPath; 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-mountpoint\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. // // 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. #define COMMON_OPTS "nonempty,use_ino,attr_timeout=0,entry_timeout=0,negative_timeout=0" 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->mountPoint = argv[optind++]; out->fuseArgv[1] = out->mountPoint; } else { fprintf(stderr, "Missing mountpoint\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->mountPoint)) { fprintf(stderr, "You must use absolute paths " "(beginning with '/') for %s\n", out->mountPoint); 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->mountPoint); 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."); } } loggedfs-loggedfs-0.9/vendor/000077500000000000000000000000001325613023000162345ustar00rootroot00000000000000loggedfs-loggedfs-0.9/vendor/github.com/000077500000000000000000000000001325613023000202735ustar00rootroot00000000000000loggedfs-loggedfs-0.9/vendor/github.com/muflihun/000077500000000000000000000000001325613023000221225ustar00rootroot00000000000000loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/000077500000000000000000000000001325613023000247725ustar00rootroot00000000000000loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/.gitignore000066400000000000000000000001411325613023000267560ustar00rootroot00000000000000build/* build-* *.pro.user .DS_Store release.info bin/* logs/* experiments/* CMakeLists.txt.user loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/.travis.yml000066400000000000000000000015221325613023000271030ustar00rootroot00000000000000language: cpp compiler: - gcc os: linux dist: trusty before_install: - sudo apt-get -qq update - sudo apt-get install -y libgtest-dev valgrind - sudo wget https://github.com/google/googletest/archive/release-1.7.0.tar.gz - sudo tar xf release-1.7.0.tar.gz - cd googletest-release-1.7.0 - sudo cmake -DBUILD_SHARED_LIBS=ON . - sudo make - sudo cp -a include/gtest /usr/include - sudo cp -a libgtest_main.so libgtest.so /usr/lib/ - which valgrind - cd "${TRAVIS_BUILD_DIR}" before_script: - cd test/ - cmake -Dtest=ON ../ - make - ls -l script: "./easyloggingpp-unit-tests -v && cd ../samples/STL && pwd && sh ./.travis_build.sh && valgrind ./bin/very-basic.cpp.bin" branches: only: - master - develop notifications: recipients: - mkhan3189@gmail.com email: on_success: never on_failure: change rvm: - 9.00 loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/CHANGELOG.md000066400000000000000000000037001325613023000266030ustar00rootroot00000000000000# Change Log ## [9.95.0] - 02-08-2017 ### Added - Added NetBSD as unix [coypoop](https://github.com/muflihun/easyloggingpp/pull/548/commits) - Ignore `NDEBUG` or `_DEBUG` to determine whether debug logs should be enabled or not. Use `ELPP_DISABLE_DEBUG_LOGS` ### Fixes - Fix compile when `_USE_32_BIT_TIME_T` defined [gggin](https://github.com/muflihun/easyloggingpp/pull/542/files) - Fix invalid usage of safeDelete which can cause an error with valgrind [Touyote](https://github.com/muflihun/easyloggingpp/pull/544/files) - Add code to ensure no nullptr references [tepperly](https://github.com/muflihun/easyloggingpp/pull/512/files) ## [9.94.2] - 12-04-2017 ### Added - CMake option to create static lib (thanks to @romariorios) - Ability to use UTC time using `ELPP_UTC_DATETIME` (thanks to @romariorios) - CMake module updated to support static lib ### Changes - Renamed long format specifiers to full names with padding for readbility ### Fixes - Fixed Android NDK build (thanks to @MoroccanMalinois) - Fix `ELPP_DISABLE_LOGS` not working in VS (thanks to @goloap) #365 ## [9.94.1] - 25-02-2017 ### Fixed - Fixes for `/W4` level warnings generated in MSVC compile (Thanks to [Falconne](https://github.com/Falconne)) - Fixed links - Fixes removing default logger if other than `default` ### Changes - Changed documentation to mention `easylogging++.cc` in introduction and added links to features ## [9.94.0] - 14-02-2017 ### Fixed - Fixed performance tracking time unit and calculations ### Added - Restored `ELPP_DEFAULT_LOGGER` and `ELPP_DEFAULT_PERFORMANCE_LOGGER` - `Helpers::getThreadName` for reading current thread name - Custom format specifier now has to return `std::string` instead - Merged `thread_name` with `thread` if thread name is available it's used otherwise ID is displayed For older versions please refer to [https://github.com/muflihun/easyloggingpp/tree/master/doc](https://github.com/muflihun/easyloggingpp/tree/master/doc) loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/CMakeLists.txt000066400000000000000000000053021325613023000275320ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.12) project(Easyloggingpp CXX) macro(require_cpp11) if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.0) # CMake 3.1 has built-in CXX standard checks. message("-- Setting C++11") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED on) else() if (CMAKE_CXX_COMPILER_ID MATCHES "GCC") message ("-- GNU CXX (-std=c++11)") list(APPEND CMAKE_CXX_FLAGS "-std=c++11") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") message ("-- CLang CXX (-std=c++11)") list(APPEND CMAKE_CXX_FLAGS "-std=c++11") else() message ("-- Easylogging++ requires C++11. Your compiler does not support it.") endif() endif() endmacro() option(test "Build all tests" OFF) option(build_static_lib "Build easyloggingpp as a static library" OFF) option(lib_utc_datetime "Build library with UTC date/time logging" OFF) set(ELPP_MAJOR_VERSION "9") set(ELPP_MINOR_VERSION "95") set(ELPP_PATCH_VERSION "0") set(ELPP_VERSION_STRING "${ELPP_MAJOR_VERSION}.${ELPP_MINOR_VERSION}.${ELPP_PATCH_VERSION}") set(ELPP_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) install(FILES src/easylogging++.h src/easylogging++.cc DESTINATION "${ELPP_INCLUDE_INSTALL_DIR}" COMPONENT dev) if (build_static_lib) if (lib_utc_datetime) add_definitions(-DELPP_UTC_DATETIME) endif() require_cpp11() add_library(easyloggingpp STATIC src/easylogging++.cc) install(TARGETS easyloggingpp ARCHIVE DESTINATION lib) endif() export(PACKAGE ${PROJECT_NAME}) ########################################## Unit Testing ################################### if (test) # We need C++11 require_cpp11() set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") find_package (gtest REQUIRED) include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) enable_testing() add_executable(easyloggingpp-unit-tests src/easylogging++.cc test/main.cc ) target_compile_definitions(easyloggingpp-unit-tests PUBLIC ELPP_FEATURE_ALL ELPP_LOGGING_FLAGS_FROM_ARG ELPP_NO_DEFAULT_LOG_FILE ELPP_FRESH_LOG_FILE ) # Standard linking to gtest stuff. target_link_libraries(easyloggingpp-unit-tests gtest gtest_main) add_test(NAME easyloggingppUnitTests COMMAND easyloggingpp-unit-tests -v) endif() loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/LICENCE000066400000000000000000000022051325613023000257560ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2017 muflihun.com https://github.com/muflihun/ https://muflihun.github.io https://muflihun.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/PULL_REQUEST_TEMPLATE.md000066400000000000000000000004031325613023000305700ustar00rootroot00000000000000### This is a - [ ] Breaking change - [ ] New feature - [ ] Bugfix ### I have - [ ] Merged in the latest upstream changes - [ ] Updated [`CHANGELOG.md`](CHANGELOG.md) - [ ] Updated [`README.md`](README.md) - [ ] [Run the tests](README.md#install-optional) loggedfs-loggedfs-0.9/vendor/github.com/muflihun/easyloggingpp/README.md000066400000000000000000002715671325613023000262730ustar00rootroot00000000000000 ‫بسم الله الرÙّحْمÙن٠الرÙّحÙÙÙ…Ù ![banner] > **Manual For v9.95.0** [![Build Status (Develop)](https://img.shields.io/travis/muflihun/easyloggingpp/develop.svg)](https://travis-ci.org/muflihun/easyloggingpp) (`develop`) [![Build Status (Master)](https://img.shields.io/travis/muflihun/easyloggingpp/master.svg)](https://travis-ci.org/muflihun/easyloggingpp) (`master`) [![Version](https://img.shields.io/github/release/muflihun/easyloggingpp.svg)](https://github.com/muflihun/easyloggingpp/releases/latest) [![Canon.io](https://img.shields.io/badge/conan.io-easyloggingpp%2F9.95.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](http://www.conan.io/source/easyloggingpp/9.95.0/memsharded/testing) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/rwDXGcnP1IoCKXrJ) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/muflihun/easyloggingpp/blob/master/LICENCE) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/MuflihunDotCom/25) [![Downloads](https://img.shields.io/github/downloads/muflihun/easyloggingpp/total.svg)](https://github.com/muflihun/easyloggingpp/releases/latest) ### Quick Links [![download] Latest Release](https://github.com/muflihun/easyloggingpp/releases/latest) [![notes] Changelog](/CHANGELOG.md) [![samples] Samples](/samples) --- ### Table of Contents
Introduction
    Why yet another library
    Features at a glance
Getting Started
    Download
    Quick Start
    Install (Optional)
    Setting Application Arguments
Configuration
    Level
    Configure
        Using Configuration File
        Using el::Configurations Class
        Using In line Configurations
    Default Configurations
    Global Configurations
    Logging Format Specifiers
    Date/Time Format Specifiers
    Custom Format Specifiers
    Logging Flags
    Application Arguments
    Configuration Macros
    Reading Configurations
Logging
    Basic
    Conditional Logging
    Occasional Logging
    printf Like Logging
    Network Logging
    Verbose Logging
        Basic
        Conditional and Occasional
        Verbose Level
        Check If Verbose Logging Is On
        VModule
    Registering New Loggers
    Unregister Loggers
    Populating Existing Logger IDs
    Sharing Logging Repository
Extra Features
    Performance Tracking
        Conditional Performance Tracking
        Make Use of Performance Tracking Data
    Log File Rotating
    Crash Handling
        Installing Custom Crash Handlers
    Stacktrace
    Multi-threading
    CHECK Macros
    Logging perror()
    Using Syslog
    STL Logging
        Supported Templates
    Qt Logging
    Boost Logging
    wxWidgets Logging
    Extending Library
        Logging Your Own Class
        Logging Third-party Class
    Manually Flushing and Rolling Log Files
    Log Dispatch Callback
    Logger Registration Callback
    Asynchronous Logging
    Helper Classes
Contribution
    Submitting Patches
    Reporting a Bug
Compatibility
Licence
Disclaimer
# Introduction Easylogging++ is single header efficient logging library for C++ applications. It is extremely powerful, highly extendable and configurable to user's requirements. It provides ability to [write your own sinks](https://github.com/muflihun/easyloggingpp/tree/master/samples/send-to-network) (referred to as `LogDispatchCallback`). Currently used by hundreds of open-source projects. This manual is for Easylogging++ v9.95.0. For other versions please refer to corresponding [release](https://github.com/muflihun/easyloggingpp/releases) on github. [![top] Goto Top](#table-of-contents) ### Why yet another library If you are working on a small utility or large project in C++, this library can be handy. Its based on single header and only requires to link to single source file. (Originally it was header-only and was changed to use source file in [issue #445](https://github.com/muflihun/easyloggingpp/issues/445). You can still use header-only in [v9.89](https://github.com/muflihun/easyloggingpp/releases/tag/9.89)). This library has been designed with various thoughts in mind (i.e, portability, performance, usability, features and easy to setup). Why yet another library? Well, answer is pretty straight forward, use it as you wrote it so you can fix issues (if any) as you go or raise them on github. In addition to that, I personally have not seen any logging library based on single-header with such a design where you can configure on the go, extend it to your needs and get fast performance. I have seen other single-header logging libraries for C++ but either they use external libraries, e.g, boost or Qt to support certain features like threading, regular expression or date etc. This library has everything built-in to prevent usage of external libraries, not that I don't like those libraries, in fact I love them, but because not all projects use these libraries, I couldn't take risk of depending on them. [![top] Goto Top](#table-of-contents) ### Features at a glance Easylogging++ is feature-rich containing many features that both typical and advanced developer will require while writing a software; * [Highly configurable](#configuration) * [Extendable](#log-dispatch-callback) * Extremely fast * [Thread](#multi-threading) and type safe * [Cross-platform](#compatibility) * [Custom log patterns](#logging-format-specifiers) * [Conditional and occasional logging](#conditional-logging) * [Performance tracking](#performance-tracking) * [Verbose logging](#verbose-logging) * [Crash handling](#crash-handling) * [Helper CHECK macros](#check-macros) * [STL logging](#stl-logging) * [Send to Syslog](#syslog) * [Third-party library logging (Qt, boost, wxWidgets etc)](#logging-third-party-class) * [Extensible (Logging your own class or third-party class)](#logging-your-own-class) * [And many more...](#extra-features) [![top] Goto Top](#table-of-contents) # Getting Started ### Download Download latest version from [Latest Release](https://github.com/muflihun/easyloggingpp/releases/latest) For other releases, please visit [releases page](https://github.com/muflihun/easyloggingpp/releases). If you application does not support C++11, please consider using [v8.91](https://github.com/muflihun/easyloggingpp/tree/v8.91). This is stable version for C++98 and C++03, just lack some features. [![top] Goto Top](#table-of-contents) ### Quick Start In order to get started with Easylogging++, you can follow three easy steps: * Download latest version * Include into your project (`easylogging++.h` and `easylogging++.cc`) * Initialize using single macro... and off you go! ```c++ #include "easylogging++.h" INITIALIZE_EASYLOGGINGPP int main(int argc, char* argv[]) { LOG(INFO) << "My first info log using default logger"; return 0; } ``` Now compile using ``` g++ main.cc easylogging++.cc -o prog -std=c++11 ``` That simple! Please note that `INITIALIZE_EASYLOGGINGPP` should be used once and once-only otherwise you will end up getting compilation errors. This is definiting several `extern` variables. This means it can be defined only once per application. Best place to put this initialization statement is in file where `int main(int, char**)` function is defined, right after last include statement. ### Install (Optional) If you want to install this header system-wide, you can do so via: ``` mkdir build cd build cmake -Dtest=ON ../ make make test make install ``` Following options are supported by Easylogging++ cmake and you can turn these options on using `-D