aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Curtin <ericcurtin17@gmail.com>2020-02-01 23:30:31 +0000
committerGitHub <noreply@github.com>2020-02-01 23:30:31 +0000
commit33c4bc444d34df46178949a66a0479cfeaf58ae9 (patch)
tree9e1735b792e3f2999ed9a170f9f1f87151fa3d7c
parentf4196688d8187162fd178892c3d75c7a8e88ac88 (diff)
downloadinotify-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.c16
-rw-r--r--libinotifytools/src/inotifytools/inotifytools.h3
-rw-r--r--src/inotifywait.c64
-rw-r--r--src/inotifywatch.c62
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, &regex, &iregex, &execute) ) {
+ &recursive, &csv, &dodaemon, &syslog, &verbose,
+ &format, &timefmt, &fromfile, &outfile, &regex,
+ &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, &regex, &iregex ) ) {
+ if ( !parse_opts( &argc, &argv, &events, &timeout,
+ &verbose, &zero, &sort, &recursive, &fromfile,
+ &regex, &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"