int main(int argc, char **argv) { int kq; struct kevent *e, kev_r; int n , i; int optcode = 0; int option_index = 0; struct timespec tv; FILE *fp; char *watchfile = NULL; int timeout = 0; struct option long_options[] = { {"file", required_argument, 0, C_FILE}, {"timeout", required_argument, 0, C_TIMEOUT}, /* End of options marker */ {0, 0, 0, 0} }; if (argc < 2) { cbsd_fwatch_usage(); return 0; } while (TRUE) { optcode = getopt_long_only(argc, argv, "", long_options, &option_index); if (optcode == -1) break; switch (optcode) { case C_FILE: watchfile = malloc(strlen(optarg) + 1); memset(watchfile, 0, strlen(optarg) + 1); strcpy(watchfile, optarg); break; case C_TIMEOUT: timeout = atoi(optarg); break; } } //while //zero for getopt *variables for next execute optarg = NULL; optind = 0; optopt = 0; opterr = 0; optreset = 0; if (!watchfile) { cbsd_fwatch_usage(); return 1; } fp = fopen(watchfile, "r"); if (!fp) { printf("Can't open file for mon: %s\n", watchfile); free(watchfile); return 1; } kq = kqueue(); if (kq == -1) { fclose(fp); free(watchfile); printf("kqueue error"); return 1; } e = malloc(argc * sizeof(struct kevent)); if (e == NULL) { fclose(fp); free(watchfile); printf("malloc"); return 1; } i = 0; //todo:multiple file alteration EV_SET(e + i, (*fp)._file, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE | NOTE_WRITE, 0, NULL); if (kevent(kq, e + i, 1, &kev_r, 0, NULL) == -1) printf("kevent"); else i++; tv.tv_sec = timeout; tv.tv_nsec = 0; //tv.tv_usec = 0; while (i > 0) { if (kev_r.fflags & NOTE_WRITE) { printf("updated\n"); } else if (kev_r.fflags & NOTE_DELETE) { printf("deleted\n"); } if (timeout == 0) n = kevent(kq, NULL, 0, e, i, NULL); else n = kevent(kq, NULL, 0, e, i, &tv); if (n == -1) { fclose(fp); printf("kevent"); free(e); free(watchfile); return 1; } i--; } free(e); free(watchfile); fclose(fp); return (EX_OK); }
int cbsd_fwatchcmd(int argc, char *argv[]) { int fd, kq, nev; struct kevent ev; int optcode = 0; int option_index = 0; struct timespec tv; char *watchfile = NULL; int timeout = 10; char cmd[10]; struct option long_options[] = { { "file", required_argument, 0, C_FILE }, { "timeout", required_argument, 0, C_TIMEOUT }, /* End of options marker */ { 0, 0, 0, 0 } }; if (argc < 2) { cbsd_fwatch_usage(); return 0; } while (TRUE) { optcode = getopt_long_only(argc, argv, "", long_options, &option_index); if (optcode == -1) break; switch (optcode) { case C_FILE: watchfile = malloc(strlen(optarg) + 1); memset(watchfile, 0, strlen(optarg) + 1); strcpy(watchfile, optarg); break; case C_TIMEOUT: timeout = atoi(optarg); break; } } //while //zero for getopt *variables for next execute optarg = NULL; optind = 0; optopt = 0; opterr = 0; optreset = 0; if (!watchfile) { cbsd_fwatch_usage(); return 1; } if ((fd = open(watchfile, O_RDONLY)) == -1) { out2fmt_flush("Cannot open: %s\n", watchfile); ckfree(watchfile); return(1); } if ((kq = kqueue()) == -1) { out2fmt_flush("Cannot create kqueue\n"); close(fd); ckfree(watchfile); return 1; } EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK| NOTE_RENAME|NOTE_REVOKE, 0, 0); if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) { out2fmt_flush("kevent\n"); close(fd); ckfree(watchfile); close(kq); return 1; } tv.tv_sec = timeout; tv.tv_nsec = 0; memset(cmd,0,sizeof(cmd)); if (timeout == 0) nev = kevent(kq, NULL, 0, &ev, 1, NULL); else nev = kevent(kq, NULL, 0, &ev, 1, &tv); if (nev == -1) { out2fmt_flush("kevent\n"); close(fd); ckfree(watchfile); close(kq); return 1; } close(kq); close(fd); if (nev != 0) { if (ev.fflags & NOTE_DELETE) { out2fmt_flush("deleted\n"); ev.fflags &= ~NOTE_DELETE; } if (ev.fflags & NOTE_WRITE) { out2fmt_flush("written\n"); ev.fflags &= ~NOTE_WRITE; } if (ev.fflags & NOTE_EXTEND) { out2fmt_flush("extended\n"); ev.fflags &= ~NOTE_EXTEND; } if (ev.fflags & NOTE_ATTRIB) { out2fmt_flush("chmod/chown/utimes\n"); ev.fflags &= ~NOTE_ATTRIB; } if (ev.fflags & NOTE_LINK) { out2fmt_flush("hardlinked\n"); ev.fflags &= ~NOTE_LINK; } if (ev.fflags & NOTE_RENAME) { out2fmt_flush("renamed\n"); ev.fflags &= ~NOTE_RENAME; } if (ev.fflags & NOTE_REVOKE) { out2fmt_flush("revoked\n"); ev.fflags &= ~NOTE_REVOKE; } } ckfree(watchfile); return 0; }