Add check for path length
[eleutheria.git] / kqdir.c
blobb3c53fc037be579da1a697942e65b0113406cbd1
1 #include <dirent.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/event.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <string.h> /* for strerror() */
9 #define MAX_ENTRIES 256
11 void diep(const char *s);
13 int main(int argc, char *argv[])
15 struct kevent evlist[MAX_ENTRIES]; /* events we want to monitor */
16 struct kevent chlist[MAX_ENTRIES]; /* events that were triggered */
17 struct dirent *pdent;
18 DIR *pdir;
19 char fullpath[256];
20 int fdlist[MAX_ENTRIES], cnt, kq, nev, i;
22 /* check argument count */
23 if (argc != 2) {
24 fprintf(stderr, "Usage: %s directory\n", argv[0]);
25 exit(EXIT_FAILURE);
28 /* create a new kernel event queue */
29 if ((kq = kqueue()) == -1)
30 diep("kqueue");
32 /* */
33 if ((pdir = opendir(argv[1])) == NULL)
34 perror("opendir");
36 /* Skip . and .. */
37 cnt = 0;
38 while((pdent = readdir(pdir)) != NULL && cnt++ < 2)
41 /* */
42 cnt = 0;
43 while((pdent = readdir(pdir)) != NULL) {
44 if (cnt > MAX_ENTRIES - 1) {
45 fprintf(stderr, "Max number of entries exceeded\n");
46 for (i = 0; i < cnt; i++)
47 close(fdlist[i]);
48 closedir(pdir);
49 close(kq);
50 exit(EXIT_FAILURE);
53 if (strlen(argv[1] + strlen(pdent->d_name) + 1) > 256) {
54 fprintf(stderr,"Max path length exceeded\n");
55 exit(EXIT_FAILURE);
57 strcpy(fullpath, argv[1]);
58 strcat(fullpath, "/");
59 strcat(fullpath, pdent->d_name);
61 if ((fdlist[cnt] = open(fullpath, O_RDONLY)) == -1)
62 perror("open");
64 EV_SET(&chlist[cnt], fdlist[cnt], EVFILT_VNODE,
65 EV_ADD | EV_ENABLE | EV_ONESHOT,
66 NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB,
67 0, 0);
69 cnt++;
72 /* loop forever */
73 for (;;) {
74 nev = kevent(kq, chlist, cnt, evlist, cnt, NULL);
75 if (nev == -1)
76 perror("kevent");
78 else if (nev > 0) {
79 for (i = 0; i < nev; i++) {
80 if (evlist[i].flags & EV_ERROR) {
81 fprintf(stderr, "EV_ERROR: %s\n", strerror(evlist[i].data));
82 exit(EXIT_FAILURE);
85 if (evlist[i].fflags & NOTE_DELETE) {
86 printf("fd: %d Deleted\n", evlist[i].ident);
88 else if (evlist[i].fflags & NOTE_EXTEND ||
89 evlist[i].fflags & NOTE_WRITE) {
90 printf("fd: %d Modified\n", evlist[i].ident);
92 else if (evlist[i].fflags & NOTE_ATTRIB) {
93 printf("fd: %d Attributes modified\n", evlist[i].ident);
99 /* */
100 for (i = 0; i < cnt; i++)
101 close(fdlist[i]);
102 closedir(pdir);
103 close(kq);
105 return EXIT_SUCCESS;
108 void diep(const char *s)
110 perror(s);
111 exit(EXIT_FAILURE);