NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
mbox_check_stats()

Check the Mailbox statistics. More...

+ Collaboration diagram for mbox_check_stats():

Functions

static enum MxStatus imap_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 
static enum MxStatus maildir_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 
static enum MxStatus mh_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 
static enum MxStatus mbox_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 
static enum MxStatus nm_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 

Detailed Description

Check the Mailbox statistics.

Parameters
mMailbox to check
flagsFunction flags
Return values
enumMxStatus

Contract

Function Documentation

◆ imap_mbox_check_stats()

static enum MxStatus imap_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.

Definition at line 1221 of file imap.c.

1222{
1223 const bool queue = (flags & MUTT_MAILBOX_CHECK_IMMEDIATE) == 0;
1224 const int new_msgs = imap_mailbox_status(m, queue);
1225 if (new_msgs == -1)
1226 return MX_STATUS_ERROR;
1227 if (new_msgs == 0)
1228 return MX_STATUS_OK;
1229 return MX_STATUS_NEW_MAIL;
1230}
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1273
#define MUTT_MAILBOX_CHECK_IMMEDIATE
Don't postpone the actual checking.
Definition: mxapi.h:77
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:85
@ MX_STATUS_OK
No changes.
Definition: mxapi.h:86
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:87
+ Here is the call graph for this function:

◆ maildir_mbox_check_stats()

static enum MxStatus maildir_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.

Definition at line 1344 of file maildir.c.

1345{
1346 bool check_stats = flags & MUTT_MAILBOX_CHECK_FORCE_STATS;
1347 bool check_new = true;
1348
1349 if (check_stats)
1350 {
1351 m->msg_count = 0;
1352 m->msg_unread = 0;
1353 m->msg_flagged = 0;
1354 m->msg_new = 0;
1355 }
1356
1357 maildir_check_dir(m, "new", check_new, check_stats);
1358
1359 const bool c_maildir_check_cur = cs_subset_bool(NeoMutt->sub, "maildir_check_cur");
1360 check_new = !m->has_new && c_maildir_check_cur;
1361 if (check_new || check_stats)
1362 maildir_check_dir(m, "cur", check_new, check_stats);
1363
1365}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
static void maildir_check_dir(struct Mailbox *m, const char *dir_name, bool check_new, bool check_stats)
Check for new mail / mail counts.
Definition: maildir.c:86
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Ignore MailboxType and calculate statistics.
Definition: mxapi.h:76
bool has_new
Mailbox has new mail.
Definition: mailbox.h:85
int msg_new
Number of new messages.
Definition: mailbox.h:92
int msg_count
Total number of messages.
Definition: mailbox.h:88
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:90
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:

◆ mh_mbox_check_stats()

static enum MxStatus mh_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.

Definition at line 190 of file mh.c.

191{
192 struct MhSequences mhs = { 0 };
193 DIR *dirp = NULL;
194 struct dirent *de = NULL;
195
196 /* when $mail_check_recent is set and the .mh_sequences file hasn't changed
197 * since the last m visit, there is no "new mail" */
198 const bool c_mail_check_recent = cs_subset_bool(NeoMutt->sub, "mail_check_recent");
199 if (c_mail_check_recent && (mh_seq_changed(m) <= 0))
200 {
201 return MX_STATUS_OK;
202 }
203
204 if (mh_seq_read(&mhs, mailbox_path(m)) < 0)
205 return MX_STATUS_ERROR;
206
207 m->msg_count = 0;
208 m->msg_unread = 0;
209 m->msg_flagged = 0;
210
211 enum MxStatus rc = MX_STATUS_OK;
212 bool check_new = true;
213 for (int i = mhs.max; i > 0; i--)
214 {
215 if ((mh_seq_check(&mhs, i) & MH_SEQ_FLAGGED))
216 m->msg_flagged++;
217 if (mh_seq_check(&mhs, i) & MH_SEQ_UNSEEN)
218 {
219 m->msg_unread++;
220 if (check_new)
221 {
222 /* if the first unseen message we encounter was in the m during the
223 * last visit, don't notify about it */
224 if (!c_mail_check_recent || (mh_already_notified(m, i) == 0))
225 {
226 m->has_new = true;
228 }
229 /* Because we are traversing from high to low, we can stop
230 * checking for new mail after the first unseen message.
231 * Whether it resulted in "new mail" or not. */
232 check_new = false;
233 }
234 }
235 }
236
237 mh_seq_free(&mhs);
238
239 dirp = opendir(mailbox_path(m));
240 if (dirp)
241 {
242 while ((de = readdir(dirp)))
243 {
244 if (*de->d_name == '.')
245 continue;
246 if (mh_valid_message(de->d_name))
247 m->msg_count++;
248 }
249 closedir(dirp);
250 }
251
252 return rc;
253}
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:210
bool mh_valid_message(const char *s)
Is this a valid MH message filename.
Definition: mh.c:149
static int mh_already_notified(struct Mailbox *m, int msgno)
Has the message changed.
Definition: mh.c:126
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:84
MhSeqFlags mh_seq_check(struct MhSequences *mhs, int i)
Get the flags for a given sequence.
Definition: sequence.c:78
void mh_seq_free(struct MhSequences *mhs)
Free some sequences.
Definition: sequence.c:67
int mh_seq_changed(struct Mailbox *m)
Has the mailbox changed.
Definition: sequence.c:436
int mh_seq_read(struct MhSequences *mhs, const char *path)
Read a set of MH sequences.
Definition: sequence.c:375
#define MH_SEQ_UNSEEN
Email hasn't been read.
Definition: sequence.h:33
#define MH_SEQ_FLAGGED
Email is flagged.
Definition: sequence.h:35
Set of MH sequence numbers.
Definition: sequence.h:41
int max
Number of flags stored.
Definition: sequence.h:42
+ Here is the call graph for this function:

◆ mbox_mbox_check_stats()

static enum MxStatus mbox_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.

Definition at line 1782 of file mbox.c.

1783{
1784 struct stat st = { 0 };
1785 if (stat(mailbox_path(m), &st) != 0)
1786 return MX_STATUS_ERROR;
1787
1788 bool new_or_changed;
1789
1790 const bool c_check_mbox_size = cs_subset_bool(NeoMutt->sub, "check_mbox_size");
1791 if (c_check_mbox_size)
1792 new_or_changed = (st.st_size > m->size);
1793 else
1794 {
1795 new_or_changed =
1797 (m->newly_created &&
1800 }
1801
1802 if (new_or_changed)
1803 {
1804 const bool c_mail_check_recent = cs_subset_bool(NeoMutt->sub, "mail_check_recent");
1805 if (!c_mail_check_recent ||
1807 {
1808 m->has_new = true;
1809 }
1810 }
1811 else if (c_check_mbox_size)
1812 {
1813 /* some other program has deleted mail from the folder */
1814 m->size = (off_t) st.st_size;
1815 }
1816
1817 if (m->newly_created && ((st.st_ctime != st.st_mtime) || (st.st_ctime != st.st_atime)))
1818 m->newly_created = false;
1819
1821 {
1824 &adata->stats_last_checked) > 0)
1825 {
1826 bool old_peek = m->peekonly;
1828 mx_mbox_close(m);
1829 m->peekonly = old_peek;
1830 adata->stats_last_checked.tv_sec = mutt_date_epoch();
1831 }
1832 }
1833
1834 if (m->has_new || m->msg_new)
1835 return MX_STATUS_NEW_MAIL;
1836 return MX_STATUS_OK;
1837}
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:428
int mutt_file_stat_compare(struct stat *st1, enum MuttStatType st1_type, struct stat *st2, enum MuttStatType st2_type)
Compare two stat infos.
Definition: file.c:1673
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:1651
@ MUTT_STAT_CTIME
File/dir's ctime - creation time.
Definition: file.h:64
@ MUTT_STAT_ATIME
File/dir's atime - last accessed time.
Definition: file.h:62
@ MUTT_STAT_MTIME
File/dir's mtime - last modified time.
Definition: file.h:63
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:119
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:615
#define MUTT_QUIET
Do not print any messages.
Definition: mxapi.h:65
#define MUTT_PEEK
Revert atime back after taking a look (if applicable)
Definition: mxapi.h:69
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mxapi.h:62
#define MUTT_MAILBOX_CHECK_FORCE
Ignore MailboxTime and check for new mail.
Definition: mxapi.h:75
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
bool newly_created
Mbox or mmdf just popped into existence.
Definition: mailbox.h:103
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:113
off_t size
Size of the Mailbox.
Definition: mailbox.h:84
struct timespec last_visited
Time of last exit from this mailbox.
Definition: mailbox.h:105
Mbox-specific Account data -.
Definition: lib.h:49
+ Here is the call graph for this function:

◆ nm_mbox_check_stats()

static enum MxStatus nm_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -.

Definition at line 1762 of file notmuch.c.

1763{
1764 struct UrlQuery *item = NULL;
1765 struct Url *url = NULL;
1766 const char *db_filename = NULL;
1767 char *db_query = NULL;
1768 notmuch_database_t *db = NULL;
1769 enum MxStatus rc = MX_STATUS_ERROR;
1770 const short c_nm_db_limit = cs_subset_number(NeoMutt->sub, "nm_db_limit");
1771 int limit = c_nm_db_limit;
1772 mutt_debug(LL_DEBUG1, "nm: count\n");
1773
1774 url = url_parse(mailbox_path(m));
1775 if (!url)
1776 {
1777 mutt_error(_("failed to parse notmuch url: %s"), mailbox_path(m));
1778 goto done;
1779 }
1780
1781 STAILQ_FOREACH(item, &url->query_strings, entries)
1782 {
1783 if (item->value && (strcmp(item->name, "query") == 0))
1784 db_query = item->value;
1785 else if (item->value && (strcmp(item->name, "limit") == 0))
1786 {
1787 // Try to parse the limit
1788 if (!mutt_str_atoi_full(item->value, &limit))
1789 {
1790 mutt_error(_("failed to parse limit: %s"), item->value);
1791 goto done;
1792 }
1793 }
1794 }
1795
1796 if (!db_query)
1797 goto done;
1798
1799 db_filename = url->path;
1800 if (!db_filename)
1801 db_filename = nm_db_get_filename(m);
1802
1803 /* don't be verbose about connection, as we're called from
1804 * sidebar/mailbox very often */
1805 db = nm_db_do_open(db_filename, false, false);
1806 if (!db)
1807 goto done;
1808
1809 /* all emails */
1810 m->msg_count = count_query(db, db_query, limit);
1811 while (m->email_max < m->msg_count)
1812 mx_alloc_memory(m);
1813
1814 // holder variable for extending query to unread/flagged
1815 char *qstr = NULL;
1816
1817 // unread messages
1818 const char *const c_nm_unread_tag = cs_subset_string(NeoMutt->sub, "nm_unread_tag");
1819 mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, c_nm_unread_tag);
1820 m->msg_unread = count_query(db, qstr, limit);
1821 FREE(&qstr);
1822
1823 // flagged messages
1824 const char *const c_nm_flagged_tag = cs_subset_string(NeoMutt->sub, "nm_flagged_tag");
1825 mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, c_nm_flagged_tag);
1826 m->msg_flagged = count_query(db, qstr, limit);
1827 FREE(&qstr);
1828
1829 rc = (m->msg_new > 0) ? MX_STATUS_NEW_MAIL : MX_STATUS_OK;
1830done:
1831 if (db)
1832 {
1833 nm_db_free(db);
1834 mutt_debug(LL_DEBUG1, "nm: count close DB\n");
1835 }
1836 url_free(&url);
1837
1838 mutt_debug(LL_DEBUG1, "nm: count done [rc=%d]\n", rc);
1839 return rc;
1840}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
#define mutt_error(...)
Definition: logging.h:87
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:43
#define _(a)
Definition: message.h:28
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1031
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1219
notmuch_database_t * nm_db_do_open(const char *filename, bool writable, bool verbose)
Open a Notmuch database.
Definition: db.c:109
const char * nm_db_get_filename(struct Mailbox *m)
Get the filename of the Notmuch database.
Definition: db.c:54
void nm_db_free(notmuch_database_t *db)
Decoupled way to close a Notmuch database.
Definition: db.c:239
static unsigned int count_query(notmuch_database_t *db, const char *qstr, int limit)
Count the results of a query.
Definition: notmuch.c:1417
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
int email_max
Number of pointers in emails.
Definition: mailbox.h:97
Parsed Query String.
Definition: url.h:58
char * name
Query name.
Definition: url.h:59
char * value
Query value.
Definition: url.h:60
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
struct UrlQueryList query_strings
List of query strings.
Definition: url.h:76
char * path
Path.
Definition: url.h:75
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
+ Here is the call graph for this function: