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