--- Begin Message ---
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) ) {
signature.asc
Description: Digital signature
--- End Message ---