]> granicus.if.org Git - neomutt/commitdiff
add support for $mail_check_recent to mh mailbox driver
authorMichael Elkins <me@sigpipe.org>
Wed, 23 Jan 2013 21:52:31 +0000 (21:52 +0000)
committerMichael Elkins <me@sigpipe.org>
Wed, 23 Jan 2013 21:52:31 +0000 (21:52 +0000)
closes #3629

buffy.c
buffy.h
mh.c
mx.h

diff --git a/buffy.c b/buffy.c
index fd54dd2dca3be2c28e04161eb4041308abeeaf3d..e5a0f79871fc14287f3d83af624cb0ddf5f31e75 100644 (file)
--- a/buffy.c
+++ b/buffy.c
@@ -454,7 +454,8 @@ int mutt_buffy_check (int force)
        break;
 
       case M_MH:
-       if ((tmp->new = mh_buffy (tmp->path)) > 0)
+       mh_buffy(tmp);
+       if (tmp->new)
          BuffyCount++;
        break;
       }
diff --git a/buffy.h b/buffy.h
index 2e5e04849e94b7b6316bee041c4406251654aa84..f9fc55a179f17aebb040445b88150dc6ea2d669f 100644 (file)
--- a/buffy.h
+++ b/buffy.h
@@ -47,3 +47,5 @@ void mutt_buffy_cleanup (const char *buf, struct stat *st);
 
 /* mark mailbox just left as already notified */
 void mutt_buffy_setnotified (const char *path);
+
+void mh_buffy (BUFFY *);
diff --git a/mh.c b/mh.c
index 7a8d7756f09c923de27ccf466a31dd73f4272acb..21e6491fa2c5bc0a9ad70ff98152da613d05f179 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 1996-2002,2007,2009 Michael R. Elkins <me@mutt.org>
  * Copyright (C) 1999-2005 Thomas Roessler <roessler@does-not-exist.org>
+ * Copyright (C) 2013 Michael R. Elkins <me@mutt.org>
  * 
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
@@ -35,6 +36,7 @@
 #include "hcache.h"
 #endif
 #include "mutt_curses.h"
+#include "buffy.h"
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -227,19 +229,70 @@ static inline mode_t mh_umask (CONTEXT* ctx)
   return 0777 & ~st.st_mode;
 }
 
-int mh_buffy (const char *path)
+/*
+ * Returns 1 if the .mh_sequences last modification time is more recent than the last visit to this mailbox
+ * Returns 0 if the modifcation time is older
+ * Returns -1 on error
+ */
+static int mh_sequences_changed(BUFFY *b)
+{
+  char path[_POSIX_PATH_MAX];
+  struct stat sb;
+
+  if ((snprintf(path, sizeof(path), "%s/.mh_sequences", b->path) < sizeof(path)) &&
+      (stat(path, &sb) == 0))
+    return (sb.st_mtime > b->last_visited);
+  return -1;
+}
+
+/*
+ * Returns 1 if the modification time on the message file is older than the last visit to this mailbox
+ * Returns 0 if the modtime is newer
+ * Returns -1 on error
+ */
+static int mh_already_notified(BUFFY *b, int msgno)
+{
+  char path[_POSIX_PATH_MAX];
+  struct stat sb;
+
+  if ((snprintf(path, sizeof(path), "%s/%d", b->path, msgno) < sizeof(path)) &&
+      (stat(path, &sb) == 0))
+    return (sb.st_mtime <= b->last_visited);
+  return -1;
+}
+
+void mh_buffy(BUFFY *b)
 {
-  int i, r = 0;
+  int i;
   struct mh_sequences mhs;
+
+  b->new = 0;
+
+  /* when $mail_check_recent is set and the .mh_sequences file hasn't changed
+   * since the last mailbox visit, there is nothing to do */
+  if (option(OPTMAILCHECKRECENT) && mh_sequences_changed(b) <= 0)
+      return;
+
   memset (&mhs, 0, sizeof (mhs));
 
-  if (mh_read_sequences (&mhs, path) < 0)
-    return 0;
-  for (i = 0; !r && i <= mhs.max; i++)
+  if (mh_read_sequences (&mhs, b->path) < 0)
+    return;
+
+  /* Traverse the sequence from high to low in order to support
+   * $mail_check_recent.  Given that new messages are appended, this should
+   * also be faster when it is unset as well.
+   */
+  for (i = mhs.max; i > 0; i--)
+  {
     if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN)
-      r = 1;
+    {
+      /* if the first unseen message we encounter was in the mailbox during the last visit, don't notify about it */
+      if (!option(OPTMAILCHECKRECENT) || mh_already_notified(b, i) == 0)
+       b->new = 1;
+      break;
+    }
+  }
   mhs_free_sequences (&mhs);
-  return r;
 }
 
 static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
diff --git a/mx.h b/mx.h
index 136ae5fbca7250df4fa9efa83839593d6d56af91..4a007158fe053f0cb1ff0738b0722f71f4bc6d0a 100644 (file)
--- a/mx.h
+++ b/mx.h
@@ -57,7 +57,6 @@ void mbox_reset_atime (CONTEXT *, struct stat *);
 int mh_read_dir (CONTEXT *, const char *);
 int mh_sync_mailbox (CONTEXT *, int *);
 int mh_check_mailbox (CONTEXT *, int *);
-int mh_buffy (const char *);
 int mh_check_empty (const char *);
 
 int maildir_read_dir (CONTEXT *);