|
INOTIFY
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:
- inotify.xml
<?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
/*
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
|
|