Schnitstelle zur Überwachung von Dateisystemereignissen.
Zur Zeit funktioniert nur inotify und nicht fanotify vernünftig.
Die Überwachung ist auch mit dem Programm iwatch möglich:
apt-get install iwatch iwatch /meinVerzeichnis
Beispiel: Überwache das /tmp-Verzeichnis rekursiv auf Dateierstellung und Änderungen:
iwatch -r -e create,write -c "ls %f" /tmp
Beispiel: Überwache das /tmp
-Verzeichnis rekursiv auf Dateierstellung und Änderungen,
Mache das als Daemon und überprüfe die Datei mit dem AVIRA-Virenscanner.
Der Virenscanner kann zwar den Dateizugriff nicht sperren aber z.B. eine Mail senden oder einen
Kdialog öffnen(wenn er vernünftig konfiguriert ist):
Ändere zunächst die Datei /etc/inotify.xml
in etwa wie folgt:
<?xml version="1.0" ?> <!DOCTYPE config SYSTEM "/etc/iwatch.dtd" > <config charset="utf-8"> <guard email="iwatch@localhost" name="IWatch"/> <watchlist> <title>AVIRA-Scanner</title> <contactpoint email="alarm@meine.domaene.de" name="Avirafilescanner"/> <path type="recursive" events="create,modify" alert="off" exec="avscan --batch %f">/tmp</path> <path type="recursive" events="create,modify" alert="off" exec="avscan --batch %f">/home</path> <path type="recursive" events="create,modify" alert="off" exec="avscan --batch %f">/root</path> <path type="recursive" events="create,modify" alert="off" exec="avscan --batch %f">/var/tmp</path> </watchlist> </config>
Starte dann die Überwachung mit:
iwatch -d
(Der Nachteil ist das immerwährende Erstellen von avscan-Prozessen und nicht von Threads.
Das muss man ausprobieren ob die Systembelastung im Rahmen bleibt).
Beispiel-C-code:
/* inotify.c * * Copyright (C) NAKAMURA Minoru <nminoru@nminoru.jp> * * gcc -Wall -o inotify inotify.c * http://www.nminoru.jp/~nminoru/data/200701/inotify.c */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stddef.h> /* for offsetof */ #include <string.h> /* for memmove */ #include <errno.h> #include <limits.h> #include <sys/inotify.h> #define MAX_WATCHPOINT_DIRS (32) static void display_inotify_event(struct inotify_event *inotify_p); static int wd_array[MAX_WATCHPOINT_DIRS]; int main(int argc, char **argv) { int i, max_wd; uint32_t imask = IN_ALL_EVENTS; if (argc < 3) { printf("%s notify for filechange \n",argv[0]); printf("-a access a file\n"); printf("-m modify a file\n"); printf("Usage: -a [directory-to-watch1 [directory-to-watch2 ...]]\n"); printf("Usage: -w [directory-to-watch1 [directory-to-watch2 ...]]\n"); printf("Example: %s -a /home\n",argv[0]); exit(EXIT_SUCCESS); } if (strcmp(argv[1],"-a") == 0){ printf("%s\n",argv[1]); imask = IN_ACCESS;} if (strcmp(argv[1],"-m") == 0){ printf("%s\n",argv[1]); imask = IN_MODIFY;} int fd = inotify_init(); if (fd == -1) { perror("inotify_init"); exit(EXIT_FAILURE); } max_wd = (MAX_WATCHPOINT_DIRS > argc -1 ) ? argc -1: MAX_WATCHPOINT_DIRS; for (i=1 ; i<max_wd ; i++) { printf("argv: %s imask: %d\n",argv[i+1],imask); int wd = inotify_add_watch(fd, argv[i+1],imask ); if (wd < 0) { perror("error inotify_add_watch"); exit(EXIT_FAILURE); } wd_array[i] = wd; } for (;;) { int i, aux=0, ret; char name_buf[PATH_MAX]; char buffer[65536]; reread: ret = read(fd, buffer + aux, sizeof(buffer) - aux); if (ret == -1) { if (ret == -EINTR) goto reread; perror("read"); exit(EXIT_FAILURE); } ret += aux; if (ret < sizeof(struct inotify_event)) { fprintf(stderr, "short of red bytes\n"); exit(EXIT_FAILURE); } i = 0; while (i < ret) { struct inotify_event *inotify_p; inotify_p = (struct inotify_event *)(buffer + i); if (ret < i + offsetof(struct inotify_event, name)) { aux = ret - i; memmove(buffer, buffer + i, aux); goto reread; } int size = sizeof(struct inotify_event) + inotify_p->len; if (ret < i + size) { aux = ret - i; memmove(buffer, buffer + i, aux); goto reread; } display_inotify_event(inotify_p); i += size; } } for (i=0 ; i<max_wd ; i++) { int ret = inotify_rm_watch(fd, wd_array[i]); if (ret == -1) { perror("inotify_rm_watch"); exit(EXIT_FAILURE); } } close(fd); return 0; } static void display_inotify_event(struct inotify_event *inotify_p) { int ret = 0; char buffer[256]; uint32_t mask = inotify_p->mask; // File was accessed (read) (*). if (mask & IN_ACCESS) ret += sprintf(buffer + ret, "ACCESS "); // Metadata changed if (mask & IN_ATTRIB) ret += sprintf(buffer + ret, "ATTRIB "); // File opened for writing was closed (*). if (mask & IN_CLOSE_WRITE) ret += sprintf(buffer + ret, "CLOSE_WRITE "); // File not opened for writing was closed (*). if (mask & IN_CLOSE_NOWRITE) ret += sprintf(buffer + ret, "CLOSE_NOWRITE "); // File/directory created in watched directory (*). if (mask & IN_CREATE) ret += sprintf(buffer + ret, "CREATE "); // File/directory deleted from watched directory (*). if (mask & IN_DELETE) ret += sprintf(buffer + ret, "DELETE "); // Watched file/directory was itself deleted. if (mask & IN_DELETE_SELF) ret += sprintf(buffer + ret, "DELETE_SELF "); // File was modified (*). if (mask & IN_MODIFY) ret += sprintf(buffer + ret, "MODIFY "); // Watched file/directory was itself moved. if (mask & IN_MOVE_SELF) ret += sprintf(buffer + ret, "MODIFY_SELF "); // File moved out of watched directory (*). if (mask & IN_MOVED_FROM) ret += sprintf(buffer + ret, "MOVE_FROM "); // File moved into watched directory (*). if (mask & IN_MOVED_TO) ret += sprintf(buffer + ret, "MOVE_TO "); // File was opened (*). if (mask & IN_OPEN) ret += sprintf(buffer + ret, "OPEN "); // Watch was removed explicitly (inotify_rm_watch(2)) or // automatically (file was deleted, or file system was // unmounted). if (mask & IN_IGNORED) ret += sprintf(buffer + ret, "IGNORED "); // Subject of this event is a directory. if (mask & IN_ISDIR) ret += sprintf(buffer + ret, "ISDIR "); // Event queue overflowed (wd is -1 for this event). if (mask & IN_Q_OVERFLOW) ret += sprintf(buffer + ret, "Q_OVERFLOW "); // File system containing watched object was unmounted. if (mask & IN_UNMOUNT) ret += sprintf(buffer + ret, "Q_UNMOUNT "); /* printf("%d %x %u %u \"%s\" [%s]\n", inotify_p->wd, inotify_p->mask, inotify_p->cookie, inotify_p->len, &inotify_p->name, buffer); */ printf("%s\t%s\n",&inotify_p->name,buffer); }
siehe auch : AVIRA for Linux