NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
mbox.c File Reference

Mbox local mailbox type. More...

#include "config.h"
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "mutt.h"
#include "lib.h"
#include "progress/lib.h"
#include "copy.h"
#include "mutt_globals.h"
#include "mutt_header.h"
#include "muttlib.h"
#include "mx.h"
#include "protos.h"
+ Include dependency graph for mbox.c:

Go to the source code of this file.

Data Structures

struct  MUpdate
 Store of new offsets, used by mutt_sync_mailbox() More...
 

Functions

static void mbox_adata_free (void **ptr)
 Free the private Account data - Implements Account::adata_free() More...
 
static struct MboxAccountDatambox_adata_new (void)
 Create a new MboxAccountData struct. More...
 
static struct MboxAccountDatambox_adata_get (struct Mailbox *m)
 Get the private data associated with a Mailbox. More...
 
static int init_mailbox (struct Mailbox *m)
 Add Mbox data to the Mailbox. More...
 
static int mbox_lock_mailbox (struct Mailbox *m, bool excl, bool retry)
 Lock a mailbox. More...
 
static void mbox_unlock_mailbox (struct Mailbox *m)
 Unlock a mailbox. More...
 
static enum MxOpenReturns mmdf_parse_mailbox (struct Mailbox *m)
 Read a mailbox in MMDF format. More...
 
static enum MxOpenReturns mbox_parse_mailbox (struct Mailbox *m)
 Read a mailbox from disk. More...
 
static int reopen_mailbox (struct Mailbox *m)
 Close and reopen a mailbox. More...
 
static bool mbox_has_new (struct Mailbox *m)
 Does the mailbox have new mail. More...
 
static int fseek_last_message (FILE *fp)
 Find the last message in the file. More...
 
static bool test_last_status_new (FILE *fp)
 Is the last message new. More...
 
bool mbox_test_new_folder (const char *path)
 Test if an mbox or mmdf mailbox has new mail. More...
 
void mbox_reset_atime (struct Mailbox *m, struct stat *st)
 Reset the access time on the mailbox file. More...
 
static bool mbox_ac_owns_path (struct Account *a, const char *path)
 Check whether an Account owns a Mailbox path - Implements MxOps::ac_owns_path() -. More...
 
static bool mbox_ac_add (struct Account *a, struct Mailbox *m)
 Add a Mailbox to an Account - Implements MxOps::ac_add() -. More...
 
static FILE * mbox_open_readwrite (struct Mailbox *m)
 Open an mbox read-write. More...
 
static FILE * mbox_open_readonly (struct Mailbox *m)
 Open an mbox read-only. More...
 
static enum MxOpenReturns mbox_mbox_open (struct Mailbox *m)
 Open a Mailbox - Implements MxOps::mbox_open() -. More...
 
static bool mbox_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() -. More...
 
static enum MxStatus mbox_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() -. More...
 
static enum MxStatus mbox_mbox_sync (struct Mailbox *m)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() -. More...
 
static enum MxStatus mbox_mbox_close (struct Mailbox *m)
 Close a Mailbox - Implements MxOps::mbox_close() -. More...
 
static bool mbox_msg_open (struct Mailbox *m, struct Message *msg, int msgno)
 Open an email message in a Mailbox - Implements MxOps::msg_open() -. More...
 
static bool mbox_msg_open_new (struct Mailbox *m, struct Message *msg, const struct Email *e)
 Open a new message in a Mailbox - Implements MxOps::msg_open_new() -. More...
 
static int mbox_msg_commit (struct Mailbox *m, struct Message *msg)
 Save changes to an email - Implements MxOps::msg_commit() -. More...
 
static int mbox_msg_close (struct Mailbox *m, struct Message *msg)
 Close an email - Implements MxOps::msg_close() -. More...
 
static int mbox_msg_padding_size (struct Mailbox *m)
 Bytes of padding between messages - Implements MxOps::msg_padding_size() -. More...
 
enum MailboxType mbox_path_probe (const char *path, const struct stat *st)
 Is this an mbox Mailbox? - Implements MxOps::path_probe() -. More...
 
static int mbox_path_canon (char *buf, size_t buflen)
 Canonicalise a Mailbox path - Implements MxOps::path_canon() -. More...
 
static int mbox_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a Mailbox path - Implements MxOps::path_pretty() -. More...
 
static int mbox_path_parent (char *buf, size_t buflen)
 Find the parent of a Mailbox path - Implements MxOps::path_parent() -. More...
 
static int mbox_path_is_empty (const char *path)
 Is the mailbox empty - Implements MxOps::path_is_empty() -. More...
 
static int mmdf_msg_commit (struct Mailbox *m, struct Message *msg)
 Save changes to an email - Implements MxOps::msg_commit() -. More...
 
static int mmdf_msg_padding_size (struct Mailbox *m)
 Bytes of padding between messages - Implements MxOps::msg_padding_size() -. More...
 
static enum MxStatus mbox_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() -. More...
 

Variables

struct MxOps MxMboxOps
 Mbox Mailbox - Implements MxOps -. More...
 
struct MxOps MxMmdfOps
 MMDF Mailbox - Implements MxOps -. More...
 

Detailed Description

Mbox local mailbox type.

Authors
  • Michael R. Elkins
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file mbox.c.

Function Documentation

◆ mbox_adata_free()

static void mbox_adata_free ( void **  ptr)
static

Free the private Account data - Implements Account::adata_free()

Definition at line 78 of file mbox.c.

79 {
80  struct MboxAccountData *m = *ptr;
81 
82  mutt_file_fclose(&m->fp);
83  FREE(ptr);
84 }
Mbox-specific Account data -.
Definition: lib.h:48
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define FREE(x)
Definition: memory.h:40
FILE * fp
Mailbox file.
Definition: lib.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_adata_new()

static struct MboxAccountData* mbox_adata_new ( void  )
static

Create a new MboxAccountData struct.

Return values
ptrNew MboxAccountData

Definition at line 90 of file mbox.c.

91 {
92  return mutt_mem_calloc(1, sizeof(struct MboxAccountData));
93 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Mbox-specific Account data -.
Definition: lib.h:48
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_adata_get()

static struct MboxAccountData* mbox_adata_get ( struct Mailbox m)
static

Get the private data associated with a Mailbox.

Parameters
mMailbox
Return values
ptrPrivate data

Definition at line 100 of file mbox.c.

101 {
102  if (!m)
103  return NULL;
104  if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
105  return NULL;
106  struct Account *a = m->account;
107  if (!a)
108  return NULL;
109  return a->adata;
110 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
A group of associated Mailboxes.
Definition: account.h:36
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
+ Here is the caller graph for this function:

◆ init_mailbox()

static int init_mailbox ( struct Mailbox m)
static

Add Mbox data to the Mailbox.

Parameters
mMailbox
Return values
0Success
-1Error Bad format

Definition at line 118 of file mbox.c.

119 {
120  if (!m || !m->account)
121  return -1;
122  if ((m->type != MUTT_MBOX) && (m->type != MUTT_MMDF))
123  return -1;
124  if (m->account->adata)
125  return 0;
126 
127  m->account->adata = mbox_adata_new();
129  return 0;
130 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void(* adata_free)(void **ptr)
Free the private data attached to the Account.
Definition: account.h:53
static void mbox_adata_free(void **ptr)
Free the private Account data - Implements Account::adata_free()
Definition: mbox.c:78
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
static struct MboxAccountData * mbox_adata_new(void)
Create a new MboxAccountData struct.
Definition: mbox.c:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_lock_mailbox()

static int mbox_lock_mailbox ( struct Mailbox m,
bool  excl,
bool  retry 
)
static

Lock a mailbox.

Parameters
mMailbox to lock
exclExclusive lock?
retryShould retry if unable to lock?
Return values
0Success
-1Failure

Definition at line 140 of file mbox.c.

141 {
142  struct MboxAccountData *adata = mbox_adata_get(m);
143  if (!adata)
144  return -1;
145 
146  int rc = mutt_file_lock(fileno(adata->fp), excl, retry);
147  if (rc == 0)
148  adata->locked = true;
149  else if (retry && !excl)
150  {
151  m->readonly = true;
152  return 0;
153  }
154 
155  return rc;
156 }
bool locked
is the mailbox locked?
Definition: lib.h:53
Mbox-specific Account data -.
Definition: lib.h:48
int mutt_file_lock(int fd, bool excl, bool timeout)
(try to) lock a file using fcntl()
Definition: file.c:1178
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
FILE * fp
Mailbox file.
Definition: lib.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_unlock_mailbox()

static void mbox_unlock_mailbox ( struct Mailbox m)
static

Unlock a mailbox.

Parameters
mMailbox to unlock

Definition at line 162 of file mbox.c.

163 {
164  struct MboxAccountData *adata = mbox_adata_get(m);
165  if (!adata)
166  return;
167 
168  if (adata->locked)
169  {
170  fflush(adata->fp);
171 
172  mutt_file_unlock(fileno(adata->fp));
173  adata->locked = false;
174  }
175 }
bool locked
is the mailbox locked?
Definition: lib.h:53
Mbox-specific Account data -.
Definition: lib.h:48
int mutt_file_unlock(int fd)
Unlock a file previously locked by mutt_file_lock()
Definition: file.c:1226
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
FILE * fp
Mailbox file.
Definition: lib.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mmdf_parse_mailbox()

static enum MxOpenReturns mmdf_parse_mailbox ( struct Mailbox m)
static

Read a mailbox in MMDF format.

Parameters
mMailbox
Return values
enumMxOpenReturns

Definition at line 182 of file mbox.c.

183 {
184  if (!m)
185  return MX_OPEN_ERROR;
186 
187  struct MboxAccountData *adata = mbox_adata_get(m);
188  if (!adata)
189  return MX_OPEN_ERROR;
190 
191  char buf[8192];
192  char return_path[1024];
193  int count = 0;
194  int lines;
195  time_t t;
196  LOFF_T loc, tmploc;
197  struct Email *e = NULL;
198  struct stat sb;
199  struct Progress *progress = NULL;
200  enum MxOpenReturns rc = MX_OPEN_ERROR;
201 
202  if (stat(mailbox_path(m), &sb) == -1)
203  {
205  goto fail;
206  }
209  m->size = sb.st_size;
210 
211  buf[sizeof(buf) - 1] = '\0';
212 
213  if (m->verbose)
214  {
215  char msg[PATH_MAX];
216  snprintf(msg, sizeof(msg), _("Reading %s..."), mailbox_path(m));
217  progress = progress_new(msg, MUTT_PROGRESS_READ, 0);
218  }
219 
220  while (true)
221  {
222  if (!fgets(buf, sizeof(buf) - 1, adata->fp))
223  break;
224 
225  if (SigInt)
226  break;
227 
228  if (mutt_str_equal(buf, MMDF_SEP))
229  {
230  loc = ftello(adata->fp);
231  if (loc < 0)
232  goto fail;
233 
234  count++;
235  if (m->verbose)
236  progress_update(progress, count, (int) (loc / (m->size / 100 + 1)));
237 
238  if (m->msg_count == m->email_max)
239  mx_alloc_memory(m);
240  e = email_new();
241  m->emails[m->msg_count] = e;
242  e->offset = loc;
243  e->index = m->msg_count;
244 
245  if (!fgets(buf, sizeof(buf) - 1, adata->fp))
246  {
247  /* TODO: memory leak??? */
248  mutt_debug(LL_DEBUG1, "unexpected EOF\n");
249  break;
250  }
251 
252  return_path[0] = '\0';
253 
254  if (!is_from(buf, return_path, sizeof(return_path), &t))
255  {
256  if (fseeko(adata->fp, loc, SEEK_SET) != 0)
257  {
258  mutt_debug(LL_DEBUG1, "#1 fseek() failed\n");
259  mutt_error(_("Mailbox is corrupt"));
260  goto fail;
261  }
262  }
263  else
264  e->received = t - mutt_date_local_tz(t);
265 
266  e->env = mutt_rfc822_read_header(adata->fp, e, false, false);
267 
268  loc = ftello(adata->fp);
269  if (loc < 0)
270  goto fail;
271 
272  if ((e->body->length > 0) && (e->lines > 0))
273  {
274  tmploc = loc + e->body->length;
275 
276  if ((tmploc > 0) && (tmploc < m->size))
277  {
278  if ((fseeko(adata->fp, tmploc, SEEK_SET) != 0) ||
279  !fgets(buf, sizeof(buf) - 1, adata->fp) || !mutt_str_equal(MMDF_SEP, buf))
280  {
281  if (fseeko(adata->fp, loc, SEEK_SET) != 0)
282  mutt_debug(LL_DEBUG1, "#2 fseek() failed\n");
283  e->body->length = -1;
284  }
285  }
286  else
287  e->body->length = -1;
288  }
289  else
290  e->body->length = -1;
291 
292  if (e->body->length < 0)
293  {
294  lines = -1;
295  do
296  {
297  loc = ftello(adata->fp);
298  if (loc < 0)
299  goto fail;
300  if (!fgets(buf, sizeof(buf) - 1, adata->fp))
301  break;
302  lines++;
303  } while (!mutt_str_equal(buf, MMDF_SEP));
304 
305  e->lines = lines;
306  e->body->length = loc - e->body->offset;
307  }
308 
309  if (TAILQ_EMPTY(&e->env->return_path) && return_path[0])
310  mutt_addrlist_parse(&e->env->return_path, return_path);
311 
312  if (TAILQ_EMPTY(&e->env->from))
313  mutt_addrlist_copy(&e->env->from, &e->env->return_path, false);
314 
315  m->msg_count++;
316  }
317  else
318  {
319  mutt_debug(LL_DEBUG1, "corrupt mailbox\n");
320  mutt_error(_("Mailbox is corrupt"));
321  goto fail;
322  }
323  }
324 
325  if (SigInt)
326  {
327  SigInt = false;
328  rc = MX_OPEN_ABORT; /* action aborted */
329  goto fail;
330  }
331 
332  rc = MX_OPEN_OK;
333 fail:
334  progress_free(&progress);
335  return rc;
336 }
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
int lines
How many lines in the body of this message?
Definition: email.h:85
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
The envelope/body of an email.
Definition: email.h:37
struct Body * body
List of MIME parts.
Definition: email.h:91
size_t size
Total expected size.
Definition: progress.c:53
#define mutt_error(...)
Definition: logging.h:88
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
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
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
struct timespec atime
File&#39;s last-access time.
Definition: lib.h:51
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1212
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
Progress tracks elements, according to $read_inc
Definition: lib.h:46
time_t mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
Definition: date.c:206
MxOpenReturns
Return values for mbox_open()
Definition: mxapi.h:88
#define mutt_perror(...)
Definition: logging.h:89
A Progress Bar.
Definition: progress.c:47
Open succeeded.
Definition: mxapi.h:90
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
File/dir&#39;s mtime - last modified time.
Definition: file.h:63
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Open was aborted.
Definition: mxapi.h:92
char msg[1024]
Message to display.
Definition: progress.c:50
bool verbose
Display status messages?
Definition: mailbox.h:118
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MMDF_SEP
Definition: lib.h:60
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
struct AddressList return_path
Return path for the Email.
Definition: envelope.h:56
Log at debug level 1.
Definition: logging.h:40
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
int index
The absolute (unsorted) message number.
Definition: email.h:86
bool is_from(const char *s, char *path, size_t pathlen, time_t *tp)
Is a string a &#39;From&#39; header line?
Definition: from.c:48
#define TAILQ_EMPTY(head)
Definition: queue.h:721
Open failed with an error.
Definition: mxapi.h:91
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1124
FILE * fp
Mailbox file.
Definition: lib.h:50
File/dir&#39;s atime - last accessed time.
Definition: file.h:62
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_parse_mailbox()

static enum MxOpenReturns mbox_parse_mailbox ( struct Mailbox m)
static

Read a mailbox from disk.

Parameters
mMailbox
Return values
enumMxOpenReturns

Note that this function is also called when new mail is appended to the currently open folder, and NOT just when the mailbox is initially read.

Note
It is assumed that the mailbox being read has been locked before this routine gets called. Strange things could happen if it's not!

Definition at line 349 of file mbox.c.

350 {
351  if (!m)
352  return MX_OPEN_ERROR;
353 
354  struct MboxAccountData *adata = mbox_adata_get(m);
355  if (!adata)
356  return MX_OPEN_ERROR;
357 
358  struct stat sb;
359  char buf[8192], return_path[256];
360  struct Email *e_cur = NULL;
361  time_t t;
362  int count = 0, lines = 0;
363  LOFF_T loc;
364  struct Progress *progress = NULL;
365  enum MxOpenReturns rc = MX_OPEN_ERROR;
366 
367  /* Save information about the folder at the time we opened it. */
368  if (stat(mailbox_path(m), &sb) == -1)
369  {
371  goto fail;
372  }
373 
374  m->size = sb.st_size;
377 
378  if (!m->readonly)
379  m->readonly = access(mailbox_path(m), W_OK) ? true : false;
380 
381  if (m->verbose)
382  {
383  char msg[PATH_MAX];
384  snprintf(msg, sizeof(msg), _("Reading %s..."), mailbox_path(m));
385  progress = progress_new(msg, MUTT_PROGRESS_READ, 0);
386  }
387 
388  loc = ftello(adata->fp);
389  while ((fgets(buf, sizeof(buf), adata->fp)) && !SigInt)
390  {
391  if (is_from(buf, return_path, sizeof(return_path), &t))
392  {
393  /* Save the Content-Length of the previous message */
394  if (count > 0)
395  {
396  struct Email *e = m->emails[m->msg_count - 1];
397  if (e->body->length < 0)
398  {
399  e->body->length = loc - e->body->offset - 1;
400  if (e->body->length < 0)
401  e->body->length = 0;
402  }
403  if (!e->lines)
404  e->lines = lines ? lines - 1 : 0;
405  }
406 
407  count++;
408 
409  if (m->verbose)
410  {
411  progress_update(progress, count, (int) (ftello(adata->fp) / (m->size / 100 + 1)));
412  }
413 
414  if (m->msg_count == m->email_max)
415  mx_alloc_memory(m);
416 
417  m->emails[m->msg_count] = email_new();
418  e_cur = m->emails[m->msg_count];
419  e_cur->received = t - mutt_date_local_tz(t);
420  e_cur->offset = loc;
421  e_cur->index = m->msg_count;
422 
423  e_cur->env = mutt_rfc822_read_header(adata->fp, e_cur, false, false);
424 
425  /* if we know how long this message is, either just skip over the body,
426  * or if we don't know how many lines there are, count them now (this will
427  * save time by not having to search for the next message marker). */
428  if (e_cur->body->length > 0)
429  {
430  LOFF_T tmploc;
431 
432  loc = ftello(adata->fp);
433 
434  /* The test below avoids a potential integer overflow if the
435  * content-length is huge (thus necessarily invalid). */
436  tmploc = (e_cur->body->length < m->size) ? (loc + e_cur->body->length + 1) : -1;
437 
438  if ((tmploc > 0) && (tmploc < m->size))
439  {
440  /* check to see if the content-length looks valid. we expect to
441  * to see a valid message separator at this point in the stream */
442  if ((fseeko(adata->fp, tmploc, SEEK_SET) != 0) ||
443  !fgets(buf, sizeof(buf), adata->fp) || !mutt_str_startswith(buf, "From "))
444  {
445  mutt_debug(LL_DEBUG1, "bad content-length in message %d (cl=" OFF_T_FMT ")\n",
446  e_cur->index, e_cur->body->length);
447  mutt_debug(LL_DEBUG1, " LINE: %s", buf);
448  /* nope, return the previous position */
449  if ((loc < 0) || (fseeko(adata->fp, loc, SEEK_SET) != 0))
450  {
451  mutt_debug(LL_DEBUG1, "#1 fseek() failed\n");
452  }
453  e_cur->body->length = -1;
454  }
455  }
456  else if (tmploc != m->size)
457  {
458  /* content-length would put us past the end of the file, so it
459  * must be wrong */
460  e_cur->body->length = -1;
461  }
462 
463  if (e_cur->body->length != -1)
464  {
465  /* good content-length. check to see if we know how many lines
466  * are in this message. */
467  if (e_cur->lines == 0)
468  {
469  int cl = e_cur->body->length;
470 
471  /* count the number of lines in this message */
472  if ((loc < 0) || (fseeko(adata->fp, loc, SEEK_SET) != 0))
473  mutt_debug(LL_DEBUG1, "#2 fseek() failed\n");
474  while (cl-- > 0)
475  {
476  if (fgetc(adata->fp) == '\n')
477  e_cur->lines++;
478  }
479  }
480 
481  /* return to the offset of the next message separator */
482  if (fseeko(adata->fp, tmploc, SEEK_SET) != 0)
483  mutt_debug(LL_DEBUG1, "#3 fseek() failed\n");
484  }
485  }
486 
487  m->msg_count++;
488 
489  if (TAILQ_EMPTY(&e_cur->env->return_path) && return_path[0])
490  {
491  mutt_addrlist_parse(&e_cur->env->return_path, return_path);
492  }
493 
494  if (TAILQ_EMPTY(&e_cur->env->from))
495  mutt_addrlist_copy(&e_cur->env->from, &e_cur->env->return_path, false);
496 
497  lines = 0;
498  }
499  else
500  lines++;
501 
502  loc = ftello(adata->fp);
503  }
504 
505  /* Only set the content-length of the previous message if we have read more
506  * than one message during _this_ invocation. If this routine is called
507  * when new mail is received, we need to make sure not to clobber what
508  * previously was the last message since the headers may be sorted. */
509  if (count > 0)
510  {
511  struct Email *e = m->emails[m->msg_count - 1];
512  if (e->body->length < 0)
513  {
514  e->body->length = ftello(adata->fp) - e->body->offset - 1;
515  if (e->body->length < 0)
516  e->body->length = 0;
517  }
518 
519  if (!e->lines)
520  e->lines = lines ? lines - 1 : 0;
521  }
522 
523  if (SigInt)
524  {
525  SigInt = false;
526  rc = MX_OPEN_ABORT;
527  goto fail; /* action aborted */
528  }
529 
530  rc = MX_OPEN_OK;
531 fail:
532  progress_free(&progress);
533  return rc;
534 }
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
int lines
How many lines in the body of this message?
Definition: email.h:85
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
The envelope/body of an email.
Definition: email.h:37
struct Body * body
List of MIME parts.
Definition: email.h:91
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
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
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
struct timespec atime
File&#39;s last-access time.
Definition: lib.h:51
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:107
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1212
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
Progress tracks elements, according to $read_inc
Definition: lib.h:46
time_t mutt_date_local_tz(time_t t)
Calculate the local timezone in seconds east of UTC.
Definition: date.c:206
MxOpenReturns
Return values for mbox_open()
Definition: mxapi.h:88
#define mutt_perror(...)
Definition: logging.h:89
A Progress Bar.
Definition: progress.c:47
Open succeeded.
Definition: mxapi.h:90
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
struct Envelope * env
Envelope information.
Definition: email.h:90
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
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Open was aborted.
Definition: mxapi.h:92
char msg[1024]
Message to display.
Definition: progress.c:50
bool verbose
Display status messages?
Definition: mailbox.h:118
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
struct AddressList return_path
Return path for the Email.
Definition: envelope.h:56
Log at debug level 1.
Definition: logging.h:40
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
int index
The absolute (unsorted) message number.
Definition: email.h:86
bool is_from(const char *s, char *path, size_t pathlen, time_t *tp)
Is a string a &#39;From&#39; header line?
Definition: from.c:48
#define TAILQ_EMPTY(head)
Definition: queue.h:721
Open failed with an error.
Definition: mxapi.h:91
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1124
FILE * fp
Mailbox file.
Definition: lib.h:50
File/dir&#39;s atime - last accessed time.
Definition: file.h:62
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reopen_mailbox()

static int reopen_mailbox ( struct Mailbox m)
static

Close and reopen a mailbox.

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

Definition at line 542 of file mbox.c.

543 {
544  if (!m)
545  return -1;
546 
547  struct MboxAccountData *adata = mbox_adata_get(m);
548  if (!adata)
549  return -1;
550 
551  bool (*cmp_headers)(const struct Email *, const struct Email *) = NULL;
552  struct Email **e_old = NULL;
553  int old_msg_count;
554  bool msg_mod = false;
555  int rc = -1;
556 
557  /* silent operations */
558  m->verbose = false;
559 
560  /* our heuristics require the old mailbox to be unsorted */
561  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
562  if (c_sort != SORT_ORDER)
563  {
566  cs_subset_str_native_set(NeoMutt->sub, "sort", c_sort, NULL);
567  }
568 
569  e_old = NULL;
570  old_msg_count = 0;
571 
572  /* simulate a close */
573  mutt_hash_free(&m->id_hash);
576  FREE(&m->v2r);
577  if (m->readonly)
578  {
579  for (int i = 0; i < m->msg_count; i++)
580  email_free(&(m->emails[i])); /* nothing to do! */
581  FREE(&m->emails);
582  }
583  else
584  {
585  /* save the old headers */
586  old_msg_count = m->msg_count;
587  e_old = m->emails;
588  m->emails = NULL;
589  }
590 
591  m->email_max = 0; /* force allocation of new headers */
592  m->msg_count = 0;
593  m->vcount = 0;
594  m->msg_tagged = 0;
595  m->msg_deleted = 0;
596  m->msg_new = 0;
597  m->msg_unread = 0;
598  m->msg_flagged = 0;
599  m->changed = false;
600  m->id_hash = NULL;
601  m->subj_hash = NULL;
603 
604  switch (m->type)
605  {
606  case MUTT_MBOX:
607  case MUTT_MMDF:
608  cmp_headers = email_cmp_strict;
609  mutt_file_fclose(&adata->fp);
610  adata->fp = mutt_file_fopen(mailbox_path(m), "r");
611  if (!adata->fp)
612  rc = -1;
613  else if (m->type == MUTT_MBOX)
614  rc = mbox_parse_mailbox(m);
615  else
616  rc = mmdf_parse_mailbox(m);
617  break;
618 
619  default:
620  rc = -1;
621  break;
622  }
623 
624  if (rc == -1)
625  {
626  /* free the old headers */
627  for (int i = 0; i < old_msg_count; i++)
628  email_free(&(e_old[i]));
629  FREE(&e_old);
630 
631  m->verbose = true;
632  return -1;
633  }
634 
635  mutt_file_touch_atime(fileno(adata->fp));
636 
637  /* now try to recover the old flags */
638 
639  if (!m->readonly)
640  {
641  for (int i = 0; i < m->msg_count; i++)
642  {
643  bool found = false;
644 
645  /* some messages have been deleted, and new messages have been
646  * appended at the end; the heuristic is that old messages have then
647  * "advanced" towards the beginning of the folder, so we begin the
648  * search at index "i" */
649  int j;
650  for (j = i; j < old_msg_count; j++)
651  {
652  if (!e_old[j])
653  continue;
654  if (cmp_headers(m->emails[i], e_old[j]))
655  {
656  found = true;
657  break;
658  }
659  }
660  if (!found)
661  {
662  for (j = 0; (j < i) && (j < old_msg_count); j++)
663  {
664  if (!e_old[j])
665  continue;
666  if (cmp_headers(m->emails[i], e_old[j]))
667  {
668  found = true;
669  break;
670  }
671  }
672  }
673 
674  if (found)
675  {
676  m->changed = true;
677  if (e_old[j]->changed)
678  {
679  /* Only update the flags if the old header was changed;
680  * otherwise, the header may have been modified externally,
681  * and we don't want to lose _those_ changes */
682  mutt_set_flag(m, m->emails[i], MUTT_FLAG, e_old[j]->flagged);
683  mutt_set_flag(m, m->emails[i], MUTT_REPLIED, e_old[j]->replied);
684  mutt_set_flag(m, m->emails[i], MUTT_OLD, e_old[j]->old);
685  mutt_set_flag(m, m->emails[i], MUTT_READ, e_old[j]->read);
686  }
687  mutt_set_flag(m, m->emails[i], MUTT_DELETE, e_old[j]->deleted);
688  mutt_set_flag(m, m->emails[i], MUTT_PURGE, e_old[j]->purge);
689  mutt_set_flag(m, m->emails[i], MUTT_TAG, e_old[j]->tagged);
690 
691  /* we don't need this header any more */
692  email_free(&(e_old[j]));
693  }
694  }
695 
696  /* free the remaining old headers */
697  for (int j = 0; j < old_msg_count; j++)
698  {
699  if (e_old[j])
700  {
701  email_free(&(e_old[j]));
702  msg_mod = true;
703  }
704  }
705  FREE(&e_old);
706  }
707 
709  m->verbose = true;
710 
711  return (m->changed || msg_mod) ? MX_STATUS_REOPENED : MX_STATUS_NEW_MAIL;
712 }
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
void mutt_file_touch_atime(int fd)
Set the access time to current time.
Definition: file.c:1029
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
Update internal tables.
Definition: mailbox.h:183
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
struct HashTable * label_hash
Hash Table for x-labels.
Definition: mailbox.h:129
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
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
New mail received in Mailbox.
Definition: mxapi.h:79
Flagged messages.
Definition: mutt.h:98
bool changed
Email has been edited.
Definition: email.h:48
Messages to be purged (bypass trash)
Definition: mutt.h:96
static enum MxOpenReturns mmdf_parse_mailbox(struct Mailbox *m)
Read a mailbox in MMDF format.
Definition: mbox.c:182
Container for Accounts, Notifications.
Definition: neomutt.h:36
Messages that have been replied to.
Definition: mutt.h:91
int vcount
The number of virtual messages.
Definition: mailbox.h:102
Mailbox was reopened.
Definition: mxapi.h:81
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:127
bool old
Email is seen, but unread.
Definition: email.h:50
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:128
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Old messages.
Definition: mutt.h:90
Email list needs resorting.
Definition: mailbox.h:181
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
Messages to be deleted.
Definition: mutt.h:94
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Tagged messages.
Definition: mutt.h:99
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
Messages that have been read.
Definition: mutt.h:92
bool verbose
Display status messages?
Definition: mailbox.h:118
bool purge
Skip trash folder when deleting.
Definition: email.h:46
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
static struct MboxAccountData * mbox_adata_get(struct Mailbox *m)
Get the private data associated with a Mailbox.
Definition: mbox.c:100
bool email_cmp_strict(const struct Email *e1, const struct Email *e2)
Strictly compare message emails.
Definition: email.c:100
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
void mutt_make_label_hash(struct Mailbox *m)
Create a Hash Table to store the labels.
Definition: mutt_header.c:368
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:95
bool deleted
Email is deleted.
Definition: email.h:45
bool replied
Email has been replied to.
Definition: email.h:54
#define FREE(x)
Definition: memory.h:40
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
FILE * fp
Mailbox file.
Definition: lib.h:50
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:208
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_has_new()

static bool mbox_has_new ( struct Mailbox m)
static

Does the mailbox have new mail.

Parameters
mMailbox
Return values
trueThe mailbox has at least 1 new messages (not old)
falseotherwise

Definition at line 720 of file mbox.c.

721 {
722  for (int i = 0; i < m->msg_count; i++)
723  {
724  struct Email *e = m->emails[i];
725  if (!e)
726  break;
727  if (!e->deleted && !e->read && !e->old)
728  return true;
729  }
730  return false;
731 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
bool deleted
Email is deleted.
Definition: email.h:45
+ Here is the caller graph for this function:

◆ fseek_last_message()

static int fseek_last_message ( FILE *  fp)
static

Find the last message in the file.

Parameters
fpFile to search
Return values
0Success
-1No message found

Definition at line 739 of file mbox.c.

740 {
741  LOFF_T pos;
742  char buf[BUFSIZ + 9] = { 0 }; /* 7 for "\n\nFrom " */
743  size_t bytes_read;
744 
745  fseek(fp, 0, SEEK_END);
746  pos = ftello(fp);
747 
748  /* Set 'bytes_read' to the size of the last, probably partial, buf;
749  * 0 < 'bytes_read' <= 'BUFSIZ'. */
750  bytes_read = pos % BUFSIZ;
751  if (bytes_read == 0)
752  bytes_read = BUFSIZ;
753  /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all
754  * reads will be on block boundaries, which might increase efficiency. */
755  while ((pos -= bytes_read) >= 0)
756  {
757  /* we save in the buf at the end the first 7 chars from the last read */
758  strncpy(buf + BUFSIZ, buf, 5 + 2); /* 2 == 2 * mutt_str_len(CRLF) */
759  fseeko(fp, pos, SEEK_SET);
760  bytes_read = fread(buf, sizeof(char), bytes_read, fp);
761  if (bytes_read == 0)
762  return -1;
763  /* 'i' is Index into 'buf' for scanning. */
764  for (int i = bytes_read; i >= 0; i--)
765  {
766  if (mutt_str_startswith(buf + i, "\n\nFrom "))
767  { /* found it - go to the beginning of the From */
768  fseeko(fp, pos + i + 2, SEEK_SET);
769  return 0;
770  }
771  }
772  bytes_read = BUFSIZ;
773  }
774 
775  /* here we are at the beginning of the file */
776  if (mutt_str_startswith(buf, "From "))
777  {
778  fseek(fp, 0, SEEK_SET);
779  return 0;
780  }
781 
782  return -1;
783 }
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ test_last_status_new()

static bool test_last_status_new ( FILE *  fp)
static

Is the last message new.

Parameters
fpFile to check
Return values
trueThe last message is new

Definition at line 790 of file mbox.c.

791 {
792  struct Email *e = NULL;
793  struct Envelope *tmp_envelope = NULL;
794  bool rc = false;
795 
796  if (fseek_last_message(fp) == -1)
797  return false;
798 
799  e = email_new();
800  tmp_envelope = mutt_rfc822_read_header(fp, e, false, false);
801  if (!e->read && !e->old)
802  rc = true;
803 
804  mutt_env_free(&tmp_envelope);
805  email_free(&e);
806 
807  return rc;
808 }
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
static int fseek_last_message(FILE *fp)
Find the last message in the file.
Definition: mbox.c:739
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1124
The header of an Email.
Definition: envelope.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_test_new_folder()

bool mbox_test_new_folder ( const char *  path)

Test if an mbox or mmdf mailbox has new mail.

Parameters
pathPath to the mailbox
Return values
trueThe folder contains new mail

Definition at line 815 of file mbox.c.

816 {
817  bool rc = false;
818 
819  enum MailboxType type = mx_path_probe(path);
820 
821  if ((type != MUTT_MBOX) && (type != MUTT_MMDF))
822  return false;
823 
824  FILE *fp = fopen(path, "rb");
825  if (fp)
826  {
827  rc = test_last_status_new(fp);
828  mutt_file_fclose(&fp);
829  }
830 
831  return rc;
832 }
static bool test_last_status_new(FILE *fp)
Is the last message new.
Definition: mbox.c:790
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1317
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
+ Here is the call graph for this function:

◆ mbox_reset_atime()

void mbox_reset_atime ( struct Mailbox m,
struct stat *  st 
)

Reset the access time on the mailbox file.

Parameters
mMailbox
stTimestamp

if mailbox has at least 1 new message, sets mtime > atime of mailbox so mailbox check reports new mail

Definition at line 842 of file mbox.c.

843 {
844  struct utimbuf utimebuf;
845  struct stat st2;
846 
847  if (!st)
848  {
849  if (stat(mailbox_path(m), &st2) < 0)
850  return;
851  st = &st2;
852  }
853 
854  utimebuf.actime = st->st_atime;
855  utimebuf.modtime = st->st_mtime;
856 
857  /* When $mbox_check_recent is set, existing new mail is ignored, so do not
858  * reset the atime to mtime-1 to signal new mail. */
859  const bool c_mail_check_recent =
860  cs_subset_bool(NeoMutt->sub, "mail_check_recent");
861  if (!c_mail_check_recent && (utimebuf.actime >= utimebuf.modtime) && mbox_has_new(m))
862  {
863  utimebuf.actime = utimebuf.modtime - 1;
864  }
865 
866  utime(mailbox_path(m), &utimebuf);
867 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Container for Accounts, Notifications.
Definition: neomutt.h:36
static bool mbox_has_new(struct Mailbox *m)
Does the mailbox have new mail.
Definition: mbox.c:720
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_open_readwrite()

static FILE* mbox_open_readwrite ( struct Mailbox m)
static

Open an mbox read-write.

Parameters
mMailbox
Return values
ptrFILE handle

This function ensures that the FILE and readonly flag are changed atomically.

Definition at line 899 of file mbox.c.

900 {
901  FILE *fp = fopen(mailbox_path(m), "r+");
902  if (fp)
903  m->readonly = false;
904  return fp;
905 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbox_open_readonly()

static FILE* mbox_open_readonly ( struct Mailbox m)
static

Open an mbox read-only.

Parameters
mMailbox
Return values
ptrFILE handle

This function ensures that the FILE and readonly flag are changed atomically.

Definition at line 914 of file mbox.c.

915 {
916  FILE *fp = fopen(mailbox_path(m), "r");
917  if (fp)
918  m->readonly = true;
919  return fp;
920 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
+ Here is the call graph for this function:
+ Here is the caller graph for this function: