NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
mbox_check()

Check for new mail. More...

+ Collaboration diagram for mbox_check():

Functions

static enum MxStatus comp_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus imap_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus maildir_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus mh_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus mbox_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus nntp_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus nm_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 
static enum MxStatus pop_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -.
 

Detailed Description

Check for new mail.

Parameters
mMailbox
Return values
enumMxStatus
Precondition
m is not NULL

Function Documentation

◆ comp_mbox_check()

static enum MxStatus comp_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Parameters
mMailbox
Return values
enumMxStatus

If the compressed file changes in size but the mailbox hasn't been changed in NeoMutt, then we can close and reopen the mailbox.

If the mailbox has been changed in NeoMutt, warn the user.

Definition at line 585 of file compress.c.

586{
587 if (!m->compress_info)
588 return MX_STATUS_ERROR;
589
590 struct CompressInfo *ci = m->compress_info;
591
592 const struct MxOps *ops = ci->child_ops;
593 if (!ops)
594 return MX_STATUS_ERROR;
595
596 int size = mutt_file_get_size(m->realpath);
597 if (size == ci->size)
598 return MX_STATUS_OK;
599
600 if (!lock_realpath(m, false))
601 {
602 mutt_error(_("Unable to lock mailbox"));
603 return MX_STATUS_ERROR;
604 }
605
606 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
607 store_size(m);
609 if (!rc)
610 return MX_STATUS_ERROR;
611
612 return ops->mbox_check(m);
613}
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:184
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition: compress.c:89
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:130
static bool execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:327
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1560
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:64
@ MX_STATUS_OK
No changes.
Definition: mxapi.h:65
Private data for compress.
Definition: lib.h:47
const char * cmd_open
open-hook command
Definition: lib.h:50
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:52
long size
size of the compressed file
Definition: lib.h:51
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:121
Definition: mxapi.h:91
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition: mxapi.h:162
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mbox_check()

static enum MxStatus imap_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Parameters
mMailbox
Return values
>0Success, e.g. MX_STATUS_REOPENED
-1Failure

Definition at line 2096 of file imap.c.

2097{
2099 enum MxStatus rc = imap_check_mailbox(m, false);
2100 /* NOTE - mv might have been changed at this point. In particular,
2101 * m could be NULL. Beware. */
2103
2104 return rc;
2105}
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1023
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1036
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition: imap.c:1019
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:63
+ Here is the call graph for this function:

◆ maildir_mbox_check()

static enum MxStatus maildir_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Definition at line 1376 of file maildir.c.

1377{
1378 return maildir_check(m);
1379}
static enum MxStatus maildir_check(struct Mailbox *m)
Check for new mail.
Definition: maildir.c:1199
+ Here is the call graph for this function:

◆ mh_mbox_check()

static enum MxStatus mh_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Definition at line 1022 of file mh.c.

1023{
1024 return mh_check(m);
1025}
static enum MxStatus mh_check(struct Mailbox *m)
Check for new mail.
Definition: mh.c:880
+ Here is the call graph for this function:

◆ mbox_mbox_check()

static enum MxStatus mbox_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Parameters
[in]mMailbox
Return values
MX_STATUS_REOPENEDMailbox has been reopened
MX_STATUS_NEW_MAILNew mail has arrived
MX_STATUS_LOCKEDCouldn't lock the file

Definition at line 929 of file mbox.c.

930{
932 if (!adata)
933 return MX_STATUS_ERROR;
934
935 if (!adata->fp)
936 {
937 if (mbox_mbox_open(m) != MX_OPEN_OK)
938 return MX_STATUS_ERROR;
940 }
941 if (!adata->fp)
942 return MX_STATUS_ERROR;
943
944 struct stat st = { 0 };
945 bool unlock = false;
946 bool modified = false;
947
948 if (stat(mailbox_path(m), &st) == 0)
949 {
950 if ((mutt_file_stat_timespec_compare(&st, MUTT_STAT_MTIME, &adata->mtime) == 0) &&
951 (st.st_size == m->size))
952 {
953 return MX_STATUS_OK;
954 }
955
956 if (st.st_size == m->size)
957 {
958 /* the file was touched, but it is still the same length, so just exit */
960 return MX_STATUS_OK;
961 }
962
963 if (st.st_size > m->size)
964 {
965 /* lock the file if it isn't already */
966 if (!adata->locked)
967 {
969 if (mbox_lock_mailbox(m, false, false) == -1)
970 {
972 /* we couldn't lock the mailbox, but nothing serious happened:
973 * probably the new mail arrived: no reason to wait till we can
974 * parse it: we'll get it on the next pass */
975 return MX_STATUS_LOCKED;
976 }
977 unlock = 1;
978 }
979
980 /* Check to make sure that the only change to the mailbox is that
981 * message(s) were appended to this file. My heuristic is that we should
982 * see the message separator at *exactly* what used to be the end of the
983 * folder. */
984 char buf[1024] = { 0 };
985 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
986 {
987 goto error;
988 }
989 if (fgets(buf, sizeof(buf), adata->fp))
990 {
991 if (((m->type == MUTT_MBOX) && mutt_str_startswith(buf, "From ")) ||
992 ((m->type == MUTT_MMDF) && mutt_str_equal(buf, MMDF_SEP)))
993 {
994 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
995 {
996 goto error;
997 }
998
999 int old_msg_count = m->msg_count;
1000 if (m->type == MUTT_MBOX)
1002 else
1004
1005 if (m->msg_count > old_msg_count)
1007
1008 /* Only unlock the folder if it was locked inside of this routine.
1009 * It may have been locked elsewhere, like in
1010 * mutt_checkpoint_mailbox(). */
1011 if (unlock)
1012 {
1015 }
1016
1017 return MX_STATUS_NEW_MAIL; /* signal that new mail arrived */
1018 }
1019 else
1020 {
1021 modified = true;
1022 }
1023 }
1024 else
1025 {
1026 mutt_debug(LL_DEBUG1, "fgets returned NULL\n");
1027 modified = true;
1028 }
1029 }
1030 else
1031 {
1032 modified = true;
1033 }
1034 }
1035
1036 if (modified)
1037 {
1038 if (reopen_mailbox(m) != -1)
1039 {
1041 if (unlock)
1042 {
1045 }
1046 return MX_STATUS_REOPENED;
1047 }
1048 }
1049
1050 /* fatal error */
1051
1052error:
1054 mx_fastclose_mailbox(m, false);
1056 mutt_error(_("Mailbox was corrupted"));
1057 return MX_STATUS_ERROR;
1058}
void mutt_file_get_stat_timespec(struct timespec *dest, struct stat *st, enum MuttStatType type)
Read the stat() time into a time value.
Definition: file.c:1620
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:733
int mutt_file_stat_timespec_compare(struct stat *st, enum MuttStatType type, struct timespec *b)
Compare stat info with a time value.
Definition: file.c:1660
@ MUTT_STAT_MTIME
File/dir's mtime - last modified time.
Definition: file.h:64
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
static enum MxOpenReturns mbox_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition: mbox.c:828
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:226
@ NT_MAILBOX_INVALID
Email list was changed.
Definition: mailbox.h:176
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:210
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
#define MMDF_SEP
Definition: lib.h:62
static enum MxOpenReturns mbox_parse_mailbox(struct Mailbox *m)
Read a mailbox from disk.
Definition: mbox.c:351
static int mbox_lock_mailbox(struct Mailbox *m, bool excl, bool retry)
Lock a mailbox.
Definition: mbox.c:138
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:123
static void mbox_unlock_mailbox(struct Mailbox *m)
Unlock a mailbox.
Definition: mbox.c:162
static enum MxOpenReturns mmdf_parse_mailbox(struct Mailbox *m)
Read a mailbox in MMDF format.
Definition: mbox.c:182
static int reopen_mailbox(struct Mailbox *m)
Close and reopen a mailbox.
Definition: mbox.c:548
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:228
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition: mx.c:430
@ MX_OPEN_OK
Open succeeded.
Definition: mxapi.h:77
@ MX_STATUS_LOCKED
Couldn't lock the Mailbox.
Definition: mxapi.h:67
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mxapi.h:68
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:66
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:163
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:181
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
int msg_count
Total number of messages.
Definition: mailbox.h:88
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
off_t size
Size of the Mailbox.
Definition: mailbox.h:84
Mbox-specific Account data -.
Definition: lib.h:49
FILE * fp
Mailbox file.
Definition: lib.h:50
bool locked
is the mailbox locked?
Definition: lib.h:55
struct timespec mtime
Time Mailbox was last changed.
Definition: lib.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_mbox_check()

static enum MxStatus nntp_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Parameters
mMailbox
Return values
enumMxStatus

Definition at line 2494 of file nntp.c.

2495{
2496 enum MxStatus rc = check_mailbox(m);
2497 if (rc == MX_STATUS_OK)
2498 {
2499 struct NntpMboxData *mdata = m->mdata;
2500 struct NntpAccountData *adata = mdata->adata;
2502 }
2503 return rc;
2504}
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
static enum MxStatus check_mailbox(struct Mailbox *m)
Check current newsgroup for new articles.
Definition: nntp.c:1456
void * mdata
Driver specific data.
Definition: mailbox.h:133
NNTP-specific Account data -.
Definition: adata.h:36
NNTP-specific Mailbox data -.
Definition: mdata.h:34
struct NntpAccountData * adata
Definition: mdata.h:48
+ Here is the call graph for this function:

◆ nm_mbox_check()

static enum MxStatus nm_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Parameters
mMailbox
Return values
enumMxStatus

Definition at line 2081 of file notmuch.c.

2082{
2083 struct NmMboxData *mdata = nm_mdata_get(m);
2084 time_t mtime = 0;
2085 if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2086 return MX_STATUS_ERROR;
2087
2088 int new_flags = 0;
2089 bool occult = false;
2090
2091 if (mdata->mtime.tv_sec >= mtime)
2092 {
2093 mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%lu mailbox=%lu)\n", mtime,
2094 mdata->mtime.tv_sec);
2095 return MX_STATUS_OK;
2096 }
2097
2098 mutt_debug(LL_DEBUG1, "nm: checking (db=%lu mailbox=%lu)\n", mtime,
2099 mdata->mtime.tv_sec);
2100
2101 notmuch_query_t *q = get_query(m, false);
2102 if (!q)
2103 goto done;
2104
2105 mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2106 mdata->oldmsgcount = m->msg_count;
2107
2108 for (int i = 0; i < m->msg_count; i++)
2109 {
2110 struct Email *e = m->emails[i];
2111 if (!e)
2112 break;
2113
2114 e->active = false;
2115 }
2116
2117 int limit = get_limit(mdata);
2118
2119 notmuch_messages_t *msgs = get_messages(q);
2120
2121 // TODO: Analyze impact of removing this version guard.
2122#if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2123 if (!msgs)
2124 return MX_STATUS_OK;
2125#elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2126 if (!msgs)
2127 goto done;
2128#endif
2129
2130 struct HeaderCache *hc = nm_hcache_open(m);
2131
2132 for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2133 notmuch_messages_move_to_next(msgs), i++)
2134 {
2135 notmuch_message_t *msg = notmuch_messages_get(msgs);
2136 struct Email *e = get_mutt_email(m, msg);
2137
2138 if (!e)
2139 {
2140 /* new email */
2141 append_message(hc, m, msg, false);
2142 notmuch_message_destroy(msg);
2143 continue;
2144 }
2145
2146 /* message already exists, merge flags */
2147 e->active = true;
2148
2149 /* Check to see if the message has moved to a different subdirectory.
2150 * If so, update the associated filename. */
2151 const char *new_file = get_message_last_filename(msg);
2152 char old_file[PATH_MAX] = { 0 };
2153 email_get_fullpath(e, old_file, sizeof(old_file));
2154
2155 if (!mutt_str_equal(old_file, new_file))
2156 update_message_path(e, new_file);
2157
2158 if (!e->changed)
2159 {
2160 /* if the user hasn't modified the flags on this message, update the
2161 * flags we just detected. */
2162 struct Email *e_tmp = maildir_email_new();
2163 maildir_parse_flags(e_tmp, new_file);
2164 e_tmp->old = e->old;
2165 maildir_update_flags(m, e, e_tmp);
2166 email_free(&e_tmp);
2167 }
2168
2169 if (update_email_tags(e, msg) == 0)
2170 new_flags++;
2171
2172 notmuch_message_destroy(msg);
2173 }
2174
2175 nm_hcache_close(&hc);
2176
2177 for (int i = 0; i < m->msg_count; i++)
2178 {
2179 struct Email *e = m->emails[i];
2180 if (!e)
2181 break;
2182
2183 if (!e->active)
2184 {
2185 occult = true;
2186 break;
2187 }
2188 }
2189
2190 if (m->msg_count > mdata->oldmsgcount)
2192done:
2193 if (q)
2194 notmuch_query_destroy(q);
2195
2196 nm_db_release(m);
2197
2198 mdata->mtime.tv_sec = mutt_date_now();
2199 mdata->mtime.tv_nsec = 0;
2200
2201 mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2202 m->msg_count, new_flags, occult);
2203
2204 if (occult)
2205 return MX_STATUS_REOPENED;
2206 if (m->msg_count > mdata->oldmsgcount)
2207 return MX_STATUS_NEW_MAIL;
2208 if (new_flags)
2209 return MX_STATUS_FLAGS;
2210 return MX_STATUS_OK;
2211}
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:120
struct Email * maildir_email_new(void)
Create a Maildir Email.
Definition: maildir.c:85
void maildir_parse_flags(struct Email *e, const char *path)
Parse Maildir file flags.
Definition: maildir.c:840
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:446
#define PATH_MAX
Definition: mutt.h:41
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mxapi.h:69
int nm_db_get_mtime(struct Mailbox *m, time_t *mtime)
Get the database modification time.
Definition: db.c:306
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: db.c:224
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mdata.c:96
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: notmuch.c:229
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: notmuch.c:406
static struct HeaderCache * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: notmuch.c:110
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: notmuch.c:441
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: notmuch.c:524
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message's last filename.
Definition: notmuch.c:652
static void append_message(struct HeaderCache *hc, struct Mailbox *m, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: notmuch.c:739
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email's tags from Notmuch.
Definition: notmuch.c:473
static void nm_hcache_close(struct HeaderCache **ptr)
Close the header cache.
Definition: notmuch.c:124
static notmuch_messages_t * get_messages(notmuch_query_t *query)
Load messages for a query.
Definition: notmuch.c:903
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: notmuch.c:705
The envelope/body of an email.
Definition: email.h:37
bool active
Message is not to be removed.
Definition: email.h:74
bool old
Email is seen, but unread.
Definition: email.h:47
bool changed
Email has been edited.
Definition: email.h:75
Header Cache.
Definition: lib.h:88
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
Notmuch-specific Mailbox data -.
Definition: mdata.h:35
int oldmsgcount
Definition: mdata.h:42
struct timespec mtime
Time Mailbox was last changed.
Definition: mdata.h:44
long tv_nsec
Number of nanosecond, on top.
Definition: file.h:52
time_t tv_sec
Number of seconds since the epoch.
Definition: file.h:51
+ Here is the call graph for this function:

◆ pop_mbox_check()

static enum MxStatus pop_mbox_check ( struct Mailbox m)
static

Check for new mail - Implements MxOps::mbox_check() -.

Definition at line 816 of file pop.c.

817{
818 if (!m || !m->account)
819 return MX_STATUS_ERROR;
820
822
823 const short c_pop_check_interval = cs_subset_number(NeoMutt->sub, "pop_check_interval");
824 if ((adata->check_time + c_pop_check_interval) > mutt_date_now())
825 return MX_STATUS_OK;
826
827 pop_logout(m);
828
830
831 if (pop_open_connection(adata) < 0)
832 return MX_STATUS_ERROR;
833
834 m->size = adata->size;
835
836 mutt_message(_("Checking for new messages..."));
837
838 int old_msg_count = m->msg_count;
839 int rc = pop_fetch_headers(m);
841 if (m->msg_count > old_msg_count)
843
844 if (rc < 0)
845 return MX_STATUS_ERROR;
846
847 if (rc > 0)
848 return MX_STATUS_NEW_MAIL;
849
850 return MX_STATUS_OK;
851}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:144
#define mutt_message(...)
Definition: logging2.h:91
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:73
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition: lib.c:316
void pop_logout(struct Mailbox *m)
Logout from a POP server.
Definition: lib.c:424
static void pop_clear_cache(struct PopAccountData *adata)
Delete all cached messages.
Definition: pop.c:491
static int pop_fetch_headers(struct Mailbox *m)
Read headers.
Definition: pop.c:322
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:101
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:128
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
POP-specific Account data -.
Definition: adata.h:37
+ Here is the call graph for this function: