|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  | #include <stdint.h> | 
|  | #include <fcntl.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; | 
|  | } |