1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/inotify.h>
#include <errno.h>
int notify_main(int argc, char *argv[])
{
int c;
int nfd, ffd;
int res;
char event_buf[512];
struct inotify_event *event;
int event_mask = IN_ALL_EVENTS;
int event_count = 1;
int print_files = 0;
int verbose = 2;
int width = 80;
char **file_names;
int file_count;
int id_offset = 0;
int i;
char *buf;
do {
c = getopt(argc, argv, "m:c:pv:w:");
if (c == EOF)
break;
switch (c) {
case 'm':
event_mask = strtol(optarg, NULL, 0);
break;
case 'c':
event_count = atoi(optarg);
break;
case 'p':
print_files = 1;
break;
case 'v':
verbose = atoi(optarg);
break;
case 'w':
width = atoi(optarg);
break;
case '?':
fprintf(stderr, "%s: invalid option -%c\n",
argv[0], optopt);
exit(1);
}
} while (1);
if (argc <= optind) {
fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]);
return 1;
}
nfd = inotify_init();
if(nfd < 0) {
fprintf(stderr, "inotify_init failed, %s\n", strerror(errno));
return 1;
}
file_names = argv + optind;
file_count = argc - optind;
for(i = 0; i < file_count; i++) {
res = inotify_add_watch(nfd, file_names[i], event_mask);
if(res < 0) {
fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno));
return 1;
}
if(i == 0)
id_offset = -res;
if(res + id_offset != i) {
fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i);
return 1;
}
}
buf = malloc(width + 2);
while(1) {
int event_pos = 0;
res = read(nfd, event_buf, sizeof(event_buf));
if(res < (int)sizeof(*event)) {
if(errno == EINTR)
continue;
fprintf(stderr, "could not get event, %s\n", strerror(errno));
return 1;
}
//printf("got %d bytes of event information\n", res);
while(res >= (int)sizeof(*event)) {
int event_size;
event = (struct inotify_event *)(event_buf + event_pos);
if(verbose >= 2)
printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : "");
else if(verbose >= 2)
printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : "");
else if(verbose >= 1)
printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
if(print_files && (event->mask & IN_MODIFY)) {
char filename[512];
ssize_t read_len;
char *display_name;
int buflen;
strcpy(filename, file_names[event->wd + id_offset]);
if(event->len) {
strcat(filename, "/");
strcat(filename, event->name);
}
ffd = open(filename, O_RDONLY);
display_name = (verbose >= 2 || event->len == 0) ? filename : event->name;
buflen = width - strlen(display_name);
read_len = read(ffd, buf, buflen);
if(read_len > 0) {
if(read_len < buflen && buf[read_len-1] != '\n') {
buf[read_len] = '\n';
read_len++;
}
if(read_len == buflen) {
buf[--read_len] = '\0';
buf[--read_len] = '\n';
buf[--read_len] = '.';
buf[--read_len] = '.';
buf[--read_len] = '.';
}
else {
buf[read_len] = '\0';
}
printf("%s: %s", display_name, buf);
}
close(ffd);
}
if(event_count && --event_count == 0)
return 0;
event_size = sizeof(*event) + event->len;
res -= event_size;
event_pos += event_size;
}
}
return 0;
}
|