NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
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() -. More...
 
static enum MxStatus imap_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 
enum MxStatus maildir_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -This function handles arrival of new mail and reopening of maildir folders. More...
 
enum MxStatus mh_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -This function handles arrival of new mail and reopening of mh/maildir folders. More...
 
static enum MxStatus mbox_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 
static enum MxStatus nntp_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 
static enum MxStatus nm_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 
static enum MxStatus pop_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 

Detailed Description

Check for new mail.

Parameters
mMailbox
Return values
enumMxStatus

Contract

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 579 of file compress.c.

580 {
581  if (!m->compress_info)
582  return MX_STATUS_ERROR;
583 
584  struct CompressInfo *ci = m->compress_info;
585 
586  const struct MxOps *ops = ci->child_ops;
587  if (!ops)
588  return MX_STATUS_ERROR;
589 
590  int size = mutt_file_get_size(m->realpath);
591  if (size == ci->size)
592  return MX_STATUS_OK;
593 
594  if (!lock_realpath(m, false))
595  {
596  mutt_error(_("Unable to lock mailbox"));
597  return MX_STATUS_ERROR;
598  }
599 
600  int rc = execute_command(m, ci->cmd_open, _("Decompressing %s"));
601  store_size(m);
602  unlock_realpath(m);
603  if (rc == 0)
604  return MX_STATUS_ERROR;
605 
606  return ops->mbox_check(m);
607 }
long mutt_file_get_size(const char *path)
Get the size of a file.
Definition: file.c:1498
#define mutt_error(...)
Definition: logging.h:88
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
#define _(a)
Definition: message.h:28
long size
size of the compressed file
Definition: lib.h:51
static void store_size(const struct Mailbox *m)
Save the size of the compressed file.
Definition: compress.c:178
enum MxStatus(* mbox_check)(struct Mailbox *m)
Definition: mxapi.h:180
No changes.
Definition: mxapi.h:78
static void unlock_realpath(struct Mailbox *m)
Unlock the mailbox->realpath.
Definition: compress.c:124
Private data for compress.
Definition: lib.h:46
static int execute_command(struct Mailbox *m, const char *command, const char *progress)
Run a system command.
Definition: compress.c:319
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
static bool lock_realpath(struct Mailbox *m, bool excl)
Try to lock the ctx->realpath.
Definition: compress.c:85
const struct MxOps * child_ops
callbacks of de-compressed file
Definition: lib.h:52
const char * cmd_open
open-hook command
Definition: lib.h:50
Definition: mxapi.h:103
An error occurred.
Definition: mxapi.h:77
+ 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 2169 of file imap.c.

2170 {
2171  imap_allow_reopen(m);
2172  enum MxStatus rc = imap_check_mailbox(m, false);
2173  /* NOTE - ctx might have been changed at this point. In particular,
2174  * m could be NULL. Beware. */
2176 
2177  return rc;
2178 }
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1034
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1021
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1103
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
+ 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() -This function handles arrival of new mail and reopening of maildir folders.

The basic idea here is we check to see if either the new or cur subdirectories have changed, and if so, we scan them for the list of files. We check for newly added messages, and then merge the flags messages we already knew about. We don't treat either subdirectory differently, as mail could be copied directly into the cur directory from another agent.

Definition at line 1166 of file maildir.c.

1167 {
1168  struct stat st_new; /* status of the "new" subdirectory */
1169  struct stat st_cur; /* status of the "cur" subdirectory */
1170  int changed = MMC_NO_DIRS; /* which subdirectories have changed */
1171  bool occult = false; /* messages were removed from the mailbox */
1172  int num_new = 0; /* number of new messages added to the mailbox */
1173  bool flags_changed = false; /* message flags were changed in the mailbox */
1174  struct HashTable *fnames = NULL; /* hash table for quickly looking up the base filename
1175  for a maildir message */
1177 
1178  /* XXX seems like this check belongs in mx_mbox_check() rather than here. */
1179  const bool c_check_new = cs_subset_bool(NeoMutt->sub, "check_new");
1180  if (!c_check_new)
1181  return MX_STATUS_OK;
1182 
1183  struct Buffer *buf = mutt_buffer_pool_get();
1184  mutt_buffer_printf(buf, "%s/new", mailbox_path(m));
1185  if (stat(mutt_buffer_string(buf), &st_new) == -1)
1186  {
1188  return MX_STATUS_ERROR;
1189  }
1190 
1191  mutt_buffer_printf(buf, "%s/cur", mailbox_path(m));
1192  if (stat(mutt_buffer_string(buf), &st_cur) == -1)
1193  {
1195  return MX_STATUS_ERROR;
1196  }
1197 
1198  /* determine which subdirectories need to be scanned */
1199  if (mutt_file_stat_timespec_compare(&st_new, MUTT_STAT_MTIME, &m->mtime) > 0)
1200  changed = MMC_NEW_DIR;
1201  if (mutt_file_stat_timespec_compare(&st_cur, MUTT_STAT_MTIME, &mdata->mtime_cur) > 0)
1202  changed |= MMC_CUR_DIR;
1203 
1204  if (changed == MMC_NO_DIRS)
1205  {
1207  return MX_STATUS_OK; /* nothing to do */
1208  }
1209 
1210  /* Update the modification times on the mailbox.
1211  *
1212  * The monitor code notices changes in the open mailbox too quickly.
1213  * In practice, this sometimes leads to all the new messages not being
1214  * noticed during the SAME group of mtime stat updates. To work around
1215  * the problem, don't update the stat times for a monitor caused check. */
1216 #ifdef USE_INOTIFY
1218  MonitorContextChanged = false;
1219  else
1220 #endif
1221  {
1224  }
1225 
1226  /* do a fast scan of just the filenames in
1227  * the subdirectories that have changed. */
1228  struct MdEmailArray mda = ARRAY_HEAD_INITIALIZER;
1229  if (changed & MMC_NEW_DIR)
1230  maildir_parse_dir(m, &mda, "new", NULL);
1231  if (changed & MMC_CUR_DIR)
1232  maildir_parse_dir(m, &mda, "cur", NULL);
1233 
1234  /* we create a hash table keyed off the canonical (sans flags) filename
1235  * of each message we scanned. This is used in the loop over the
1236  * existing messages below to do some correlation. */
1237  fnames = mutt_hash_new(ARRAY_SIZE(&mda), MUTT_HASH_NO_FLAGS);
1238 
1239  struct MdEmail *md = NULL;
1240  struct MdEmail **mdp = NULL;
1241  ARRAY_FOREACH(mdp, &mda)
1242  {
1243  md = *mdp;
1244  maildir_canon_filename(buf, md->email->path);
1245  md->canon_fname = mutt_buffer_strdup(buf);
1246  mutt_hash_insert(fnames, md->canon_fname, md);
1247  }
1248 
1249  /* check for modifications and adjust flags */
1250  for (int i = 0; i < m->msg_count; i++)
1251  {
1252  struct Email *e = m->emails[i];
1253  if (!e)
1254  break;
1255 
1256  e->active = false;
1257  maildir_canon_filename(buf, e->path);
1258  md = mutt_hash_find(fnames, mutt_buffer_string(buf));
1259  if (md && md->email)
1260  {
1261  /* message already exists, merge flags */
1262  e->active = true;
1263 
1264  /* check to see if the message has moved to a different
1265  * subdirectory. If so, update the associated filename. */
1266  if (!mutt_str_equal(e->path, md->email->path))
1267  mutt_str_replace(&e->path, md->email->path);
1268 
1269  /* if the user hasn't modified the flags on this message, update
1270  * the flags we just detected. */
1271  if (!e->changed)
1272  if (maildir_update_flags(m, e, md->email))
1273  flags_changed = true;
1274 
1275  if (e->deleted == e->trash)
1276  {
1277  if (e->deleted != md->email->deleted)
1278  {
1279  e->deleted = md->email->deleted;
1280  flags_changed = true;
1281  }
1282  }
1283  e->trash = md->email->trash;
1284 
1285  /* this is a duplicate of an existing email, so remove it */
1286  email_free(&md->email);
1287  }
1288  /* This message was not in the list of messages we just scanned.
1289  * Check to see if we have enough information to know if the
1290  * message has disappeared out from underneath us. */
1291  else if (((changed & MMC_NEW_DIR) && mutt_strn_equal(e->path, "new/", 4)) ||
1292  ((changed & MMC_CUR_DIR) && mutt_strn_equal(e->path, "cur/", 4)))
1293  {
1294  /* This message disappeared, so we need to simulate a "reopen"
1295  * event. We know it disappeared because we just scanned the
1296  * subdirectory it used to reside in. */
1297  occult = true;
1298  e->deleted = true;
1299  e->purge = true;
1300  }
1301  else
1302  {
1303  /* This message resides in a subdirectory which was not
1304  * modified, so we assume that it is still present and
1305  * unchanged. */
1306  e->active = true;
1307  }
1308  }
1309 
1310  /* destroy the file name hash */
1311  mutt_hash_free(&fnames);
1312 
1313  /* If we didn't just get new mail, update the tables. */
1314  if (occult)
1316 
1317  /* do any delayed parsing we need to do. */
1318  maildir_delayed_parsing(m, &mda, NULL);
1319 
1320  /* Incorporate new messages */
1321  num_new = maildir_move_to_mailbox(m, &mda);
1322  if (num_new > 0)
1323  {
1325  m->changed = true;
1326  }
1327 
1329 
1330  ARRAY_FREE(&mda);
1331  if (occult)
1332  return MX_STATUS_REOPENED;
1333  if (num_new > 0)
1334  return MX_STATUS_NEW_MAIL;
1335  if (flags_changed)
1336  return MX_STATUS_FLAGS;
1337  return MX_STATUS_OK;
1338 }
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
void maildir_canon_filename(struct Buffer *dest, const char *src)
Generate the canonical filename for a Maildir folder.
Definition: maildir.c:727
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
A Hash Table.
Definition: hash.h:87
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:122
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
void mutt_file_get_stat_timespec(struct timespec *dest, struct stat *sb, enum MuttStatType type)
Read the stat() time into a time value.
Definition: file.c:1540
int maildir_move_to_mailbox(struct Mailbox *m, struct MdEmailArray *mda)
Copy the Maildir list to the Mailbox.
Definition: shared.c:75
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
String manipulation buffer.
Definition: buffer.h:33
Nondestructive flags change (IMAP)
Definition: mxapi.h:82
New mail received in Mailbox.
Definition: mxapi.h:79
bool changed
Email has been edited.
Definition: email.h:48
char * canon_fname
Definition: mdemail.h:36
Email list was changed.
Definition: mailbox.h:180
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MMC_NEW_DIR
&#39;new&#39; directory changed
Definition: maildir.c:73
Container for Accounts, Notifications.
Definition: neomutt.h:36
Mailbox was reopened.
Definition: mxapi.h:81
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
A Maildir Email helper.
Definition: mdemail.h:33
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:54
File/dir&#39;s mtime - last modified time.
Definition: file.h:63
void * mdata
Driver specific data.
Definition: mailbox.h:136
bool trash
Message is marked as trashed on disk (used by the maildir_trash option)
Definition: email.h:60
Email list needs resorting.
Definition: mailbox.h:181
struct Email * email
Definition: mdemail.h:35
bool active
Message is not to be removed.
Definition: email.h:59
No changes.
Definition: mxapi.h:78
void maildir_delayed_parsing(struct Mailbox *m, struct MdEmailArray *mda, struct Progress *progress)
This function does the second parsing pass.
Definition: maildir.c:597
bool purge
Skip trash folder when deleting.
Definition: email.h:46
int mutt_file_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct timespec *b)
Compare stat info with a time value.
Definition: file.c:1580
#define MMC_NO_DIRS
No directories changed.
Definition: maildir.c:72
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
bool deleted
Email is deleted.
Definition: email.h:45
struct timespec mtime_cur
Definition: mdata.h:36
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:52
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int maildir_parse_dir(struct Mailbox *m, struct MdEmailArray *mda, const char *subdir, struct Progress *progress)
Read a Maildir mailbox.
Definition: maildir.c:513
#define MMC_CUR_DIR
&#39;cur&#39; directory changed
Definition: maildir.c:74
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:100
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
Maildir-specific Mailbox data -.
Definition: mdata.h:34
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
An error occurred.
Definition: mxapi.h:77
struct MaildirMboxData * maildir_mdata_get(struct Mailbox *m)
Get the private data for this Mailbox.
Definition: mdata.c:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mh_mbox_check()

enum MxStatus mh_mbox_check ( struct Mailbox m)

Check for new mail - Implements MxOps::mbox_check() -This function handles arrival of new mail and reopening of mh/maildir folders.

Things are getting rather complex because we don't have a well-defined "mailbox order", so the tricks from mbox.c and mx.c won't work here.

Don't change this code unless you really understand what happens.

Definition at line 885 of file mh.c.

886 {
887  char buf[PATH_MAX];
888  struct stat st, st_cur;
889  bool modified = false, occult = false, flags_changed = false;
890  int num_new = 0;
891  struct MhSequences mhs = { 0 };
892  struct HashTable *fnames = NULL;
894 
895  const bool c_check_new = cs_subset_bool(NeoMutt->sub, "check_new");
896  if (!c_check_new)
897  return MX_STATUS_OK;
898 
899  mutt_str_copy(buf, mailbox_path(m), sizeof(buf));
900  if (stat(buf, &st) == -1)
901  return MX_STATUS_ERROR;
902 
903  /* create .mh_sequences when there isn't one. */
904  snprintf(buf, sizeof(buf), "%s/.mh_sequences", mailbox_path(m));
905  int rc = stat(buf, &st_cur);
906  if ((rc == -1) && (errno == ENOENT))
907  {
908  char *tmp = NULL;
909  FILE *fp = NULL;
910 
911  if (mh_mkstemp(m, &fp, &tmp))
912  {
913  mutt_file_fclose(&fp);
914  if (mutt_file_safe_rename(tmp, buf) == -1)
915  unlink(tmp);
916  FREE(&tmp);
917  }
918  }
919 
920  if ((rc == -1) && (stat(buf, &st_cur) == -1))
921  modified = true;
922 
925  {
926  modified = true;
927  }
928 
929  if (!modified)
930  return MX_STATUS_OK;
931 
932  /* Update the modification times on the mailbox.
933  *
934  * The monitor code notices changes in the open mailbox too quickly.
935  * In practice, this sometimes leads to all the new messages not being
936  * noticed during the SAME group of mtime stat updates. To work around
937  * the problem, don't update the stat times for a monitor caused check. */
938 #ifdef USE_INOTIFY
940  MonitorContextChanged = false;
941  else
942 #endif
943  {
946  }
947 
948  struct MdEmailArray mda = ARRAY_HEAD_INITIALIZER;
949 
950  mh_parse_dir(m, &mda, NULL);
951  mh_delayed_parsing(m, &mda, NULL);
952 
953  if (mh_seq_read(&mhs, mailbox_path(m)) < 0)
954  return MX_STATUS_ERROR;
955  mh_update_maildir(&mda, &mhs);
956  mh_seq_free(&mhs);
957 
958  /* check for modifications and adjust flags */
960 
961  struct MdEmail *md = NULL;
962  struct MdEmail **mdp = NULL;
963  ARRAY_FOREACH(mdp, &mda)
964  {
965  md = *mdp;
966  /* the hash key must survive past the header, which is freed below. */
967  md->canon_fname = mutt_str_dup(md->email->path);
968  mutt_hash_insert(fnames, md->canon_fname, md);
969  }
970 
971  for (int i = 0; i < m->msg_count; i++)
972  {
973  struct Email *e = m->emails[i];
974  if (!e)
975  break;
976 
977  e->active = false;
978 
979  md = mutt_hash_find(fnames, e->path);
980  if (md && md->email && email_cmp_strict(e, md->email))
981  {
982  e->active = true;
983  /* found the right message */
984  if (!e->changed)
985  if (maildir_update_flags(m, e, md->email))
986  flags_changed = true;
987 
988  email_free(&md->email);
989  }
990  else /* message has disappeared */
991  occult = true;
992  }
993 
994  /* destroy the file name hash */
995 
996  mutt_hash_free(&fnames);
997 
998  /* If we didn't just get new mail, update the tables. */
999  if (occult)
1001 
1002  /* Incorporate new messages */
1003  num_new = maildir_move_to_mailbox(m, &mda);
1004  if (num_new > 0)
1005  {
1007  m->changed = true;
1008  }
1009 
1010  ARRAY_FREE(&mda);
1011  if (occult)
1012  return MX_STATUS_REOPENED;
1013  if (num_new > 0)
1014  return MX_STATUS_NEW_MAIL;
1015  if (flags_changed)
1016  return MX_STATUS_FLAGS;
1017  return MX_STATUS_OK;
1018 }
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
A Hash Table.
Definition: hash.h:87
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:122
void mh_seq_free(struct MhSequences *mhs)
Free some sequences.
Definition: sequence.c:67
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
void mutt_file_get_stat_timespec(struct timespec *dest, struct stat *sb, enum MuttStatType type)
Read the stat() time into a time value.
Definition: file.c:1540
int maildir_move_to_mailbox(struct Mailbox *m, struct MdEmailArray *mda)
Copy the Maildir list to the Mailbox.
Definition: shared.c:75
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
Nondestructive flags change (IMAP)
Definition: mxapi.h:82
New mail received in Mailbox.
Definition: mxapi.h:79
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
bool changed
Email has been edited.
Definition: email.h:48
char * canon_fname
Definition: mdemail.h:36
Email list was changed.
Definition: mailbox.h:180
int mh_seq_read(struct MhSequences *mhs, const char *path)
Read a set of MH sequences.
Definition: sequence.c:381
Set of MH sequence numbers.
Definition: sequence.h:40
Container for Accounts, Notifications.
Definition: neomutt.h:36
Mailbox was reopened.
Definition: mxapi.h:81
A Maildir Email helper.
Definition: mdemail.h:33
void mh_delayed_parsing(struct Mailbox *m, struct MdEmailArray *mda, struct Progress *progress)
This function does the second parsing pass.
Definition: mh.c:607
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:54
File/dir&#39;s mtime - last modified time.
Definition: file.h:63
void * mdata
Driver specific data.
Definition: mailbox.h:136
Email list needs resorting.
Definition: mailbox.h:181
struct Email * email
Definition: mdemail.h:35
bool active
Message is not to be removed.
Definition: email.h:59
#define PATH_MAX
Definition: mutt.h:40
void mh_update_maildir(struct MdEmailArray *mda, struct MhSequences *mhs)
Update our record of flags.
Definition: mh.c:260
No changes.
Definition: mxapi.h:78
int mutt_file_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct timespec *b)
Compare stat info with a time value.
Definition: file.c:1580
bool mh_mkstemp(struct Mailbox *m, FILE **fp, char **tgt)
Create a temporary file.
Definition: mh.c:77
bool email_cmp_strict(const struct Email *e1, const struct Email *e2)
Strictly compare message emails.
Definition: email.c:100
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct timespec mtime_cur
Definition: mdata.h:36
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:52
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
#define FREE(x)
Definition: memory.h:40
int mh_parse_dir(struct Mailbox *m, struct MdEmailArray *mda, struct Progress *progress)
Read a Maildir mailbox.
Definition: mh.c:501
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:251
#define MUTT_HASH_NO_FLAGS
No flags are set.
Definition: hash.h:100
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
Maildir-specific Mailbox data -.
Definition: mdata.h:34
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
An error occurred.
Definition: mxapi.h:77
int mutt_file_safe_rename(const char *src, const char *target)
NFS-safe renaming of files.
Definition: file.c:354
struct MaildirMboxData * maildir_mdata_get(struct Mailbox *m)
Get the private data for this Mailbox.
Definition: mdata.c:58
+ Here is the call graph for this function:
+ Here is the caller 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 1023 of file mbox.c.

1024 {
1025  struct MboxAccountData *adata = mbox_adata_get(m);
1026  if (!adata)
1027  return MX_STATUS_ERROR;
1028 
1029  if (!adata->fp)
1030  {
1031  if (mbox_mbox_open(m) != MX_OPEN_OK)
1032  return MX_STATUS_ERROR;
1034  }
1035 
1036  struct stat st;
1037  bool unlock = false;
1038  bool modified = false;
1039 
1040  if (stat(mailbox_path(m), &st) == 0)
1041  {
1042  if ((mutt_file_stat_timespec_compare(&st, MUTT_STAT_MTIME, &m->mtime) == 0) &&
1043  (st.st_size == m->size))
1044  {
1045  return MX_STATUS_OK;
1046  }
1047 
1048  if (st.st_size == m->size)
1049  {
1050  /* the file was touched, but it is still the same length, so just exit */
1052  return MX_STATUS_OK;
1053  }
1054 
1055  if (st.st_size > m->size)
1056  {
1057  /* lock the file if it isn't already */
1058  if (!adata->locked)
1059  {
1060  mutt_sig_block();
1061  if (mbox_lock_mailbox(m, false, false) == -1)
1062  {
1063  mutt_sig_unblock();
1064  /* we couldn't lock the mailbox, but nothing serious happened:
1065  * probably the new mail arrived: no reason to wait till we can
1066  * parse it: we'll get it on the next pass */
1067  return MX_STATUS_LOCKED;
1068  }
1069  unlock = 1;
1070  }
1071 
1072  /* Check to make sure that the only change to the mailbox is that
1073  * message(s) were appended to this file. My heuristic is that we should
1074  * see the message separator at *exactly* what used to be the end of the
1075  * folder. */
1076  char buf[1024];
1077  if (fseeko(adata->fp, m->size, SEEK_SET) != 0)
1078  mutt_debug(LL_DEBUG1, "#1 fseek() failed\n");
1079  if (fgets(buf, sizeof(buf), adata->fp))
1080  {
1081  if (((m->type == MUTT_MBOX) && mutt_str_startswith(buf, "From ")) ||
1082  ((m->type == MUTT_MMDF) && mutt_str_equal(buf, MMDF_SEP)))
1083  {
1084  if (fseeko(adata->fp, m->size, SEEK_SET) != 0)
1085  mutt_debug(LL_DEBUG1, "#2 fseek() failed\n");
1086 
1087  int old_msg_count = m->msg_count;
1088  if (m->type == MUTT_MBOX)
1089  mbox_parse_mailbox(m);
1090  else
1091  mmdf_parse_mailbox(m);
1092 
1093  if (m->msg_count > old_msg_count)
1095 
1096  /* Only unlock the folder if it was locked inside of this routine.
1097  * It may have been locked elsewhere, like in
1098  * mutt_checkpoint_mailbox(). */
1099  if (unlock)
1100  {
1102  mutt_sig_unblock();
1103  }
1104 
1105  return MX_STATUS_NEW_MAIL; /* signal that new mail arrived */
1106  }
1107  else
1108  modified = true;
1109  }
1110  else
1111  {
1112  mutt_debug(LL_DEBUG1, "fgets returned NULL\n");
1113  modified = true;
1114  }
1115  }
1116  else
1117  modified = true;
1118  }
1119 
1120  if (modified)
1121  {
1122  if (reopen_mailbox(m) != -1)
1123  {
1125  if (unlock)
1126  {
1128  mutt_sig_unblock();
1129  }
1130  return MX_STATUS_REOPENED;
1131  }
1132  }
1133 
1134  /* fatal error */
1135 
1138  mutt_sig_unblock();
1139  mutt_error(_("Mailbox was corrupted"));
1140  return MX_STATUS_ERROR;
1141 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
void mutt_sig_unblock(void)
Restore previously blocked signals.
Definition: signal.c:168
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
#define mutt_error(...)
Definition: logging.h:88
bool locked
is the mailbox locked?
Definition: lib.h:53
void mutt_file_get_stat_timespec(struct timespec *dest, struct stat *sb, enum MuttStatType type)
Read the stat() time into a time value.
Definition: file.c:1540
Mbox-specific Account data -.
Definition: lib.h:48
static enum MxOpenReturns mbox_parse_mailbox(struct Mailbox *m)
Read a mailbox from disk.
Definition: mbox.c:349
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
New mail received in Mailbox.
Definition: mxapi.h:79
#define _(a)
Definition: message.h:28
Email list was changed.
Definition: mailbox.h:180
static int reopen_mailbox(struct Mailbox *m)
Close and reopen a mailbox.
Definition: mbox.c:542
static enum MxOpenReturns mmdf_parse_mailbox(struct Mailbox *m)
Read a mailbox in MMDF format.
Definition: mbox.c:182
Open succeeded.
Definition: mxapi.h:90
Mailbox was reopened.
Definition: mxapi.h:81
static int mbox_lock_mailbox(struct Mailbox *m, bool excl, bool retry)
Lock a mailbox.
Definition: mbox.c:140
static enum MxOpenReturns mbox_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open() -.
Definition: mbox.c:925
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:429
File/dir&#39;s mtime - last modified time.
Definition: file.h:63
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
No changes.
Definition: mxapi.h:78
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
Couldn&#39;t lock the Mailbox.
Definition: mxapi.h:80
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
int mutt_file_stat_timespec_compare(struct stat *sba, enum MuttStatType type, struct timespec *b)
Compare stat info with a time value.
Definition: file.c:1580
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MMDF_SEP
Definition: lib.h:60
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
Log at debug level 1.
Definition: logging.h:40
static void mbox_unlock_mailbox(struct Mailbox *m)
Unlock a mailbox.
Definition: mbox.c:162
FILE * fp
Mailbox file.
Definition: lib.h:50
void mutt_sig_block(void)
Block signals during critical operations.
Definition: signal.c:150
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
An error occurred.
Definition: mxapi.h:77
+ 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 2472 of file nntp.c.

2473 {
2474  enum MxStatus rc = check_mailbox(m);
2475  if (rc == MX_STATUS_OK)
2476  {
2477  struct NntpMboxData *mdata = m->mdata;
2478  struct NntpAccountData *adata = mdata->adata;
2479  nntp_newsrc_close(adata);
2480  }
2481  return rc;
2482 }
struct NntpAccountData * adata
Definition: mdata.h:47
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:118
NNTP-specific Account data -.
Definition: adata.h:36
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
No changes.
Definition: mxapi.h:78
static enum MxStatus check_mailbox(struct Mailbox *m)
Check current newsgroup for new articles.
Definition: nntp.c:1433
NNTP-specific Mailbox data -.
Definition: mdata.h:32
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
+ 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 2094 of file notmuch.c.

2095 {
2096  struct NmMboxData *mdata = nm_mdata_get(m);
2097  time_t mtime = 0;
2098  if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2099  return MX_STATUS_ERROR;
2100 
2101  int new_flags = 0;
2102  bool occult = false;
2103 
2104  if (m->mtime.tv_sec >= mtime)
2105  {
2106  mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%lu mailbox=%lu)\n", mtime,
2107  m->mtime.tv_sec);
2108  return MX_STATUS_OK;
2109  }
2110 
2111  mutt_debug(LL_DEBUG1, "nm: checking (db=%lu mailbox=%lu)\n", mtime, m->mtime.tv_sec);
2112 
2113  notmuch_query_t *q = get_query(m, false);
2114  if (!q)
2115  goto done;
2116 
2117  mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2118  mdata->oldmsgcount = m->msg_count;
2119 
2120  for (int i = 0; i < m->msg_count; i++)
2121  {
2122  struct Email *e = m->emails[i];
2123  if (!e)
2124  break;
2125 
2126  e->active = false;
2127  }
2128 
2129  int limit = get_limit(mdata);
2130 
2131  notmuch_messages_t *msgs = get_messages(q);
2132 
2133  // TODO: Analyze impact of removing this version guard.
2134 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2135  if (!msgs)
2136  return MX_STATUS_OK;
2137 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2138  if (!msgs)
2139  goto done;
2140 #endif
2141 
2142  struct HeaderCache *h = nm_hcache_open(m);
2143 
2144  for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2145  notmuch_messages_move_to_next(msgs), i++)
2146  {
2147  notmuch_message_t *msg = notmuch_messages_get(msgs);
2148  struct Email *e = get_mutt_email(m, msg);
2149 
2150  if (!e)
2151  {
2152  /* new email */
2153  append_message(h, m, NULL, msg, false);
2154  notmuch_message_destroy(msg);
2155  continue;
2156  }
2157 
2158  /* message already exists, merge flags */
2159  e->active = true;
2160 
2161  /* Check to see if the message has moved to a different subdirectory.
2162  * If so, update the associated filename. */
2163  const char *new_file = get_message_last_filename(msg);
2164  char old_file[PATH_MAX];
2165  email_get_fullpath(e, old_file, sizeof(old_file));
2166 
2167  if (!mutt_str_equal(old_file, new_file))
2168  update_message_path(e, new_file);
2169 
2170  if (!e->changed)
2171  {
2172  /* if the user hasn't modified the flags on this message, update the
2173  * flags we just detected. */
2174  struct Email e_tmp = { 0 };
2175  e_tmp.edata = maildir_edata_new();
2176  maildir_parse_flags(&e_tmp, new_file);
2177  maildir_update_flags(m, e, &e_tmp);
2178  maildir_edata_free(&e_tmp.edata);
2179  }
2180 
2181  if (update_email_tags(e, msg) == 0)
2182  new_flags++;
2183 
2184  notmuch_message_destroy(msg);
2185  }
2186 
2187  nm_hcache_close(h);
2188 
2189  for (int i = 0; i < m->msg_count; i++)
2190  {
2191  struct Email *e = m->emails[i];
2192  if (!e)
2193  break;
2194 
2195  if (!e->active)
2196  {
2197  occult = true;
2198  break;
2199  }
2200  }
2201 
2202  if (m->msg_count > mdata->oldmsgcount)
2204 done:
2205  if (q)
2206  notmuch_query_destroy(q);
2207 
2208  nm_db_release(m);
2209 
2210  m->mtime.tv_sec = mutt_date_epoch();
2211  m->mtime.tv_nsec = 0;
2212 
2213  mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2214  m->msg_count, new_flags, occult);
2215 
2216  if (occult)
2217  return MX_STATUS_REOPENED;
2218  if (m->msg_count > mdata->oldmsgcount)
2219  return MX_STATUS_NEW_MAIL;
2220  if (new_flags)
2221  return MX_STATUS_FLAGS;
2222  return MX_STATUS_OK;
2223 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: notmuch.c:440
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
int nm_db_get_mtime(struct Mailbox *m, time_t *mtime)
Get the database modification time.
Definition: db.c:278
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:122
header cache structure
Definition: lib.h:84
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
Nondestructive flags change (IMAP)
Definition: mxapi.h:82
New mail received in Mailbox.
Definition: mxapi.h:79
bool changed
Email has been edited.
Definition: email.h:48
Email list was changed.
Definition: mailbox.h:180
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: notmuch.c:522
Mailbox was reopened.
Definition: mxapi.h:81
time_t tv_sec
Definition: file.h:50
int oldmsgcount
Definition: mdata.h:41
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message&#39;s last filename.
Definition: notmuch.c:651
void maildir_parse_flags(struct Email *e, const char *path)
Parse Maildir file flags.
Definition: maildir.c:811
Log at debug level 2.
Definition: logging.h:41
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: notmuch.c:404
Notmuch-specific Mailbox data -.
Definition: mdata.h:33
static notmuch_messages_t * get_messages(notmuch_query_t *query)
load messages for a query
Definition: notmuch.c:903
long tv_nsec
Definition: file.h:51
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mdata.c:98
bool active
Message is not to be removed.
Definition: email.h:59
#define PATH_MAX
Definition: mutt.h:40
static struct HeaderCache * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: notmuch.c:109
No changes.
Definition: mxapi.h:78
struct MaildirEmailData * maildir_edata_new(void)
Create a new MaildirEmailData object.
Definition: edata.c:53
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
static void nm_hcache_close(struct HeaderCache *h)
Close the header cache.
Definition: notmuch.c:124
Log at debug level 1.
Definition: logging.h:40
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: db.c:196
void * edata
Driver-specific data.
Definition: email.h:111
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: notmuch.c:226
static void append_message(struct HeaderCache *h, struct Mailbox *m, notmuch_query_t *q, 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&#39;s tags from Notmuch.
Definition: notmuch.c:472
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: notmuch.c:704
void maildir_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free()
Definition: edata.c:38
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
An error occurred.
Definition: mxapi.h:77
+ 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 825 of file pop.c.

826 {
827  struct PopAccountData *adata = pop_adata_get(m);
828 
829  const short c_pop_check_interval =
830  cs_subset_number(NeoMutt->sub, "pop_check_interval");
831  if ((adata->check_time + c_pop_check_interval) > mutt_date_epoch())
832  return MX_STATUS_OK;
833 
834  pop_logout(m);
835 
836  mutt_socket_close(adata->conn);
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);
847  pop_clear_cache(adata);
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 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
size_t size
Definition: adata.h:50
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition: lib.c:310
New mail received in Mailbox.
Definition: mxapi.h:79
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
Email list was changed.
Definition: mailbox.h:180
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:64
Container for Accounts, Notifications.
Definition: neomutt.h:36
static int pop_fetch_headers(struct Mailbox *m)
Read headers.
Definition: pop.c:322
static void pop_clear_cache(struct PopAccountData *adata)
delete all cached messages
Definition: pop.c:495
time_t check_time
Definition: adata.h:51
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
No changes.
Definition: mxapi.h:78
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:97
#define mutt_message(...)
Definition: logging.h:87
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
POP-specific Account data -.
Definition: adata.h:36
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
void pop_logout(struct Mailbox *m)
logout from a POP server
Definition: lib.c:420
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function: