Logo Search packages:      
Sourcecode: mswatch version File versions  Download package

watcher_partial.cc

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <string>

#include "lib/util.h"
#include "watch_maildirs.h"
#include "watcher_maildir.h"
#include "watcher_partial.h"

using std::string;

watcher_partial::watcher_partial(struct inotify_state* state, const string& partial_maildir)
      : state(state), partial_maildir(partial_maildir)
{
      string maildir(mkfilename(state->base_path, partial_maildir));

      wd = start_watch(maildir.c_str());

      cur_exists = dir_exists(mkfilename(maildir, "cur/").c_str());
      new_exists = dir_exists(mkfilename(maildir, "new/").c_str());
      if (cur_exists && new_exists)
            exit(EXIT_RESTART); // it is probably illegal to delete this, so exit
}

watcher_partial::~watcher_partial()
{
      if (wd >= 0)
            stop_watch(wd);
}


void watcher_partial::process_event(const struct inotify_event& event)
{
      if (!(event.mask & IN_ISDIR))
            return;

      if (event.mask & IN_DELETE_SELF)
      {
            delete this;
            return;
      }

      if (event.mask & (IN_MOVED_TO | IN_CREATE))
      {
            if (!strcmp(event.name, "cur"))
                  cur_exists = true;
            else if (!strcmp(event.name, "new"))
                  new_exists = true;

            if (cur_exists && new_exists)
            {
                  transition_to_maildir();
                  return;
            }
      }
      else if (event.mask & (IN_MOVED_FROM | IN_DELETE))
      {
            if (!strcmp(event.name, "cur"))
                  cur_exists = false;
            else if (!strcmp(event.name, "new"))
                  new_exists = false;
      }
}

bool watcher_partial::dir_exists(const char* dir) const
{
      struct stat st;
      int r = stat(dir, &st);
      if (r < 0 && errno == ENOENT)
            return false;
      die_if(r < 0, "stat(\"%s\")\n", dir);
      return S_ISDIR(st.st_mode);
}

void watcher_partial::transition_to_maildir()
{
      send_maildir_modified(maildir_to_imap(partial_maildir).c_str());

      stop_watch(wd);
      wd = -1;

      new watcher_maildir(state, partial_maildir);

      delete this;
}

int watcher_partial::start_watch(const char* dir)
{
      int wd = inotify_add_watch(state->inotify_fd, dir, notify);
      die_if(wd < 0, "inotify_add_watch(\"%s\")", dir);
      state->add_imap_watcher(wd, maildir_to_imap(partial_maildir), this);
      return wd;
}

void watcher_partial::stop_watch(int wd)
{
      int r = inotify_rm_watch(state->inotify_fd, wd);
      die_if(r < 0, "inotify_rm_watch(\"%s\")\n", partial_maildir.c_str());
      state->remove_imap_watcher(wd, maildir_to_imap(partial_maildir));
}

Generated by  Doxygen 1.6.0   Back to index