NeoMutt  2024-03-23-23-gec7045
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() -.
 
enum MxStatus maildir_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 mh_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 583 of file compress.c.

584{
585 if (!m->compress_info)
586 return MX_STATUS_ERROR;
587
588 struct CompressInfo *ci = m->compress_info;
589
590 const struct MxOps *ops = ci->child_ops;
591 if (!ops)
592 return MX_STATUS_ERROR;
593
594 int size = mutt_file_get_size(m->realpath);
595 if (size == ci->size)
596 return MX_STATUS_OK;
597
598 if (!lock_realpath(m, false))
599 {
600 mutt_error(_("Unable to lock mailbox"));
601 return MX_STATUS_ERROR;
602 }
603
604 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
605 store_size(m);
607 if (!rc)
608 return MX_STATUS_ERROR;
609
610 return ops->mbox_check(m);
611}
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:202
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the Mailbox.realpath.
Definition: compress.c:107
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:148
static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
Run a system command.
Definition: compress.c:323
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:58
struct Expando * cmd_open
open-hook command
Definition: lib.h:61
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:63
long size
size of the compressed file
Definition: lib.h:62
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 2106 of file imap.c.

2107{
2109 enum MxStatus rc = imap_check_mailbox(m, false);
2110 /* NOTE - mv might have been changed at this point. In particular,
2111 * m could be NULL. Beware. */
2113
2114 return rc;
2115}
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1026
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1039
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition: imap.c:1031
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition: mxapi.h:63
+ Here is the call graph for this function:

◆ maildir_mbox_check()

enum MxStatus maildir_mbox_check ( struct Mailbox m)

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

Definition at line 800 of file mailbox.c.

801{
802 return maildir_check(m);
803}
static enum MxStatus maildir_check(struct Mailbox *m)
Check for new mail.
Definition: mailbox.c:537
+ 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 928 of file mbox.c.

929{
931 if (!adata)
932 return MX_STATUS_ERROR;
933
934 if (!adata->fp)
935 {
936 if (mbox_mbox_open(m) != MX_OPEN_OK)
937 return MX_STATUS_ERROR;
939 }
940 if (!adata->fp)
941 return MX_STATUS_ERROR;
942
943 struct stat st = { 0 };
944 bool unlock = false;
945 bool modified = false;
946
947 if (stat(mailbox_path(m), &st) == 0)
948 {
949 if ((mutt_file_stat_timespec_compare(&st, MUTT_STAT_MTIME, &adata->mtime) == 0) &&
950 (st.st_size == m->size))
951 {
952 return MX_STATUS_OK;
953 }
954
955 if (st.st_size == m->size)
956 {
957 /* the file was touched, but it is still the same length, so just exit */
959 return MX_STATUS_OK;
960 }
961
962 if (st.st_size > m->size)
963 {
964 /* lock the file if it isn't already */
965 if (!adata->locked)
966 {
968 if (mbox_lock_mailbox(m, false, false) == -1)
969 {
971 /* we couldn't lock the mailbox, but nothing serious happened:
972 * probably the new mail arrived: no reason to wait till we can
973 * parse it: we'll get it on the next pass */
974 return MX_STATUS_LOCKED;
975 }
976 unlock = 1;
977 }
978
979 /* Check to make sure that the only change to the mailbox is that
980 * message(s) were appended to this file. My heuristic is that we should
981 * see the message separator at *exactly* what used to be the end of the
982 * folder. */
983 char buf[1024] = { 0 };
984 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
985 {
986 goto error;
987 }
988 if (fgets(buf, sizeof(buf), adata->fp))
989 {
990 if (((m->type == MUTT_MBOX) && mutt_str_startswith(buf, "From ")) ||
991 ((m->type == MUTT_MMDF) && mutt_str_equal(buf, MMDF_SEP)))
992 {
993 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
994 {
995 goto error;
996 }
997
998 int old_msg_count = m->msg_count;
999 if (m->type == MUTT_MBOX)
1001 else
1003
1004 if (m->msg_count > old_msg_count)
1006
1007 /* Only unlock the folder if it was locked inside of this routine.
1008 * It may have been locked elsewhere, like in
1009 * mutt_checkpoint_mailbox(). */
1010 if (unlock)
1011 {
1014 }
1015
1016 return MX_STATUS_NEW_MAIL; /* signal that new mail arrived */
1017 }
1018 else
1019 {
1020 modified = true;
1021 }
1022 }
1023 else
1024 {
1025 mutt_debug(LL_DEBUG1, "fgets returned NULL\n");
1026 modified = true;
1027 }
1028 }
1029 else
1030 {
1031 modified = true;
1032 }
1033 }
1034
1035 if (modified)
1036 {
1037 if (reopen_mailbox(m) != -1)
1038 {
1040 if (unlock)
1041 {
1044 }
1045 return MX_STATUS_REOPENED;
1046 }
1047 }
1048
1049 /* fatal error */
1050
1051error:
1053 mx_fastclose_mailbox(m, false);
1055 mutt_error(_("Mailbox was corrupted"));
1056 return MX_STATUS_ERROR;
1057}
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:234
@ NT_MAILBOX_INVALID
Email list was changed.
Definition: mailbox.h:189
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:223
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
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:771
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:65
#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:827
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#define MMDF_SEP
Definition: lib.h:62
static enum MxOpenReturns mbox_parse_mailbox(struct Mailbox *m)
Read a mailbox from disk.
Definition: mbox.c:350
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:547
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:709
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition: mx.c:412
@ 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:166
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:184
void * adata
Private data (for Mailbox backends)
Definition: account.h:42
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:

◆ mh_mbox_check()

static enum MxStatus mh_mbox_check ( struct Mailbox m)
static

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

Definition at line 1049 of file mh.c.

1050{
1051 return mh_check(m);
1052}
static enum MxStatus mh_check(struct Mailbox *m)
Check for new mail.
Definition: mh.c:907
+ Here is the call 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 2499 of file nntp.c.

2500{
2501 enum MxStatus rc = check_mailbox(m);
2502 if (rc == MX_STATUS_OK)
2503 {
2504 struct NntpMboxData *mdata = m->mdata;
2505 struct NntpAccountData *adata = mdata->adata;
2507 }
2508 return rc;
2509}
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:121
static enum MxStatus check_mailbox(struct Mailbox *m)
Check current newsgroup for new articles.
Definition: nntp.c:1459
void * mdata
Driver specific data.
Definition: mailbox.h:132
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 2090 of file notmuch.c.

2091{
2092 struct NmMboxData *mdata = nm_mdata_get(m);
2093 time_t mtime = 0;
2094 if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2095 return MX_STATUS_ERROR;
2096
2097 int new_flags = 0;
2098 bool occult = false;
2099
2100 if (mdata->mtime.tv_sec >= mtime)
2101 {
2102 mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%llu mailbox=%llu)\n",
2103 (unsigned long long) mtime, (unsigned long long) mdata->mtime.tv_sec);
2104 return MX_STATUS_OK;
2105 }
2106
2107 mutt_debug(LL_DEBUG1, "nm: checking (db=%llu mailbox=%llu)\n",
2108 (unsigned long long) mtime, (unsigned long long) mdata->mtime.tv_sec);
2109
2110 notmuch_query_t *q = get_query(m, false);
2111 if (!q)
2112 goto done;
2113
2114 mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2115 mdata->oldmsgcount = m->msg_count;
2116
2117 for (int i = 0; i < m->msg_count; i++)
2118 {
2119 struct Email *e = m->emails[i];
2120 if (!e)
2121 break;
2122
2123 e->active = false;
2124 }
2125
2126 int limit = get_limit(mdata);
2127
2128 notmuch_messages_t *msgs = get_messages(q);
2129
2130 // TODO: Analyze impact of removing this version guard.
2131#if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2132 if (!msgs)
2133 return MX_STATUS_OK;
2134#elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2135 if (!msgs)
2136 goto done;
2137#endif
2138
2139 struct HeaderCache *hc = nm_hcache_open(m);
2140
2141 for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2142 notmuch_messages_move_to_next(msgs), i++)
2143 {
2144 notmuch_message_t *msg = notmuch_messages_get(msgs);
2145 struct Email *e = get_mutt_email(m, msg);
2146
2147 if (!e)
2148 {
2149 /* new email */
2150 append_message(hc, m, msg, false);
2151 notmuch_message_destroy(msg);
2152 continue;
2153 }
2154
2155 /* message already exists, merge flags */
2156 e->active = true;
2157
2158 /* Check to see if the message has moved to a different subdirectory.
2159 * If so, update the associated filename. */
2160 const char *new_file = get_message_last_filename(msg);
2161 char old_file[PATH_MAX] = { 0 };
2162 email_get_fullpath(e, old_file, sizeof(old_file));
2163
2164 if (!mutt_str_equal(old_file, new_file))
2165 update_message_path(e, new_file);
2166
2167 if (!e->changed)
2168 {
2169 /* if the user hasn't modified the flags on this message, update the
2170 * flags we just detected. */
2171 struct Email *e_tmp = maildir_email_new();
2172 maildir_parse_flags(e_tmp, new_file);
2173 e_tmp->old = e->old;
2174 maildir_update_flags(m, e, e_tmp);
2175 email_free(&e_tmp);
2176 }
2177
2178 if (update_email_tags(e, msg) == 0)
2179 new_flags++;
2180
2181 notmuch_message_destroy(msg);
2182 }
2183
2184 nm_hcache_close(&hc);
2185
2186 for (int i = 0; i < m->msg_count; i++)
2187 {
2188 struct Email *e = m->emails[i];
2189 if (!e)
2190 break;
2191
2192 if (!e->active)
2193 {
2194 occult = true;
2195 break;
2196 }
2197 }
2198
2199 if (m->msg_count > mdata->oldmsgcount)
2201done:
2202 if (q)
2203 notmuch_query_destroy(q);
2204
2205 nm_db_release(m);
2206
2207 mdata->mtime.tv_sec = mutt_date_now();
2208 mdata->mtime.tv_nsec = 0;
2209
2210 mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2211 m->msg_count, new_flags, occult);
2212
2213 if (occult)
2214 return MX_STATUS_REOPENED;
2215 if (m->msg_count > mdata->oldmsgcount)
2216 return MX_STATUS_NEW_MAIL;
2217 if (new_flags)
2218 return MX_STATUS_FLAGS;
2219 return MX_STATUS_OK;
2220}
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:46
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
struct Email * maildir_email_new(void)
Create a Maildir Email.
Definition: mailbox.c:68
void maildir_parse_flags(struct Email *e, const char *path)
Parse Maildir file flags.
Definition: mailbox.c:82
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:105
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:455
#define PATH_MAX
Definition: mutt.h:42
@ 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:314
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: db.c:232
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:237
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: notmuch.c:414
static struct HeaderCache * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: notmuch.c:118
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: notmuch.c:449
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: notmuch.c:533
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message's last filename.
Definition: notmuch.c:661
static void append_message(struct HeaderCache *hc, struct Mailbox *m, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: notmuch.c:748
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email's tags from Notmuch.
Definition: notmuch.c:481
static void nm_hcache_close(struct HeaderCache **ptr)
Close the header cache.
Definition: notmuch.c:132
static notmuch_messages_t * get_messages(notmuch_query_t *query)
Load messages for a query.
Definition: notmuch.c:912
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: notmuch.c:714
The envelope/body of an email.
Definition: email.h:39
bool active
Message is not to be removed.
Definition: email.h:76
bool old
Email is seen, but unread.
Definition: email.h:49
bool changed
Email has been edited.
Definition: email.h:77
Header Cache.
Definition: lib.h:86
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:53
time_t tv_sec
Number of seconds since the epoch.
Definition: file.h:52
+ 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 818 of file pop.c.

819{
820 if (!m || !m->account)
821 return MX_STATUS_ERROR;
822
824
825 const short c_pop_check_interval = cs_subset_number(NeoMutt->sub, "pop_check_interval");
826 if ((adata->check_time + c_pop_check_interval) > mutt_date_now())
827 return MX_STATUS_OK;
828
829 pop_logout(m);
830
832
833 if (pop_open_connection(adata) < 0)
834 return MX_STATUS_ERROR;
835
836 m->size = adata->size;
837
838 mutt_message(_("Checking for new messages..."));
839
840 int old_msg_count = m->msg_count;
841 int rc = pop_fetch_headers(m);
843 if (m->msg_count > old_msg_count)
845
846 if (rc < 0)
847 return MX_STATUS_ERROR;
848
849 if (rc > 0)
850 return MX_STATUS_NEW_MAIL;
851
852 return MX_STATUS_OK;
853}
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:317
void pop_logout(struct Mailbox *m)
Logout from a POP server.
Definition: lib.c:425
static void pop_clear_cache(struct PopAccountData *adata)
Delete all cached messages.
Definition: pop.c:493
static int pop_fetch_headers(struct Mailbox *m)
Read headers.
Definition: pop.c:324
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:100
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
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: