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