• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
notify_main(int argc,char * argv[])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