NeoMutt  2025-12-11-694-ga89709
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 554 of file compress.c.

555{
556 if (!m->compress_info)
557 return MX_STATUS_ERROR;
558
559 struct CompressInfo *ci = m->compress_info;
560
561 const struct MxOps *ops = ci->child_ops;
562 if (!ops)
563 return MX_STATUS_ERROR;
564
565 long size = mutt_file_get_size(m->realpath);
566 if (size == ci->size)
567 return MX_STATUS_OK;
568
569 if (!lock_realpath(m, false))
570 {
571 mutt_error(_("Unable to lock mailbox"));
572 return MX_STATUS_ERROR;
573 }
574
575 bool rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
576 store_size(m);
578 if (!rc)
579 return MX_STATUS_ERROR;
580
581 return ops->mbox_check(m);
582}
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:108
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition compress.c:153
static bool execute_command(struct Mailbox *m, const struct Expando *exp, const char *progress)
Run a system command.
Definition compress.c:295
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition file.c:1414
#define mutt_error(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
@ MX_STATUS_ERROR
An error occurred.
Definition mxapi.h:60
@ MX_STATUS_OK
No changes.
Definition mxapi.h:61
Private data for compress.
Definition lib.h:61
struct Expando * cmd_open
open-hook command
Definition lib.h:64
const struct MxOps * child_ops
callbacks of de-compressed file
Definition lib.h:66
long size
size of the compressed file
Definition lib.h:65
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition mailbox.h:80
void * compress_info
Compressed mbox module private data.
Definition mailbox.h:120
Definition mxapi.h:87
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition mxapi.h:158
+ 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 2307 of file imap.c.

2308{
2310 enum MxStatus rc = imap_check_mailbox(m, false);
2311 /* NOTE - mv might have been changed at this point. In particular,
2312 * m could be NULL. Beware. */
2314
2315 return rc;
2316}
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition util.c:1075
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition util.c:1088
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition imap.c:1212
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition mxapi.h:59
+ 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 811 of file mailbox.c.

812{
813 return maildir_check(m);
814}
static enum MxStatus maildir_check(struct Mailbox *m)
Check for new mail.
Definition mailbox.c:545
+ 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 933 of file mbox.c.

934{
936 if (!adata)
937 return MX_STATUS_ERROR;
938
939 if (!adata->fp)
940 {
941 if (mbox_mbox_open(m) != MX_OPEN_OK)
942 return MX_STATUS_ERROR;
944 }
945 if (!adata->fp)
946 return MX_STATUS_ERROR;
947
948 struct stat st = { 0 };
949 bool unlock = false;
950 bool modified = false;
951
952 if (stat(mailbox_path(m), &st) == 0)
953 {
954 if ((mutt_file_stat_timespec_compare(&st, MUTT_STAT_MTIME, &adata->mtime) == 0) &&
955 (st.st_size == m->size))
956 {
957 return MX_STATUS_OK;
958 }
959
960 if (st.st_size == m->size)
961 {
962 /* the file was touched, but it is still the same length, so just exit */
964 return MX_STATUS_OK;
965 }
966
967 if (st.st_size > m->size)
968 {
969 /* lock the file if it isn't already */
970 if (!adata->locked)
971 {
973 if (mbox_lock_mailbox(m, false, false) == -1)
974 {
976 /* we couldn't lock the mailbox, but nothing serious happened:
977 * probably the new mail arrived: no reason to wait till we can
978 * parse it: we'll get it on the next pass */
979 return MX_STATUS_LOCKED;
980 }
981 unlock = 1;
982 }
983
984 /* Check to make sure that the only change to the mailbox is that
985 * message(s) were appended to this file. My heuristic is that we should
986 * see the message separator at *exactly* what used to be the end of the
987 * folder. */
988 char buf[1024] = { 0 };
989 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
990 {
991 goto error;
992 }
993 if (fgets(buf, sizeof(buf), adata->fp))
994 {
995 if (((m->type == MUTT_MBOX) && mutt_str_startswith(buf, "From ")) ||
996 ((m->type == MUTT_MMDF) && mutt_str_equal(buf, MMDF_SEP)))
997 {
998 if (!mutt_file_seek(adata->fp, m->size, SEEK_SET))
999 {
1000 goto error;
1001 }
1002
1003 int old_msg_count = m->msg_count;
1004 if (m->type == MUTT_MBOX)
1006 else
1008
1009 if (m->msg_count > old_msg_count)
1011
1012 /* Only unlock the folder if it was locked inside of this routine.
1013 * It may have been locked elsewhere, like in
1014 * mutt_checkpoint_mailbox(). */
1015 if (unlock)
1016 {
1019 }
1020
1021 return MX_STATUS_NEW_MAIL; /* signal that new mail arrived */
1022 }
1023 else
1024 {
1025 modified = true;
1026 }
1027 }
1028 else
1029 {
1030 mutt_debug(LL_DEBUG1, "fgets returned NULL\n");
1031 modified = true;
1032 }
1033 }
1034 else
1035 {
1036 modified = true;
1037 }
1038 }
1039
1040 if (modified)
1041 {
1042 if (reopen_mailbox(m) != -1)
1043 {
1045 if (unlock)
1046 {
1049 }
1050 return MX_STATUS_REOPENED;
1051 }
1052 }
1053
1054 /* fatal error */
1055
1056error:
1058 mx_fastclose_mailbox(m, false);
1060 mutt_error(_("Mailbox was corrupted"));
1061 return MX_STATUS_ERROR;
1062}
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition mailbox.c:232
@ NT_MAILBOX_INVALID
Email list was changed.
Definition mailbox.h:179
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:213
@ MUTT_MMDF
'mmdf' Mailbox type
Definition mailbox.h:45
@ MUTT_MBOX
'mbox' Mailbox type
Definition mailbox.h:44
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:1474
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
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:1514
@ MUTT_STAT_MTIME
File/dir's mtime - last modified time.
Definition file.h:54
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
static enum MxOpenReturns mbox_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition mbox.c:832
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
#define MMDF_SEP
Definition lib.h:63
static enum MxOpenReturns mbox_parse_mailbox(struct Mailbox *m)
Read a mailbox from disk.
Definition mbox.c:355
static int mbox_lock_mailbox(struct Mailbox *m, bool excl, bool retry)
Lock a mailbox.
Definition mbox.c:136
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition mbox.c:121
static void mbox_unlock_mailbox(struct Mailbox *m)
Unlock a mailbox.
Definition mbox.c:160
static enum MxOpenReturns mmdf_parse_mailbox(struct Mailbox *m)
Read a mailbox in MMDF format.
Definition mbox.c:180
static int reopen_mailbox(struct Mailbox *m)
Close and reopen a mailbox.
Definition mbox.c:552
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition mx.c:411
@ MX_OPEN_OK
Open succeeded.
Definition mxapi.h:73
@ MX_STATUS_LOCKED
Couldn't lock the Mailbox.
Definition mxapi.h:63
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition mxapi.h:64
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition mxapi.h:62
void mutt_sig_block(void)
Block signals during critical operations.
Definition signal.c:227
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition signal.c:245
void * adata
Private data (for Mailbox backends)
Definition account.h:42
int msg_count
Total number of messages.
Definition mailbox.h:87
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
off_t size
Size of the Mailbox.
Definition mailbox.h:83
Mbox-specific Account data -.
Definition lib.h:50
FILE * fp
Mailbox file.
Definition lib.h:51
bool locked
is the mailbox locked?
Definition lib.h:56
struct timespec mtime
Time Mailbox was last changed.
Definition lib.h:52
+ 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 1053 of file mh.c.

1054{
1055 return mh_check(m);
1056}
static enum MxStatus mh_check(struct Mailbox *m)
Check for new mail.
Definition mh.c:911
+ 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 2548 of file nntp.c.

2549{
2550 enum MxStatus rc = check_mailbox(m);
2551 if (rc == MX_STATUS_OK)
2552 {
2553 struct NntpMboxData *mdata = m->mdata;
2554 struct NntpAccountData *adata = mdata->adata;
2556 }
2557 return rc;
2558}
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition newsrc.c:119
static enum MxStatus check_mailbox(struct Mailbox *m)
Check current newsgroup for new articles.
Definition nntp.c:1492
void * mdata
Driver specific data.
Definition mailbox.h:131
NNTP-specific Account data -.
Definition adata.h:36
NNTP-specific Mailbox data -.
Definition mdata.h:34
struct NntpAccountData * adata
Account data.
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 2140 of file notmuch.c.

2141{
2142 struct NmMboxData *mdata = nm_mdata_get(m);
2143 time_t mtime = 0;
2144 if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2145 return MX_STATUS_ERROR;
2146
2147 int new_flags = 0;
2148 bool occult = false;
2149
2150 if (mdata->mtime.tv_sec >= mtime)
2151 {
2152 mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%llu mailbox=%llu)\n",
2153 (unsigned long long) mtime, (unsigned long long) mdata->mtime.tv_sec);
2154 return MX_STATUS_OK;
2155 }
2156
2157 mutt_debug(LL_DEBUG1, "nm: checking (db=%llu mailbox=%llu)\n",
2158 (unsigned long long) mtime, (unsigned long long) mdata->mtime.tv_sec);
2159
2160 notmuch_query_t *q = get_query(m, false);
2161 if (!q)
2162 goto done;
2163
2164 mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2165 mdata->oldmsgcount = m->msg_count;
2166
2167 for (int i = 0; i < m->msg_count; i++)
2168 {
2169 struct Email *e = m->emails[i];
2170 if (!e)
2171 break;
2172
2173 e->active = false;
2174 }
2175
2176 int limit = get_limit(mdata);
2177
2178 notmuch_messages_t *msgs = get_messages(q);
2179
2180 // TODO: Analyze impact of removing this version guard.
2181#if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2182 if (!msgs)
2183 goto done;
2184#elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2185 if (!msgs)
2186 goto done;
2187#endif
2188
2189 struct HeaderCache *hc = nm_hcache_open(m);
2190
2191 for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2192 notmuch_messages_move_to_next(msgs), i++)
2193 {
2194 notmuch_message_t *msg = notmuch_messages_get(msgs);
2195 struct Email *e = get_mutt_email(m, msg);
2196
2197 if (!e)
2198 {
2199 /* new email */
2200 append_message(hc, m, msg, false);
2201 notmuch_message_destroy(msg);
2202 continue;
2203 }
2204
2205 /* message already exists, merge flags */
2206 e->active = true;
2207
2208 /* Check to see if the message has moved to a different subdirectory.
2209 * If so, update the associated filename. */
2210 char *new_file = get_message_last_filename(msg);
2211 char old_file[PATH_MAX] = { 0 };
2212 email_get_fullpath(e, old_file, sizeof(old_file));
2213
2214 if (!mutt_str_equal(old_file, new_file))
2215 update_message_path(e, new_file);
2216
2217 if (!e->changed)
2218 {
2219 /* if the user hasn't modified the flags on this message, update the
2220 * flags we just detected. */
2221 struct Email *e_tmp = maildir_email_new();
2222 maildir_parse_flags(e_tmp, new_file);
2223 e_tmp->old = e->old;
2224 maildir_update_flags(m, e, e_tmp);
2225 email_free(&e_tmp);
2226 }
2227
2228 FREE(&new_file);
2229
2230 if (update_email_tags(e, msg) == 0)
2231 new_flags++;
2232
2233 notmuch_message_destroy(msg);
2234 }
2235
2236 nm_hcache_close(&hc);
2237
2238 for (int i = 0; i < m->msg_count; i++)
2239 {
2240 struct Email *e = m->emails[i];
2241 if (!e)
2242 break;
2243
2244 if (!e->active)
2245 {
2246 occult = true;
2247 break;
2248 }
2249 }
2250
2251 if (m->msg_count > mdata->oldmsgcount)
2253done:
2254 if (q)
2255 notmuch_query_destroy(q);
2256
2257 nm_db_release(m);
2258
2259 mdata->mtime.tv_sec = mutt_date_now();
2260 mdata->mtime.tv_nsec = 0;
2261
2262 mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2263 m->msg_count, new_flags, occult);
2264
2265 if (occult)
2266 return MX_STATUS_REOPENED;
2267 if (m->msg_count > mdata->oldmsgcount)
2268 return MX_STATUS_NEW_MAIL;
2269 if (new_flags)
2270 return MX_STATUS_FLAGS;
2271 return MX_STATUS_OK;
2272}
void email_free(struct Email **ptr)
Free an Email.
Definition email.c:46
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
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:104
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition date.c:457
#define PATH_MAX
Definition mutt.h:49
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition mxapi.h:65
int nm_db_get_mtime(struct Mailbox *m, time_t *mtime)
Get the database modification time.
Definition db.c:315
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition db.c:233
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:230
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:111
static char * get_message_last_filename(notmuch_message_t *msg)
Get a message's last filename.
Definition notmuch.c:687
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:536
static void append_message(struct HeaderCache *hc, struct Mailbox *m, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition notmuch.c:774
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:125
static notmuch_messages_t * get_messages(notmuch_query_t *query)
Load messages for a query.
Definition notmuch.c:946
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition notmuch.c:740
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:87
struct Email ** emails
Array of Emails.
Definition mailbox.h:95
Notmuch-specific Mailbox data -.
Definition mdata.h:35
int oldmsgcount
Old message count.
Definition mdata.h:42
struct timespec mtime
Time Mailbox was last changed.
Definition mdata.h:44
+ 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 823 of file pop.c.

824{
825 if (!m || !m->account)
826 return MX_STATUS_ERROR;
827
829
830 const short c_pop_check_interval = cs_subset_number(NeoMutt->sub, "pop_check_interval");
831 if ((adata->check_time + c_pop_check_interval) > mutt_date_now())
832 return MX_STATUS_OK;
833
834 pop_logout(m);
835
837
838 if (pop_open_connection(adata) < 0)
839 return MX_STATUS_ERROR;
840
841 m->size = adata->size;
842
843 mutt_message(_("Checking for new messages..."));
844
845 int old_msg_count = m->msg_count;
846 int rc = pop_fetch_headers(m);
848 if (m->msg_count > old_msg_count)
850
851 if (rc < 0)
852 return MX_STATUS_ERROR;
853
854 if (rc > 0)
855 return MX_STATUS_NEW_MAIL;
856
857 return MX_STATUS_OK;
858}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
#define mutt_message(...)
Definition logging2.h:93
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:425
static void pop_clear_cache(struct PopAccountData *adata)
Delete all cached messages.
Definition pop.c:498
static int pop_fetch_headers(struct Mailbox *m)
Read headers.
Definition pop.c:329
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:126
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
POP-specific Account data -.
Definition adata.h:37
+ Here is the call graph for this function: