commit 9fd06b0d1bdbc8cac24a9dd9a0bce8fe570a512f
parent 496ea93e3942b856d01b7a955c6e069b3828644b
Author: z3bra <willy@mailoo.org>
Date: Mon, 30 Mar 2015 20:43:57 +0200
formatting: 4 spaces -> 8 tabs
Diffstat:
M | wendy.c | | | 382 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
1 file changed, 188 insertions(+), 194 deletions(-)
diff --git a/wendy.c b/wendy.c
@@ -27,13 +27,12 @@
/* maximum number of event * queuing at the same time */
#define BUF_LEN (512 * (EVENT_SIZE+16))
-#define DEFAULT_FILE "." /* defaults to current directory */
#define DEFAULT_CHECK 1 /* defaults to 1 second */
struct node_t {
- int wd;
- char path[PATH_MAX];
- struct node_t *next;
+ int wd;
+ char path[PATH_MAX];
+ struct node_t *next;
};
extern char **environ;
@@ -41,233 +40,228 @@ extern char **environ;
int verbose = 0, nb = 0;
struct node_t *head = NULL;
- void
+ void
usage()
{
- fputs("usage: wendy [-C] [-D] [-M] [-m mask] [-l] [-f file] [-t timeout] [-q] "
- "[-e command [args] ..]\n"
- "\t-C : raise creation events (default)\n"
- "\t-D : raise deletion events\n"
- "\t-M : raise modification events\n"
- "\t-m mask : set mask manually (see -l))\n"
- "\t-l : list events mask values\n"
- "\t-f file : file to watch (everything is a file)\n"
- "\t-t timeout : time between event check (in seconds)\n"
- "\t-v : talk to me, program\n"
- "\t-e command : command to launch (must be the last argument!)\n",
- stdout);
- exit(1);
+ fputs("usage: wendy [-m mask] [-l] [-f file] [-t timeout] [-q] "
+ "[-e command [args] ..]\n"
+ "\t-m mask : set mask manually (see -l))\n"
+ "\t-l : list events mask values\n"
+ "\t-f file : file to watch (everything is a file)\n"
+ "\t-t timeout : time between event check (in seconds)\n"
+ "\t-v : talk to me, program\n"
+ "\t-e command : command to launch (must be the last arg!)\n",
+ stdout);
+ exit(1);
}
- void
+ void
list_events()
{
- fprintf(stdout,
- "IN_ACCESS ........ %u\n"
- "IN_MODIFY ........ %u\n"
- "IN_ATTRIB ........ %u\n"
- "IN_CLOSE_WRITE ... %u\n"
- "IN_CLOSE_NOWRITE . %u\n"
- "IN_OPEN .......... %u\n"
- "IN_MOVED_FROM .... %u\n"
- "IN_MOVED_TO ...... %u\n"
- "IN_CREATE ........ %u\n"
- "IN_DELETE ........ %u\n"
- "IN_DELETE_SELF ... %u\n"
- "IN_MOVE_SELF ..... %u\n"
- "IN_ALL_EVENTS .... %u\n"
- "IN_UNMOUNT ....... %u\n",
- IN_ACCESS,
- IN_MODIFY,
- IN_ATTRIB,
- IN_CLOSE_WRITE,
- IN_CLOSE_NOWRITE,
- IN_OPEN,
- IN_MOVED_FROM,
- IN_MOVED_TO,
- IN_CREATE,
- IN_DELETE,
- IN_DELETE_SELF,
- IN_MOVE_SELF,
- IN_ALL_EVENTS,
- IN_UNMOUNT
- );
- exit(0);
+ fprintf(stdout,
+ "IN_ACCESS ........ %u\n"
+ "IN_MODIFY ........ %u\n"
+ "IN_ATTRIB ........ %u\n"
+ "IN_CLOSE_WRITE ... %u\n"
+ "IN_CLOSE_NOWRITE . %u\n"
+ "IN_OPEN .......... %u\n"
+ "IN_MOVED_FROM .... %u\n"
+ "IN_MOVED_TO ...... %u\n"
+ "IN_CREATE ........ %u\n"
+ "IN_DELETE ........ %u\n"
+ "IN_DELETE_SELF ... %u\n"
+ "IN_MOVE_SELF ..... %u\n"
+ "IN_ALL_EVENTS .... %u\n"
+ "IN_UNMOUNT ....... %u\n",
+ IN_ACCESS,
+ IN_MODIFY,
+ IN_ATTRIB,
+ IN_CLOSE_WRITE,
+ IN_CLOSE_NOWRITE,
+ IN_OPEN,
+ IN_MOVED_FROM,
+ IN_MOVED_TO,
+ IN_CREATE,
+ IN_DELETE,
+ IN_DELETE_SELF,
+ IN_MOVE_SELF,
+ IN_ALL_EVENTS,
+ IN_UNMOUNT
+ );
+ exit(0);
}
- char *
+ char *
read_filename(int fd)
{
- int i;
- char *fn = NULL, ch;
-
- fn = malloc(PATH_MAX);
- if (!fn)
- return NULL;
-
- for (i=0; read(fd, &ch, 1) > 0 && i < PATH_MAX; i++) {
- if (ch == 0 || ch == '\n') {
- *(fn + i + 1) = 0;
- return fn;
- } else {
- *(fn+i) = ch;
- }
- }
-
- return NULL;
+ int i;
+ char *fn = NULL, ch;
+
+ fn = malloc(PATH_MAX);
+ if (!fn)
+ return NULL;
+
+ for (i=0; read(fd, &ch, 1) > 0 && i < PATH_MAX; i++) {
+ if (ch == 0 || ch == '\n') {
+ *(fn + i + 1) = 0;
+ return fn;
+ } else {
+ *(fn+i) = ch;
+ }
+ }
+
+ return NULL;
}
- int
+ int
execvpe(const char *program, char **argv, char **envp)
{
- char **saved = environ;
- int rc;
- environ = envp;
- rc = execvp(program, argv);
- environ = saved;
- return rc;
+ char **saved = environ;
+ int rc;
+ environ = envp;
+ rc = execvp(program, argv);
+ environ = saved;
+ return rc;
}
- struct node_t *
+ struct node_t *
add_node(int wd, const char *path)
{
- struct node_t *n = NULL;
+ struct node_t *n = NULL;
- n = malloc(sizeof(struct node_t));
+ n = malloc(sizeof(struct node_t));
+ if (!n)
+ return NULL;
- if (!n)
- return NULL;
+ n->wd = wd;
+ strncpy(n->path, path, PATH_MAX);
+ n->next = head ? head : NULL;
+ head = n;
- n->wd = wd;
- strncpy(n->path, path, PATH_MAX);
-
- n->next = head ? head : NULL;
- head = n;
-
- return n;
+ return n;
}
- const char *
+ const char *
wd_name(int wd)
{
- struct node_t *n = head;
+ struct node_t *n = head;
- while (n && n->wd != wd)
- n = n->next;
+ while (n && n->wd != wd)
+ n = n->next;
- return n ? n->path : "unknown";
+ return n ? n->path : "unknown";
}
- int
+ int
watch_node(int fd, const char *path, uint32_t mask)
{
- int wd = -1;
+ int wd = -1;
- if (!path)
- return -1;
+ if (!path)
+ return -1;
- /* add a watcher on the file */
- wd = inotify_add_watch(fd, path, mask);
- if (wd < 0) {
- perror("inotify_add_watch");
- exit(1);
- }
+ /* add a watcher on the file */
+ wd = inotify_add_watch(fd, path, mask);
+ if (wd < 0) {
+ perror("inotify_add_watch");
+ exit(1);
+ }
- add_node(wd, path);
- nb++;
+ add_node(wd, path);
+ nb++;
- return wd;
+ return wd;
}
- int
+ int
main (int argc, char **argv)
{
- int fd, len, i = 0, timeout = 0, ignore = 0;
- uint32_t mask = 0;
- char buf[BUF_LEN];
- char *fn = NULL;
- char **cmd = NULL;
- struct inotify_event *ev;
-
- if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
-
- /* get file descriptor */
- fd = inotify_init();
- if (fd < 0)
- perror("inotify_init");
-
-
- /* parse option given. see usage() above */
- for(i = 1; (i < argc) && (argv[i][0] == '-') && !ignore; i++) {
- switch (argv[i][1]) {
- case 'C': mask |= IN_CREATE; break;
- case 'D': mask |= IN_DELETE; break;
- case 'M': mask |= IN_MODIFY; break;
- case 'm': mask = atoi(argv[++i]); break;
- case 'l': list_events(); break;
- case 'v': verbose += 1; break;
- case 'f': watch_node(fd, argv[++i], mask); break;
- case 't': timeout = atoi(argv[++i]); break;
- case 'e': cmd = &argv[++i]; ignore=1; break;
- default: usage();
- }
- }
-
- /* test given arguments */
- if (!timeout) { timeout = DEFAULT_CHECK; }
-
- if (!nb) {
- while ((fn = read_filename(0)) != NULL)
- watch_node(fd, fn, mask);
-
- free(fn);
- }
-
- /* start looping */
- while (nb>0) {
- /* get every event raised, and queue them */
- len = read(fd, buf, BUF_LEN);
- if (!len || len < 0) {
- perror("read");
- }
-
- i = 0;
-
- /* treat all events queued */
- while (i < len) {
-
- /* get events one by one */
- ev = (struct inotify_event *) &buf[i];
-
- if (verbose) {
- if (ev->mask & IN_IGNORED) {
- printf("!\t%s\n", ev->len? ev->name: wd_name(ev->wd));
- nb--;
- }
-
- printf("%-3u\t%s\n", ev->mask, ev->len? ev->name: wd_name(ev->wd));
- }
-
- /*
- * Do not do anything if no command given.
- * Also only execute the command if the file concerned by the event
- * is the one we're watching, or if we're not looking for a specific
- * file.
- *
- * If you don't undersand this sentence, don't worry. Me neither.
- * Just trust the if().
- */
- if (cmd) {
- /* OMG a new event ! Quick, raise an alert ! */
- if (!fork()) { execvpe(cmd[0], cmd, environ); }
- }
-
- /* jump to the next one */
- i += EVENT_SIZE + ev->len;
- }
- /* wait before queuing events */
- sleep(timeout);
- }
-
- return EXIT_SUCCESS;
+ int fd, len, i = 0, timeout = 0, ignore = 0;
+ uint32_t mask = 0;
+ char buf[BUF_LEN];
+ char *fn = NULL;
+ char **cmd = NULL;
+ struct inotify_event *ev;
+
+ if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
+
+ /* get file descriptor */
+ fd = inotify_init();
+ if (fd < 0)
+ perror("inotify_init");
+
+
+ /* parse option given. see usage() above */
+ for(i = 1; (i < argc) && (argv[i][0] == '-') && !ignore; i++) {
+ switch (argv[i][1]) {
+ case 'm': mask = atoi(argv[++i]); break;
+ case 'l': list_events(); break;
+ case 'v': verbose += 1; break;
+ case 'f': watch_node(fd, argv[++i], mask); break;
+ case 't': timeout = atoi(argv[++i]); break;
+ case 'e': cmd = &argv[++i]; ignore=1; break;
+ default: usage();
+ }
+ }
+
+ /* test given arguments */
+ if (!timeout) { timeout = DEFAULT_CHECK; }
+
+ if (!nb) {
+ while ((fn = read_filename(0)) != NULL)
+ watch_node(fd, fn, mask);
+
+ free(fn);
+ }
+
+ /* start looping */
+ while (nb>0) {
+ /* get every event raised, and queue them */
+ len = read(fd, buf, BUF_LEN);
+ if (!len || len < 0) {
+ perror("read");
+ }
+
+ i = 0;
+
+ /* treat all events queued */
+ while (i < len) {
+
+ /* get events one by one */
+ ev = (struct inotify_event *) &buf[i];
+
+ if (verbose) {
+ if (ev->mask & IN_IGNORED) {
+ printf("!\t%s\n", ev->len? ev->name:
+ wd_name(ev->wd));
+ nb--;
+ }
+
+ printf("%u\t%s\n", ev->mask, ev->len?
+ ev->name: wd_name(ev->wd));
+ fflush(stdout);
+ }
+
+ /*
+ * Do not do anything if no command given. Also only
+ * execute the command if the file concerned by the
+ * event is the one we're watching, or if we're not
+ * looking for a specific file.
+ *
+ * If you don't undersand this sentence, don't worry.
+ * Me neither. Just trust the if().
+ */
+ if (cmd) {
+ /* OMG a new event ! Quick, raise an alert ! */
+ if (!fork()) { execvpe(cmd[0], cmd, environ); }
+ }
+
+ /* jump to the next one */
+ i += EVENT_SIZE + ev->len;
+ }
+ /* wait before queuing events */
+ sleep(timeout);
+ }
+
+ return EXIT_SUCCESS;
}