Package: inoticoming
Version: 0.1.1-1
Severity: minor

It would be nice if inoticoming could perform its actions against files
already existing in the monitored directory when it starts, so I've
coded such a feature and attached a diff.

The patch also updates the syntax() function to match the man page.

I also noticed that the man page states "Note that since it is a well-
behaved daemon, its working directory is / which will be inherited by
all actions", but in fact the daemon never invokes chdir("/"); so I
added such a call.

-- 
Robert Edmonds
[EMAIL PROTECTED]
diff -pru inoticoming-0.1.1/inoticoming.1 inoticoming-0.1.1.initial/inoticoming.1
--- inoticoming-0.1.1/inoticoming.1	2007-07-14 06:21:17.000000000 -0400
+++ inoticoming-0.1.1.initial/inoticoming.1	2007-08-17 15:54:13.940325381 -0400
@@ -19,6 +19,9 @@ a directory and call \fBreprepro\fP to p
 .B \-\-foreground
 Do not fork, but stay in the foreground and log to stderr.
 .TP
+.B \-\-initial
+Process matching files which are initially present.
+.TP
 .B \-\-logfile \fIfilename\fP
 After forking in the background, log to the specified
 .I filename
diff -pru inoticoming-0.1.1/inoticoming.c inoticoming-0.1.1.initial/inoticoming.c
--- inoticoming-0.1.1/inoticoming.c	2007-07-25 05:21:15.000000000 -0400
+++ inoticoming-0.1.1.initial/inoticoming.c	2007-08-17 15:57:59.845198966 -0400
@@ -29,6 +29,8 @@
 #include <getopt.h>
 #include <syslog.h>
 #include <signal.h>
+#include <dirent.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 #ifdef HAVE_SYS_INOTIFY_H
 #include <sys/inotify.h>
@@ -317,6 +319,24 @@ static void doaction(const struct lookfo
 	execvp(args[0],args);
 }
 
+static bool shouldprocess(const struct lookfor *l, const char *filename) {
+	bool process = true;
+	size_t len = strlen(filename);
+	/* does not start or end as it should */
+	if( l->prefix != NULL && (len < l->prefixlen ||
+		memcmp(filename, l->prefix, l->prefixlen) != 0 ))
+		process = false;
+	if( l->suffix != NULL && (len < l->suffixlen ||
+		memcmp(filename+len-l->suffixlen, l->suffix, l->suffixlen) != 0 ))
+		process = false;
+	/* if there is a regexp, and it does not match, don't */
+	if( l->regexp != NULL ) {
+		if( regexec(&l->reg, filename, 0, NULL, 0) != 0 )
+			process = false;
+	}
+	return process;
+}
+
 static void processevent(const struct inotify_event *event) {
 	const struct lookfor *l;
 
@@ -343,22 +363,36 @@ static void processevent(const struct in
 		return;
 
 	for( l = lookfor ; l != NULL ; l = l->next ) {
-		size_t len = strlen(event->name);
+		if( shouldprocess(l, event->name) )
+			doaction(l, event->name);
+	}
+}
 
-		/* does not start or end as it should */
-		if( l->prefix != NULL && (len < l->prefixlen ||
-		    memcmp(event->name, l->prefix, l->prefixlen) != 0 ))
-			continue;
-		if( l->suffix != NULL && (len < l->suffixlen ||
-		    memcmp(event->name+len-l->suffixlen, l->suffix, l->suffixlen) != 0 ))
+static void processinitial(const char *directory) {
+	struct lookfor *l;
+	DIR *dir;
+	struct dirent *de;
+	struct stat sb;
+
+	dir = opendir(directory);
+	if( dir == NULL )
+		logerror_die("Error opening directory %s: %s(%d)\n",
+			directory, strerror(errno), errno);
+	while( (de = readdir(dir)) != NULL ) {
+		chdir(directory);
+		if( stat(de->d_name, &sb) == -1 ) {
+			logerror("Unable to stat %s: %s(%d)\n",
+				de->d_name, strerror(errno), errno);
+			chdir("..");
 			continue;
-		/* if there is a regexp, and it does not match, don't */
-		if( l->regexp != NULL ) {
-			if( regexec(&l->reg, event->name, 0, NULL, 0) != 0 )
-				continue;
 		}
-		doaction(l, event->name);
+		chdir("..");
+		if( (sb.st_mode & S_IFMT) == S_IFREG )
+			for( l = lookfor ; l != NULL ; l = l->next )
+				if( shouldprocess(l, de->d_name) )
+					doaction(l, de->d_name);
 	}
+	closedir(dir);
 }
 
 static inline char *xstrdup(const char *s) {
@@ -528,8 +562,20 @@ static void parseaction(int argc, char *
 
 static void syntax(FILE *file, int exitcode) {
 	fprintf(file,
-"Syntax: %s [--logfile <file>] [--foreground] <directory to watch> <actions>\n"
-"where action is: [--regexp <regexp>] [--chdir <dir>] command [<arguments>] ;\n",
+"Syntax: %s\n"
+"\t[--foreground]\n"
+"\t[--initial]\n"
+"\t[--logfile <file>]\n"
+"\t[--pid-file <file>]\n"
+"\t<directory to watch> <actions>\n"
+"where action is:\n"
+"\t[--prefix <string>]\n"
+"\t[--suffix <string>]\n"
+"\t[--regexp <regexp>]\n"
+"\t[--chdir <dir>]\n"
+"\t[--stdout-to-log]\n"
+"\t[--stderr-to-log]\n"
+"\tcommand [<arguments>] ;\n",
 			program);
 	exit(exitcode);
 }
@@ -542,11 +588,13 @@ int main(int argc, char * const argv[]) 
 	int timeout, e, opt;
 	struct inotify_event *event;
 	FILE *pidfile;
+	bool initial = false;
 	static const struct option global_long_options[] = {
 		{ "version",	no_argument,		NULL, 1},
 		{ "help",	no_argument,		NULL, 'h'},
 		{ "logfile",	required_argument,	NULL, 'l'},
 		{ "foreground",	no_argument,		NULL, 'F'},
+		{ "initial",	no_argument,		NULL, 'i'},
 		{ "pid-file",	required_argument,	NULL, 'p'},
 		{ NULL,	0, NULL, 0}
 	};
@@ -580,6 +628,9 @@ int main(int argc, char * const argv[]) 
 			case 'F':
 				foreground = true;
 				break;
+			case 'i':
+				initial = true;
+				break;
 			case '?':
 				if( optopt == '\0' )
 					logerror_die("Unknown/ambiguous global option '%s'!\n",
@@ -656,6 +707,11 @@ int main(int argc, char * const argv[]) 
 	signal(SIGTERM, termsignal);
 	signal(SIGABRT, termsignal);
 
+	if( initial )
+		processinitial(directory);
+	
+	chdir("/");
+
 	timeout = -1;
 	while( !termsignaled ) {
 		if( waitforevent(notifd, timeout) ) {

Attachment: signature.asc
Description: Digital signature

Reply via email to