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