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