From def4f30a99f50898c18afb53a2023945a5927800 Mon Sep 17 00:00:00 2001 From: Michael Elkins Date: Wed, 23 Jan 2013 21:52:31 +0000 Subject: [PATCH] add support for $mail_check_recent to mh mailbox driver closes #3629 --- buffy.c | 3 ++- buffy.h | 2 ++ mh.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++------ mx.h | 1 - 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/buffy.c b/buffy.c index fd54dd2dc..e5a0f7987 100644 --- 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 2e5e04849..f9fc55a17 100644 --- 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 7a8d7756f..21e6491fa 100644 --- a/mh.c +++ b/mh.c @@ -1,6 +1,7 @@ /* * Copyright (C) 1996-2002,2007,2009 Michael R. Elkins * Copyright (C) 1999-2005 Thomas Roessler + * Copyright (C) 2013 Michael R. Elkins * * 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 #include @@ -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 136ae5fbc..4a007158f 100644 --- 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 *); -- 2.40.0