Subject: [alpine-aports] [PATCH] testing/inotify-tools-inc: new aport (with --include regex)

From: Stuart Cardall <[email-masked]>
Date: Sun, 10 May 2015 21:46:06 +0000

This is inotify-tools patched to add --include & --includei regexes

I've been testing it watching for a specific file. The --exclude
regexes still work too.
---
 testing/inotify-tools-inc/APKBUILD                |  59 ++++
 testing/inotify-tools-inc/add-include-regex.patch | 365 ++++++++++++++++++++++
 2 files changed, 424 insertions(+)
 create mode 100644 testing/inotify-tools-inc/APKBUILD
 create mode 100644 testing/inotify-tools-inc/add-include-regex.patch

diff --git a/testing/inotify-tools-inc/APKBUILD b/testing/inotify-tools-inc/APKBUILD
new file mode 100644
index 0000000..78e6220
--- /dev/null
+++ b/testing/inotify-tools-inc/APKBUILD
@@ -0,0 +1,59 @@
+# Contributor: Stuart Cardall <[email-masked]>
+# Maintainer: Stuart Cardall <[email-masked]>
+pkgname="inotify-tools-inc"
+_realname="${pkgname%*-inc}"
+pkgver=3.14
+pkgrel=0
+pkgdesc="inotify-tools patched to add --include regex"
+url="http://github.com/rvoicilas/inotify-tools"
+arch="all"
+license="GPL2"
+replaces="inotify-tools"
+subpackages="$pkgname-dev $pkgname-doc"
+source="https://github.com/downloads/rvoicilas/$_realname/$_realname-$pkgver.tar.gz
+	add-include-regex.patch
+	"
+
+_builddir="$srcdir"/$_realname-$pkgver
+prepare() {
+	local i
+        cd "$_builddir"
+        for i in $source; do
+                case $i in
+                *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+                esac
+        done
+}
+
+build() {
+	cd "$_builddir"
+	./configure --prefix=/usr \
+		--sysconfdir=/etc \
+		--mandir=/usr/share/man \
+		--infodir=/usr/share/info \
+		|| return 1
+	make || return 1
+}
+
+package() {
+	cd "$_builddir"
+	make DESTDIR="$pkgdir" install || return 1
+	rm "$pkgdir"/usr/lib/*.la || return 1
+	# post-install message
+	mkdir -p "$pkgdir/usr/share/doc/$pkgname"
+        cat > $pkgdir/usr/share/doc/$pkgname/example.sh <<EOF
+#!/bin/sh
+## watch for a specific file recursively ##
+inotifywait -mr -e modify /path/to/watch --include="(my.file)$" |
+while read path action file; do
+	echo "The file '$file' appeared in directory '$path' via '$action'"
+done
+EOF
+}
+
+md5sums="b43d95a0fa8c45f8bab3aec9672cf30c  inotify-tools-3.14.tar.gz
+72f3ffd0d57ddb2b6b38faaa3b751ca8  add-include-regex.patch"
+sha256sums="222bcca8893d7bf8a1ce207fb39ceead5233b5015623d099392e95197676c92f  inotify-tools-3.14.tar.gz
+5b193b9b5cbd16d4aca9ce843a8493191cbf825598978a2602180fc28d56ffd7  add-include-regex.patch"
+sha512sums="6074d510e89bba5da0d7c4d86f2562c662868666ba0a7ea5d73e53c010a0050dd1fc01959b22cffdb9b8a35bd1b0b43c04d02d6f19927520f05889e8a9297dfb  inotify-tools-3.14.tar.gz
+b858b79dcfb2967d0c8d31ecbc17f4f36064218d2276fdafcdc6c8e51c9db2645fa102f88f1401b78f79a1b2ddbe400ea3e691bf93d084ecb312a170f69bda24  add-include-regex.patch"
diff --git a/testing/inotify-tools-inc/add-include-regex.patch b/testing/inotify-tools-inc/add-include-regex.patch
new file mode 100644
index 0000000..31833e0
--- /dev/null
+++ b/testing/inotify-tools-inc/add-include-regex.patch
@@ -0,0 +1,365 @@
+### adapted from https://github.com/rvoicilas/inotify-tools/pull/28 ###
+diff -urp inotify-tools-3.14/libinotifytools/src/inotifytools/inotifytools.h inotify-tools.new/libinotifytools/src/inotifytools/inotifytools.h
+--- inotify-tools-3.14/libinotifytools/src/inotifytools/inotifytools.h	2010-03-12 13:53:46.000000000 +0000
++++ inotify-tools.new/libinotifytools/src/inotifytools/inotifytools.h	2015-05-10 02:22:22.971561931 +0000
+@@ -28,7 +28,7 @@ int inotifytools_watch_recursively_with_
+                                                  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 -urp inotify-tools-3.14/libinotifytools/src/inotifytools.c inotify-tools.new/libinotifytools/src/inotifytools.c
+--- inotify-tools-3.14/libinotifytools/src/inotifytools.c	2010-03-12 13:53:46.000000000 +0000
++++ inotify-tools.new/libinotifytools/src/inotifytools.c	2015-05-10 02:21:08.839560752 +0000
+@@ -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
+ 	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,7 @@ 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 +2016,10 @@ int inotifytools_ignore_events_by_regex(
+ 	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 -urp inotify-tools-3.14/src/inotifywait.c inotify-tools.new/src/inotifywait.c
+--- inotify-tools-3.14/src/inotifywait.c	2010-03-12 13:53:46.000000000 +0000
++++ inotify-tools.new/src/inotifywait.c	2015-05-10 16:53:20.384393049 +0000
+@@ -48,7 +48,9 @@ bool parse_opts(
+   char ** fromfile,
+   char ** outfile,
+   char ** regex,
+-  char ** iregex
++  char ** iregex,
++  char ** include_regex,
++  char ** include_iregex
+ );
+ 
+ void print_help();
+@@ -157,16 +159,29 @@ int main(int argc, char ** argv)
+ 	char * outfile = NULL;
+ 	char * regex = NULL;
+ 	char * iregex = NULL;
++	char * include_regex = NULL;
++	char * include_iregex = NULL;
++	bool invert_regex = false;
+ 	pid_t pid;
+     int fd;
+ 
+ 	// Parse commandline options, aborting if something goes wrong
+ 	if ( !parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout,
+-	                 &recursive, &csv, &daemon, &syslog, &format, &timefmt, 
+-                         &fromfile, &outfile, &regex, &iregex) ) {
++			&recursive, &csv, &daemon, &syslog, &format, &timefmt,
++			&fromfile, &outfile, &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 ( !inotifytools_initialize() ) {
+ 		fprintf(stderr, "Couldn't initialize inotify.  Are you running Linux "
+ 		                "2.6.13 or later, and was the\n"
+@@ -180,11 +195,11 @@ int main(int argc, char ** argv)
+ 
+ 	if ( timefmt ) inotifytools_set_printf_timefmt( timefmt );
+ 	if (
+-		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) ||
++		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED, invert_regex) ) ||
+ 		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
+-		                                                        REG_ICASE))
++									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;
+ 	}
+ 
+@@ -423,18 +438,20 @@ bool parse_opts(
+   char ** fromfile,
+   char ** outfile,
+   char ** regex,
+-  char ** iregex
++  char ** iregex,
++  char ** include_regex,
++  char ** include_iregex
+ ) {
+ 	assert( argc ); assert( argv ); assert( events ); assert( monitor );
+ 	assert( quiet ); assert( timeout ); assert( csv ); assert( daemon );
+-	assert( syslog ); assert( format ); assert( timefmt ); assert( fromfile ); 
++	assert( syslog ); assert( format ); assert( timefmt ); assert( fromfile );
+ 	assert( outfile ); assert( regex ); assert( iregex );
+ 
+ 	// Short options
+ 	char * opt_string = "mrhcdsqt:fo:e:";
+ 
+ 	// Construct array
+-	struct option long_opts[17];
++	struct option long_opts[19];
+ 
+ 	// --help
+ 	long_opts[0].name = "help";
+@@ -520,11 +537,21 @@ bool parse_opts(
+ 	long_opts[15].has_arg = 1;
+ 	long_opts[15].flag = NULL;
+ 	long_opts[15].val = (int)'b';
++	// --include
++	long_opts[16].name = "include";
++	long_opts[16].has_arg = 1;
++	long_opts[16].flag = NULL;
++	long_opts[16].val = (int)'j';
++	// --includei
++	long_opts[17].name = "includei";
++	long_opts[17].has_arg = 1;
++	long_opts[17].flag = NULL;
++	long_opts[17].val = (int)'k';
+ 	// Empty last element
+-	long_opts[16].name = 0;
+-	long_opts[16].has_arg = 0;
+-	long_opts[16].flag = 0;
+-	long_opts[16].val = 0;
++	long_opts[18].name = 0;
++	long_opts[18].has_arg = 0;
++	long_opts[18].flag = 0;
++	long_opts[18].val = 0;
+ 
+ 	// Get first option
+ 	char curr_opt = getopt_long(*argc, *argv, opt_string, long_opts, NULL);
+@@ -604,6 +631,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) {
+@@ -671,6 +708,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;
+@@ -715,6 +762,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 -urp inotify-tools-3.14/src/inotifywatch.c inotify-tools.new/src/inotifywatch.c
+--- inotify-tools-3.14/src/inotifywatch.c	2010-03-12 13:53:46.000000000 +0000
++++ inotify-tools.new/src/inotifywatch.c	2015-05-10 16:51:40.060391453 +0000
+@@ -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,34 @@ 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 ) ) {
++			&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) ) ||
++		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED, invert_regex) ) ||
+ 		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
+-		                                                        REG_ICASE))
++									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 +405,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 );
+@@ -400,7 +417,7 @@ bool parse_opts(
+ 	char * opt_string = "hra:d:zve:t:";
+ 
+ 	// Construct array
+-	struct option long_opts[12];
++	struct option long_opts[14];
+ 
+ 	// --help
+ 	long_opts[0].name = "help";
+@@ -460,11 +477,21 @@ bool parse_opts(
+ 	long_opts[10].has_arg = 1;
+ 	long_opts[10].flag = NULL;
+ 	long_opts[10].val = (int)'b';
++	// --include
++	long_opts[11].name = "include";
++	long_opts[11].has_arg = 1;
++	long_opts[11].flag = NULL;
++	long_opts[11].val = (int)'j';
++	// --includei
++	long_opts[12].name = "includei";
++	long_opts[12].has_arg = 1;
++	long_opts[12].flag = NULL;
++	long_opts[12].val = (int)'k';
+ 	// Empty last element
+-	long_opts[11].name = 0;
+-	long_opts[11].has_arg = 0;
+-	long_opts[11].flag = 0;
+-	long_opts[11].val = 0;
++	long_opts[13].name = 0;
++	long_opts[13].has_arg = 0;
++	long_opts[13].flag = 0;
++	long_opts[13].val = 0;
+ 
+ 	// Get first option
+ 	char curr_opt = getopt_long(*argc, *argv, opt_string, long_opts, NULL);
+@@ -506,6 +533,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) {
+@@ -625,6 +662,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 ? returned, invalid option
+ 	return (curr_opt != '?');
+ }
+@@ -647,6 +694,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"
-- 
2.4.0

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---