From 2780979eaf756decd2ac2017a297f1975dba88b0 Mon Sep 17 00:00:00 2001 From: Austin Ray Date: Fri, 23 Nov 2018 12:41:55 +0000 Subject: [PATCH] move backend-specific code --- mailbox.c | 188 +--------------------------------------------- maildir/maildir.h | 2 + maildir/mh.c | 124 ++++++++++++++++++++++++++++++ mbox/mbox.c | 59 +++++++++++++++ mbox/mbox.h | 5 +- 5 files changed, 190 insertions(+), 188 deletions(-) diff --git a/mailbox.c b/mailbox.c index 302b7be18..0f1ae322b 100644 --- a/mailbox.c +++ b/mailbox.c @@ -117,190 +117,6 @@ void mailbox_free(struct Mailbox **m) FREE(m); } -/** - * mailbox_maildir_check_dir - Check for new mail / mail counts - * @param m Mailbox to check - * @param dir_name Path to Mailbox - * @param check_new if true, check for new mail - * @param check_stats if true, count total, new, and flagged messages - * @retval 1 if the dir has new mail - * - * Checks the specified maildir subdir (cur or new) for new mail or mail counts. - */ -static int mailbox_maildir_check_dir(struct Mailbox *m, const char *dir_name, - bool check_new, bool check_stats) -{ - DIR *dirp = NULL; - struct dirent *de = NULL; - char *p = NULL; - int rc = 0; - struct stat sb; - - struct Buffer *path = mutt_buffer_pool_get(); - struct Buffer *msgpath = mutt_buffer_pool_get(); - mutt_buffer_printf(path, "%s/%s", m->path, dir_name); - - /* when $mail_check_recent is set, if the new/ directory hasn't been modified since - * the user last exited the m, then we know there is no recent mail. - */ - if (check_new && MailCheckRecent) - { - if (stat(mutt_b2s(path), &sb) == 0 && - mutt_stat_timespec_compare(&sb, MUTT_STAT_MTIME, &m->last_visited) < 0) - { - rc = 0; - check_new = false; - } - } - - if (!(check_new || check_stats)) - goto cleanup; - - dirp = opendir(mutt_b2s(path)); - if (!dirp) - { - m->magic = MUTT_UNKNOWN; - rc = 0; - goto cleanup; - } - - while ((de = readdir(dirp))) - { - if (*de->d_name == '.') - continue; - - p = strstr(de->d_name, ":2,"); - if (p && strchr(p + 3, 'T')) - continue; - - if (check_stats) - { - m->msg_count++; - if (p && strchr(p + 3, 'F')) - m->msg_flagged++; - } - if (!p || !strchr(p + 3, 'S')) - { - if (check_stats) - m->msg_unread++; - if (check_new) - { - if (MailCheckRecent) - { - mutt_buffer_printf(msgpath, "%s/%s", mutt_b2s(path), de->d_name); - /* ensure this message was received since leaving this m */ - if (stat(mutt_b2s(msgpath), &sb) == 0 && - (mutt_stat_timespec_compare(&sb, MUTT_STAT_CTIME, &m->last_visited) <= 0)) - { - continue; - } - } - m->has_new = true; - rc = 1; - check_new = false; - if (!check_stats) - break; - } - } - } - - closedir(dirp); - -cleanup: - mutt_buffer_pool_release(&path); - mutt_buffer_pool_release(&msgpath); - - return rc; -} - -/** - * mailbox_maildir_check - Check for new mail in a maildir mailbox - * @param m Mailbox to check - * @param check_stats if true, also count total, new, and flagged messages - * @retval 1 if the mailbox has new mail - */ -static int mailbox_maildir_check(struct Mailbox *m, bool check_stats) -{ - int rc = 1; - bool check_new = true; - - if (check_stats) - { - m->msg_count = 0; - m->msg_unread = 0; - m->msg_flagged = 0; - m->msg_new = 0; - } - - rc = mailbox_maildir_check_dir(m, "new", check_new, check_stats); - - check_new = !rc && MaildirCheckCur; - if (check_new || check_stats) - if (mailbox_maildir_check_dir(m, "cur", check_new, check_stats)) - rc = 1; - - return rc; -} - -/** - * mailbox_mbox_check - Check for new mail for an mbox mailbox - * @param m Mailbox to check - * @param sb stat(2) information about the mailbox - * @param check_stats if true, also count total, new, and flagged messages - * @retval 1 if the mailbox has new mail - */ -static int mailbox_mbox_check(struct Mailbox *m, struct stat *sb, bool check_stats) -{ - int rc = 0; - bool new_or_changed; - - if (CheckMboxSize) - new_or_changed = (sb->st_size > m->size); - else - { - new_or_changed = - (mutt_stat_compare(sb, MUTT_STAT_MTIME, sb, MUTT_STAT_ATIME) > 0) || - (m->newly_created && - (mutt_stat_compare(sb, MUTT_STAT_CTIME, sb, MUTT_STAT_MTIME) == 0) && - (mutt_stat_compare(sb, MUTT_STAT_CTIME, sb, MUTT_STAT_ATIME) == 0)); - } - - if (new_or_changed) - { - if (!MailCheckRecent || - (mutt_stat_timespec_compare(sb, MUTT_STAT_MTIME, &m->last_visited) > 0)) - { - rc = 1; - m->has_new = true; - } - } - else if (CheckMboxSize) - { - /* some other program has deleted mail from the folder */ - m->size = (off_t) sb->st_size; - } - - if (m->newly_created && (sb->st_ctime != sb->st_mtime || sb->st_ctime != sb->st_atime)) - m->newly_created = false; - - if (check_stats && - (mutt_stat_timespec_compare(sb, MUTT_STAT_MTIME, &m->stats_last_checked) > 0)) - { - struct Context *ctx = - mx_mbox_open(m, NULL, MUTT_READONLY | MUTT_QUIET | MUTT_NOSORT | MUTT_PEEK); - if (ctx) - { - m->msg_count = ctx->mailbox->msg_count; - m->msg_unread = ctx->mailbox->msg_unread; - m->msg_flagged = ctx->mailbox->msg_flagged; - m->stats_last_checked = ctx->mailbox->mtime; - mx_mbox_close(&ctx, NULL); - } - } - - return rc; -} - /** * mailbox_check - Check a mailbox for new mail * @param m Mailbox to check @@ -357,12 +173,12 @@ static void mailbox_check(struct Mailbox *m, struct stat *ctx_sb, bool check_sta { case MUTT_MBOX: case MUTT_MMDF: - if (mailbox_mbox_check(m, &sb, check_stats) > 0) + if (mbox_check(m, &sb, check_stats) > 0) MailboxCount++; break; case MUTT_MAILDIR: - if (mailbox_maildir_check(m, check_stats) > 0) + if (maildir_check(m, check_stats) > 0) MailboxCount++; break; diff --git a/maildir/maildir.h b/maildir/maildir.h index 9df02cd3a..1ab61c77a 100644 --- a/maildir/maildir.h +++ b/maildir/maildir.h @@ -55,6 +55,8 @@ extern char *MhSeqUnseen; extern struct MxOps mx_maildir_ops; extern struct MxOps mx_mh_ops; +int maildir_check(struct Mailbox *m, bool check_stats); +int maildir_check_dir(struct Mailbox *m, const char *dir_name, bool check_new, bool check_stats); int maildir_check_empty(const char *path); void maildir_gen_flags(char *dest, size_t destlen, struct Email *e); FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname); diff --git a/maildir/mh.c b/maildir/mh.c index 189850941..f47547721 100644 --- a/maildir/mh.c +++ b/maildir/mh.c @@ -3144,6 +3144,130 @@ enum MailboxType mh_path_probe(const char *path, const struct stat *st) return MUTT_UNKNOWN; } +/** + * maildir_check_dir - Check for new mail / mail counts + * @param m Mailbox to check + * @param dir_name Path to Mailbox + * @param check_new if true, check for new mail + * @param check_stats if true, count total, new, and flagged messages + * @retval 1 if the dir has new mail + * + * Checks the specified maildir subdir (cur or new) for new mail or mail counts. + */ +int maildir_check_dir(struct Mailbox *m, const char *dir_name, bool check_new, bool check_stats) +{ + DIR *dirp = NULL; + struct dirent *de = NULL; + char *p = NULL; + int rc = 0; + struct stat sb; + + struct Buffer *path = mutt_buffer_pool_get(); + struct Buffer *msgpath = mutt_buffer_pool_get(); + mutt_buffer_printf(path, "%s/%s", m->path, dir_name); + + /* when $mail_check_recent is set, if the new/ directory hasn't been modified since + * the user last exited the m, then we know there is no recent mail. + */ + if (check_new && MailCheckRecent) + { + if (stat(mutt_b2s(path), &sb) == 0 && + mutt_stat_timespec_compare(&sb, MUTT_STAT_MTIME, &m->last_visited) < 0) + { + rc = 0; + check_new = false; + } + } + + if (!(check_new || check_stats)) + goto cleanup; + + dirp = opendir(mutt_b2s(path)); + if (!dirp) + { + m->magic = MUTT_UNKNOWN; + rc = 0; + goto cleanup; + } + + while ((de = readdir(dirp))) + { + if (*de->d_name == '.') + continue; + + p = strstr(de->d_name, ":2,"); + if (p && strchr(p + 3, 'T')) + continue; + + if (check_stats) + { + m->msg_count++; + if (p && strchr(p + 3, 'F')) + m->msg_flagged++; + } + if (!p || !strchr(p + 3, 'S')) + { + if (check_stats) + m->msg_unread++; + if (check_new) + { + if (MailCheckRecent) + { + mutt_buffer_printf(msgpath, "%s/%s", mutt_b2s(path), de->d_name); + /* ensure this message was received since leaving this m */ + if (stat(mutt_b2s(msgpath), &sb) == 0 && + (mutt_stat_timespec_compare(&sb, MUTT_STAT_CTIME, &m->last_visited) <= 0)) + { + continue; + } + } + m->has_new = true; + rc = 1; + check_new = false; + if (!check_stats) + break; + } + } + } + + closedir(dirp); + +cleanup: + mutt_buffer_pool_release(&path); + mutt_buffer_pool_release(&msgpath); + + return rc; +} + +/** + * maildir_check - Check for new mail in a maildir mailbox + * @param m Mailbox to check + * @param check_stats if true, also count total, new, and flagged messages + * @retval 1 if the mailbox has new mail + */ +int maildir_check(struct Mailbox *m, bool check_stats) +{ + int rc = 1; + bool check_new = true; + + if (check_stats) + { + m->msg_count = 0; + m->msg_unread = 0; + m->msg_flagged = 0; + m->msg_new = 0; + } + + rc = maildir_check_dir(m, "new", check_new, check_stats); + + check_new = !rc && MaildirCheckCur; + if (check_new || check_stats) + if (maildir_check_dir(m, "cur", check_new, check_stats)) + rc = 1; + + return rc; +} + // clang-format off /** * struct mx_maildir_ops - Maildir mailbox - Implements ::MxOps diff --git a/mbox/mbox.c b/mbox/mbox.c index 4060e83d9..e9d528e93 100644 --- a/mbox/mbox.c +++ b/mbox/mbox.c @@ -1784,6 +1784,65 @@ static int mmdf_msg_padding_size(struct Mailbox *m) return 10; } +/** + * mbox_check - Check for new mail for an mbox mailbox + * @param m Mailbox to check + * @param sb stat(2) information about the mailbox + * @param check_stats if true, also count total, new, and flagged messages + * @retval 1 if the mailbox has new mail + */ +int mbox_check(struct Mailbox *m, struct stat *sb, bool check_stats) +{ + int rc = 0; + bool new_or_changed; + + if (CheckMboxSize) + new_or_changed = (sb->st_size > m->size); + else + { + new_or_changed = + (mutt_stat_compare(sb, MUTT_STAT_MTIME, sb, MUTT_STAT_ATIME) > 0) || + (m->newly_created && + (mutt_stat_compare(sb, MUTT_STAT_CTIME, sb, MUTT_STAT_MTIME) == 0) && + (mutt_stat_compare(sb, MUTT_STAT_CTIME, sb, MUTT_STAT_ATIME) == 0)); + } + + if (new_or_changed) + { + if (!MailCheckRecent || + (mutt_stat_timespec_compare(sb, MUTT_STAT_MTIME, &m->last_visited) > 0)) + { + rc = 1; + m->has_new = true; + } + } + else if (CheckMboxSize) + { + /* some other program has deleted mail from the folder */ + m->size = (off_t) sb->st_size; + } + + if (m->newly_created && (sb->st_ctime != sb->st_mtime || sb->st_ctime != sb->st_atime)) + m->newly_created = false; + + if (check_stats && + (mutt_stat_timespec_compare(sb, MUTT_STAT_MTIME, &m->stats_last_checked) > 0)) + { + struct Context *ctx = + mx_mbox_open(m, NULL, MUTT_READONLY | MUTT_QUIET | MUTT_NOSORT | MUTT_PEEK); + if (ctx) + { + m->msg_count = ctx->mailbox->msg_count; + m->msg_unread = ctx->mailbox->msg_unread; + m->msg_flagged = ctx->mailbox->msg_flagged; + m->stats_last_checked = ctx->mailbox->mtime; + mx_mbox_close(&ctx, NULL); + } + } + + return rc; +} + // clang-format off /** * struct mx_mbox_ops - Mbox mailbox - Implements ::MxOps diff --git a/mbox/mbox.h b/mbox/mbox.h index 744de4763..8ff31e8fd 100644 --- a/mbox/mbox.h +++ b/mbox/mbox.h @@ -56,8 +56,9 @@ extern struct MxOps mx_mmdf_ops; #define MMDF_SEP "\001\001\001\001\n" -void mbox_reset_atime(struct Mailbox *m, struct stat *st); +int mbox_check(struct Mailbox *m, struct stat *sb, bool check_stats); enum MailboxType mbox_path_probe(const char *path, const struct stat *st); -bool mbox_test_new_folder(const char *path); +void mbox_reset_atime(struct Mailbox *m, struct stat *st); +bool mbox_test_new_folder(const char *path); #endif /* MUTT_MBOX_MBOX_H */ -- 2.50.1