aboutsummaryrefslogblamecommitdiffstats
path: root/src/bin/filemon.c
blob: 2f0af24976ff6d3dcfdf0b3710f3c4e2d23418a7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                                                  







                      
 






                                         
 








































































                                                                                                         
//ripped from the netbsd man page for kqueue
//and modified very slightly.
//I'll add some more stuff as I find a use for it.
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>

int main(int argc, char *argv[]) {
  if(argc < 2) {
    printf("usage: filemon file [prog]");
    return 1;
  }
  monitor(argv[1],argv[2]);
}

int monitor(char *file,char *handler) {
  int fd, kq, nev;
  struct kevent ev;
  struct stat sb;
  char buffer[
  static const struct timespec tout = { 1, 0 };
  if ((fd = open(file, O_RDONLY)) == -1) err(1, "Cannot open `%s'", argv[1]);
  fstat(fd,&sb);
  if(S_ISDIR(sb.st_mode)) {
    //read list of files from dir?
    //rerun self on all files in that dir.
    //system("filemon file/*"); //XD
    getdents(fd,,);
  }
  if ((kq = kqueue()) == -1) err(1, "Cannot create kqueue");
  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, &tout) == -1) err(1, "kevent");
  for (;;) {
    nev = kevent(kq, NULL, 0, &ev, 1, &tout);
    if (nev == -1) err(1, "kevent");
    if (nev == 0) continue;
    printf("nev:%x\n",nev);//probably fd that triggered event?
    printf("ev.ident:%x\n",ev.ident);
    printf("ev.filter:%x\n",ev.filter);
    printf("ev.flags:%x\n",ev.flags);
    printf("ev.fflags:%x\n",ev.fflags);
    printf("ev.data:%x\n",ev.data);
    printf("ev.udata:%x\n",ev.udata);
    if (ev.fflags & (NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE)) {
      printf("%s: ",file);
      if(argv[2]) system(handler);
    }
    if (ev.fflags & NOTE_DELETE) {
      printf("deleted ");
      ev.fflags &= ~NOTE_DELETE;
    }
    if (ev.fflags & NOTE_WRITE) {
      printf("written ");
      ev.fflags &= ~NOTE_WRITE;
    }
    if (ev.fflags & NOTE_EXTEND) {
      printf("extended ");
      ev.fflags &= ~NOTE_EXTEND;
    }
    if (ev.fflags & NOTE_ATTRIB) {
      printf("chmod/chown/utimes ");
      ev.fflags &= ~NOTE_ATTRIB;
    }
    if (ev.fflags & NOTE_LINK) {
      printf("hardlinked ");
      ev.fflags &= ~NOTE_LINK;
    }
    if (ev.fflags & NOTE_RENAME) {
      printf("renamed ");
      ev.fflags &= ~NOTE_RENAME;
    }
    if (ev.fflags & NOTE_REVOKE) {
      printf("revoked ");
      ev.fflags &= ~NOTE_REVOKE;
    }
    printf("\n");
    if (ev.fflags) {
      warnx("unknown event 0x%x\n", ev.fflags);
    }
  }
  return 0;
}