diff --git a/Makefile.include b/Makefile.include index 71ff197..326791b 100644 --- a/Makefile.include +++ b/Makefile.include @@ -32,9 +32,10 @@ obj-log = src/log.o $(obj-strbuf) $(obj-xalloc) obj-inotify-backend = src/inotify-backend.o $(obj-log) obj-inotify-watch = src/inotify-watch.o $(obj-tree) obj-inotify-map = src/inotify-map.o $(obj-inotify-watch) $(obj-path) $(obj-rbtree) $(obj-list) -obj-inotify = src/notify-inotify.o src/queue.o $(obj-inotify-backend) $(obj-inotify-map) +obj-inotify = src/inotify.o src/queue.o $(obj-inotify-backend) $(obj-inotify-map) +obj-notify-inotify = src/notify-inotify.o $(obj-inotify) -obj-notify = src/event.o $(obj-inotify) $(obj-xalloc) $(obj-fscrawl) +obj-notify = src/event.o $(obj-notify-inotify) $(obj-xalloc) $(obj-fscrawl) obj-ini = lib/ini/iniparser.o lib/ini/dictionary.o obj-mongo = src/database/mongo.o $(obj-path) $(obj-ini) obj-mysql = src/database/mysql.o $(obj-ini) $(obj-xalloc) diff --git a/src/inotify.c b/src/inotify.c new file mode 100644 index 0000000..f1e7906 --- /dev/null +++ b/src/inotify.c @@ -0,0 +1,125 @@ + +#include +#include "log.h" +#include "path.h" +#include "queue.h" +#include "inotify-backend.h" +#include "inotify-map.h" +#include "inotify.h" + +static queue_t event_queue; + +int inotify_init(void) { + + inotify_backend_init(); + event_queue = queue_init(); + + return 1; +} + +void inotify_exit(void) { + + inotify_backend_exit(); + + if (event_queue) { + notify_event *e; + while((e = queue_dequeue(event_queue))) + notify_event_del(e); + queue_destroy(event_queue); + event_queue = NULL; + } +} + +int inotify_watch(const char *path) { + + int wd = inotify_backend_watch(path); + if (wd > 0) + inotify_map(wd, path); + + return wd; +} + +int inotify_ignore(const char *path) { + + int wd = inotify_map_get_wd(path); + + if (wd < 0) + return -1; + + /* unmap and remove watch */ + if (inotify_unmap_path(path) == 0) { + logmsg(LOG_DEBUG, "remove watch: %i %s", wd, path); + + if (inotify_backend_ignore(wd) < 0) + return -1; + } + return 0; +} + +static void proc_event(struct inotify_event *iev) { + + int i; + struct list *watch_list; + int isdir; + + logmsg(LOG_DEBUG, "RAW EVENT: %i, %x, %s", iev->wd, iev->mask, iev->name); + + if (iev->mask & IN_IGNORED) { + inotify_unmap_wd(iev->wd); + return; + } + + /* lookup watch descriptors */ + watch_list = inotify_map_get_path(iev->wd); + + if (!watch_list) { + logmsg(LOG_WARN, "-- IGNORING EVENT -- invalid watchdescriptor %i", iev->wd); + return; + } + + /* set dir and drop that bit off (so its not in the way) */ + isdir = (iev->mask & IN_ISDIR) != 0; + iev->mask &= ~IN_ISDIR; + + for(i=0; i < watch_list->nr; i++) { + + struct watch *watch = watch_list->items[i]; + notify_event *event = notify_event_new(); + + notify_event_set_path(event, watch->path); + notify_event_set_filename(event, iev->name); + event->dir = isdir; + + switch(iev->mask) { + case IN_CREATE : + case IN_MOVED_TO : + event->type = NOTIFY_CREATE; + break; + case IN_DELETE : + case IN_MOVED_FROM : + event->type = NOTIFY_DELETE; + inotify_ignore(mkpath("%s%s/", event->path, event->filename)); + break; + default: + event->type = NOTIFY_UNKNOWN; + } + + queue_enqueue(event_queue, event); + } + + list_destroy(watch_list); +} + +notify_event* inotify_read(void) { + + char buf[4096]; + int read, offset = 0; + + read = inotify_backend_read(buf, sizeof(buf)); + while(read > offset) { + struct inotify_event *ev = (struct inotify_event*) &buf[offset]; + proc_event(ev); + offset += sizeof(struct inotify_event) + ev->len; + } + return queue_dequeue(event_queue); +} diff --git a/src/inotify.h b/src/inotify.h new file mode 100644 index 0000000..e661553 --- /dev/null +++ b/src/inotify.h @@ -0,0 +1,17 @@ + +#ifndef __INOTIFY_H +#define __INOTIFY_H + +#include "event.h" + +int inotify_init(void); + +void inotify_exit(void); + +int inotify_watch(const char *path); + +int inotify_ignore(const char *path); + +notify_event* inotify_read(void); + +#endif /* __INOTIFY_H */