diff options
author | Eric Curtin <ericcurtin17@gmail.com> | 2020-02-01 23:30:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-01 23:30:31 +0000 |
commit | 33c4bc444d34df46178949a66a0479cfeaf58ae9 (patch) | |
tree | 9e1735b792e3f2999ed9a170f9f1f87151fa3d7c | |
parent | f4196688d8187162fd178892c3d75c7a8e88ac88 (diff) | |
download | inotify-tools-next.zip inotify-tools-next.tar.gz inotify-tools-next.tar.bz2 |
Add an additional `invert` argument to libinotifytools' `inotifytools_ignore_events_by_regex`, which allows the ignore logic in the RETURN(A) macro to be optionally negated. (#28)next
In `inotifywatch` and `inotifywait`, add `--include` and `--includei` options, allowing regular expressions typically used with `--exclude` and `--excludei` to be easily negated.
-rw-r--r-- | libinotifytools/src/inotifytools.c | 16 | ||||
-rw-r--r-- | libinotifytools/src/inotifytools/inotifytools.h | 3 | ||||
-rw-r--r-- | src/inotifywait.c | 64 | ||||
-rw-r--r-- | src/inotifywatch.c | 62 |
4 files changed, 124 insertions, 21 deletions
diff --git a/libinotifytools/src/inotifytools.c b/libinotifytools/src/inotifytools.c index b3feca3..a24c6dc 100644 --- a/libinotifytools/src/inotifytools.c +++ b/libinotifytools/src/inotifytools.c @@ -149,6 +149,7 @@ static int error = 0; static int init = 0; static char* timefmt = 0; static regex_t* regex = 0; +static int invert_regex = 0; int isdir( char const * path ); void record_stats( struct inotify_event const * event ); @@ -1103,12 +1104,14 @@ struct inotify_event * inotifytools_next_events( int timeout, int num_events ) { static ssize_t bytes; static jmp_buf jmp; static char match_name[MAX_STRLEN]; + static int rv; #define RETURN(A) {\ if (regex) {\ inotifytools_snprintf(match_name, MAX_STRLEN, A, "%w%f");\ - if (0 == regexec(regex, match_name, 0, 0, 0)) {\ - longjmp(jmp,0);\ + rv = regexec(regex, match_name, 0, 0, 0); \ + if ((!invert_regex && 0 == rv) || (invert_regex && 0 != rv)) { \ + longjmp(jmp,0); \ }\ }\ if ( collect_stats ) {\ @@ -1999,7 +2002,8 @@ int inotifytools_get_max_user_watches() { * events occur. If the regular expression matches, the matched event will be * ignored. */ -int inotifytools_ignore_events_by_regex( char const *pattern, int flags ) { +int inotifytools_ignore_events_by_regex( char const *pattern, + int flags, int invert ) { if (!pattern) { if (regex) { regfree(regex); @@ -2013,7 +2017,11 @@ int inotifytools_ignore_events_by_regex( char const *pattern, int flags ) { else { regex = (regex_t *)malloc(sizeof(regex_t)); } int ret = regcomp(regex, pattern, flags | REG_NOSUB); - if (0 == ret) return 1; + + if (0 == ret) { + invert_regex = invert; + return 1; + } regfree(regex); free(regex); diff --git a/libinotifytools/src/inotifytools/inotifytools.h b/libinotifytools/src/inotifytools/inotifytools.h index e48f25e..e48dfea 100644 --- a/libinotifytools/src/inotifytools/inotifytools.h +++ b/libinotifytools/src/inotifytools/inotifytools.h @@ -28,7 +28,8 @@ int inotifytools_watch_recursively_with_exclude( char const * path, int events, char const ** exclude_list ); // [UH] -int inotifytools_ignore_events_by_regex( char const *pattern, int flags ); +int inotifytools_ignore_events_by_regex( char const *pattern, + int flags, int invert ); struct inotify_event * inotifytools_next_event( int timeout ); struct inotify_event * inotifytools_next_events( int timeout, int num_events ); int inotifytools_error(); diff --git a/src/inotifywait.c b/src/inotifywait.c index ed2f2ce..1184e8f 100644 --- a/src/inotifywait.c +++ b/src/inotifywait.c @@ -50,7 +50,9 @@ bool parse_opts( char ** outfile, char ** regex, char ** iregex, - char ** execute + char ** execute, + char ** include_regex, + char ** include_iregex ); void print_help(); @@ -145,7 +147,7 @@ void output_error( bool syslog, char* fmt, ... ) { int main(int argc, char ** argv) { int events = 0; - int orig_events; + int orig_events; bool monitor = false; int quiet = 0; unsigned long int timeout = 0; @@ -160,19 +162,33 @@ int main(int argc, char ** argv) char * outfile = NULL; char * regex = NULL; char * iregex = NULL; + char * include_regex = NULL; + char * include_iregex = NULL; char * execute = NULL; + bool invert_regex = false; int fd; // Parse commandline options, aborting if something goes wrong if ( !parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout, - &recursive, &csv, &dodaemon, &syslog, &verbose, &format, &timefmt, - &fromfile, &outfile, ®ex, &iregex, &execute) ) { + &recursive, &csv, &dodaemon, &syslog, &verbose, + &format, &timefmt, &fromfile, &outfile, ®ex, + &iregex, &include_regex, &include_iregex, &execute) ) { return EXIT_FAILURE; } if (verbose) fprintf(stderr, "Running verbosely. \n"); + if (include_regex) { + regex = include_regex; + invert_regex = true; + } + + if (include_iregex) { + iregex = include_iregex; + invert_regex = true; + } + if ( !inotifytools_initialize() ) { fprintf(stderr, "Couldn't initialize inotify. Are you running Linux " "2.6.13 or later, and was the\n" @@ -186,11 +202,14 @@ int main(int argc, char ** argv) if ( timefmt ) inotifytools_set_printf_timefmt( timefmt ); if ( - (regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) || - (iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED| - REG_ICASE)) + (regex && !inotifytools_ignore_events_by_regex(regex, + REG_EXTENDED, + invert_regex) ) || + (iregex && !inotifytools_ignore_events_by_regex(iregex, + REG_EXTENDED|REG_ICASE, + invert_regex)) ) { - fprintf(stderr, "Error in `exclude' regular expression.\n"); + fprintf(stderr, "Error in `exclude' or `include' regular expression.\n"); return EXIT_FAILURE; } @@ -454,6 +473,8 @@ bool parse_opts( char ** outfile, char ** regex, char ** iregex, + char ** include_regex, + char ** include_iregex, char ** execute ) { assert( argc ); assert( argv ); assert( events ); assert( monitor ); @@ -489,6 +510,8 @@ bool parse_opts( {"outfile", required_argument, NULL, 'o'}, {"exclude", required_argument, NULL, 'a'}, {"excludei", required_argument, NULL, 'b'}, + {"include", required_argument, NULL, 'j'}, + {"includei", required_argument, NULL, 'k'}, {"execute", required_argument, NULL, 'x'}, {NULL, 0, 0, 0}, }; @@ -576,6 +599,16 @@ bool parse_opts( (*iregex) = optarg; break; + // --include + case 'j': + (*include_regex) = optarg; + break; + + // --includei + case 'k': + (*include_iregex) = optarg; + break; + // --fromfile case 'z': if (*fromfile) { @@ -646,6 +679,16 @@ bool parse_opts( return false; } + if ( *include_regex && *include_iregex ) { + fprintf(stderr, "--include and --includei cannot both be specified.\n"); + return false; + } + + if ( ( *include_regex || *include_iregex ) && ( *regex || *iregex ) ) { + fprintf(stderr, "Cannot use include and exclude options simultaneously.\n"); + return false; + } + if ( *format && *csv ) { fprintf(stderr, "-c and --format cannot both be specified.\n"); return false; @@ -690,6 +733,11 @@ void print_help() "\t \textended regular expression <pattern>.\n"); printf("\t--excludei <pattern>\n" "\t \tLike --exclude but case insensitive.\n"); + printf("\t--include <pattern>\n" + "\t \tInclude all events on only those files matching\n" + "\t \tthe extended regular expression <pattern>.\n"); + printf("\t--includei <pattern>\n" + "\t \tLike --include but case insensitive.\n"); printf("\t-m|--monitor \tKeep listening for events forever. Without\n" "\t \tthis option, inotifywait will exit after one\n" "\t \tevent is received.\n"); diff --git a/src/inotifywatch.c b/src/inotifywatch.c index 72b9733..6622e41 100644 --- a/src/inotifywatch.c +++ b/src/inotifywatch.c @@ -43,7 +43,9 @@ bool parse_opts( int * recursive, char ** fromfile, char ** regex, - char ** iregex + char ** iregex, + char ** include_regex, + char ** include_iregex ); void print_help(); @@ -91,21 +93,37 @@ int main(int argc, char ** argv) done = false; char * regex = NULL; char * iregex = NULL; + char * include_regex = NULL; + char * include_iregex = NULL; + bool invert_regex = false; signal( SIGINT, handle_impatient_user ); // Parse commandline options, aborting if something goes wrong - if ( !parse_opts( &argc, &argv, &events, &timeout, &verbose, &zero, &sort, - &recursive, &fromfile, ®ex, &iregex ) ) { + if ( !parse_opts( &argc, &argv, &events, &timeout, + &verbose, &zero, &sort, &recursive, &fromfile, + ®ex, &iregex, &include_regex, &include_iregex ) ) { return EXIT_FAILURE; } + if (include_regex) { + regex = include_regex; + invert_regex = true; + } + + if (include_iregex) { + iregex = include_iregex; + invert_regex = true; + } if ( - (regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) || - (iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED| - REG_ICASE)) + (regex && !inotifytools_ignore_events_by_regex(regex, + REG_EXTENDED, + invert_regex) ) || + (iregex && !inotifytools_ignore_events_by_regex(iregex, + REG_EXTENDED|REG_ICASE, + invert_regex)) ) { - fprintf(stderr, "Error in `exclude' regular expression.\n"); + fprintf(stderr, "Error in `exclude' or `include' regular expression.\n"); return EXIT_FAILURE; } @@ -390,7 +408,9 @@ bool parse_opts( int * recursive, char ** fromfile, char ** regex, - char ** iregex + char ** iregex, + char ** include_regex, + char ** include_iregex ) { assert( argc ); assert( argv ); assert( events ); assert( timeout ); assert( verbose ); assert( zero ); assert( sort ); assert( recursive ); @@ -417,6 +437,8 @@ bool parse_opts( {"fromfile", required_argument, NULL, 'o'}, {"exclude", required_argument, NULL, 'c'}, {"excludei", required_argument, NULL, 'b'}, + {"include", required_argument, NULL, 'j'}, + {"includei", required_argument, NULL, 'k'}, {NULL, 0, 0, 0}, }; @@ -460,6 +482,16 @@ bool parse_opts( (*iregex) = optarg; break; + // --include + case 'j': + (*include_regex) = optarg; + break; + + // --includei + case 'k': + (*include_iregex) = optarg; + break; + // --fromfile case 'o': if (*fromfile) { @@ -579,6 +611,15 @@ bool parse_opts( return false; } + if ( *include_regex && *include_iregex ) { + fprintf(stderr, "--include and --includei cannot both be specified.\n"); + return false; + } + + if ( ( *include_regex || *include_iregex ) && ( *regex || *iregex ) ) { + fprintf(stderr, "Cannot use include and exclude options simultaneously.\n"); + return false; + } // If ? returned, invalid option return (curr_opt != '?'); } @@ -601,6 +642,11 @@ void print_help() "\t\texpression <pattern>.\n"); printf("\t--excludei <pattern>\n" "\t\tLike --exclude but case insensitive.\n"); + printf("\t--include <pattern>\n" + "\t\tInclude all events only those files matching the extended\n" + "\t\tregular expression <pattern>.\n"); + printf("\t--includei <pattern>\n" + "\t\tLike --include but case insensitive.\n"); printf("\t-z|--zero\n" "\t\tIn the final table of results, output rows and columns even\n" "\t\tif they consist only of zeros (the default is to not output\n" |