view dglwatcher.c @ 195:3bdee6371c3f

Change various filenames. The shell script previously used to launch the daemon is now called "initscript". The script files have had the ".js" extension removed from their names.
author John "Elwin" Edwards
date Thu, 14 Jan 2016 20:52:29 -0500
parents fba1b34e7554
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/select.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>

struct watchdir {
  int wd;
  char *name;
};

char ibuf[sizeof(struct inotify_event) + NAME_MAX + 1];

int startwatch(int ifd, char *dir, struct watchdir *w) {
  DIR *dstream;
  struct dirent *ent;

  w->name = dir;
  w->wd = inotify_add_watch(ifd, dir, IN_CREATE|IN_DELETE|IN_DELETE_SELF);
  if (w->wd < 0) {
    fprintf(stderr, "Could not watch %s\n", dir);
    return 1;
  }
  dstream = opendir(dir);
  if (dstream == NULL) {
    fprintf(stderr, "%s is not a readable directory\n", dir);
    inotify_rm_watch(ifd, w->wd);
    w->wd = -1;
    return 1;
  }
  ent = readdir(dstream);
  while (ent != NULL) {
    if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
      printf("E %s/%s\n", dir, ent->d_name);
    ent = readdir(dstream);
  }
  closedir(dstream);
  fflush(stdout);
  return 0;
}

int main(int argc, char *argv[]) {
  int ifd, rsize, off, done, nwatchers, i, result;
  char typecode;
  struct inotify_event *iev;
  fd_set rfds;
  struct watchdir *watchers;

  done = 0;
  nwatchers = argc - 1;
  iev = (struct inotify_event *) ibuf;
  ifd = inotify_init();
  if (nwatchers == 0) {
    watchers = malloc(sizeof(struct watchdir));
    nwatchers = 1;
    startwatch(ifd, ".", watchers);
  }
  else {
    watchers = malloc(nwatchers * sizeof(struct watchdir));
    for (i = 0; i < nwatchers; i++) {
      startwatch(ifd, argv[i+1], watchers + i);
    }
  }

  while (!done) {
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    FD_SET(ifd, &rfds);
    result = select(ifd + 1, &rfds, NULL, NULL, NULL);
    if (result < 0) {
      /* Something went wrong. */
      break;
    }
    if (FD_ISSET(ifd, &rfds)) {
      off = 0;
      rsize = read(ifd, ibuf, sizeof(struct inotify_event) + NAME_MAX + 1);
      while (off < rsize) {
        iev = (struct inotify_event *) (ibuf + off);
        if (iev->mask & IN_CREATE)
          typecode = 'C';
        else if (iev->mask & IN_DELETE)
          typecode = 'D';
        else
          typecode = '?';
        for (i = 0; i < nwatchers; i++) {
          if (watchers[i].wd == iev->wd)
            printf("%c %s/%s\n", typecode, watchers[i].name, iev->name);
        }
        off += sizeof(struct inotify_event) + iev->len;
      }
      fflush(stdout);
    }
    if (FD_ISSET(0, &rfds)) {
      result = read(0, &typecode, 1);
      if (result <= 0) {
        /* EOF on stdin: controlling process probably died. */
        done = 1;
      }
      if (typecode == '\n')
        done = 1;
    }
    
  }
  close(ifd);
  return 0;
}