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

watch_maildirs.cc

#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>

#include "compat.h"
#include "lib/util.h"
#include "watch_maildirs.h"

using std::string;

//
// utilities for watch_maildirs

// errno must be set to zero prior to calling readdir, otherwise
// there is no way to distinguish between EOF and an error.
// GNU libc does not modify errno on EOF or success.
struct dirent* safe_readdir(DIR* dir)
{
      errno = 0;
      return readdir(dir);
}

bool is_maildir(const string& maildir)
{
      string maildir_cur(mkfilename(maildir, string("cur/")));
      string maildir_new(mkfilename(maildir, string("new/")));
      struct stat st;
      bool cur_p, new_p;
      int r;

      r = stat(maildir_cur.c_str(), &st);
      die_if(r < 0 && errno != ENOENT, "stat(\"%s\")", maildir_cur.c_str());
      cur_p = (!r && S_ISDIR(st.st_mode));

      r = stat(maildir_new.c_str(), &st);
      die_if(r < 0 && errno != ENOENT, "stat(\"%s\")", maildir_new.c_str());
      new_p = (!r && S_ISDIR(st.st_mode));

      return (cur_p && new_p);
}

void die_if_not_maildir(const string& maildir)
{
      if (!is_maildir(maildir))
      {
            fprintf(stderr, "Error: \"%s\" is not a Maildir\n", maildir.c_str());
            exit(1);
      }
}

string maildir_to_imap(const string& maildir)
{
      if (maildir.empty())
            return "INBOX";
      else
      {
            assert(maildir[0] == '.');
            return maildir.substr(1);
      }
}

void send_watch_started()
{
      int r;
      r = printf("\n");
      die_if(r != 1, "printf(\"\n\")");
      r = fflush(stdout);
      die_if(r < 0, "fflush(stdout)");
}

void send_maildir_modified(const char* imap_name)
{
      int r;
      r = printf("%s\n", imap_name);
      die_if(r < 0, "printf");
      r = fflush(stdout);
      die_if(r < 0, "fflush(stdout)");
}


//
// main

static void configure_watchmaildirs(int argc, char** argv, char** maildir)
{
      gboolean version = 0;
      char** argv_remains = NULL;
      GOptionContext* ctx;
      GError* gerror = NULL;
      gboolean r;

      GOptionEntry options[] =
      {
            { "maildir", 'm', 0, G_OPTION_ARG_FILENAME, maildir,
              "The Maildir/Maildir++ to watch (default: $MAILDIR; or if not defined, ~/Maildir)", "DIR" },
            { "version", 'V', 0, G_OPTION_ARG_NONE, &version,
              "Display version", NULL },
            { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &argv_remains,
              NULL, NULL },
            { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
      };

      ctx = g_option_context_new("- watch for and display Maildir/Maildir++ changes");
      g_option_context_add_main_entries(ctx, options, NULL);
      r = g_option_context_parse(ctx, &argc, &argv, &gerror);
      if (r == FALSE)
      {
            GQuark error = G_OPTION_ERROR;
            assert(error == G_OPTION_ERROR_BAD_VALUE);
            fprintf(stderr, "%s\n", gerror->message);
            g_error_free(gerror);
            exit(1);
      }
      assert(!gerror);
      g_option_context_free(ctx);
      ctx = NULL;

      if (argv_remains && *argv_remains)
      {
            fprintf(stderr, "Unknown arguments starting with \"%s\"\n", *argv_remains);
            exit(1);
      }

      if (version)
      {
            printf("watch_maildirs (%s)\n", notify_method);
            printf(PACKAGE " " VERSION "\n");
            exit(1);
      }

      if (!*maildir)
      {
            if (getenv("MAILDIR"))
                  *maildir = strdup(getenv("MAILDIR"));
            else
                  *maildir = strdup(mkfilename(getenv("HOME"), "Maildir").c_str());
            die_if(!*maildir, "strdup");
      }
}

int main(int argc, char* argv[])
{
      char* maildir = NULL;

      configure_watchmaildirs(argc, argv, &maildir);

      watch(maildir);

      free(maildir);
      maildir = NULL;
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index