NeoMutt  2021-02-05-329-g9e03b7
Teaching an old dog new tricks
DOXYGEN
mx.c File Reference

Mailbox multiplexor. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "mx.h"
#include "maildir/lib.h"
#include "mbox/lib.h"
#include "commands.h"
#include "copy.h"
#include "hook.h"
#include "keymap.h"
#include "mutt_globals.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "compmbox/lib.h"
#include "imap/lib.h"
#include "pop/lib.h"
#include "nntp/lib.h"
#include "nntp/adata.h"
#include "nntp/mdata.h"
#include "notmuch/lib.h"
#include <libintl.h>
+ Include dependency graph for mx.c:

Go to the source code of this file.

Functions

const struct MxOpsmx_get_ops (enum MailboxType type)
 Get mailbox operations. More...
 
static bool mutt_is_spool (const char *str)
 Is this the spool_file? More...
 
int mx_access (const char *path, int flags)
 Wrapper for access, checks permissions on a given mailbox. More...
 
static bool mx_open_mailbox_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a mailbox for appending. More...
 
bool mx_mbox_ac_link (struct Mailbox *m)
 Link a Mailbox to an existing or new Account. More...
 
bool mx_mbox_open (struct Mailbox *m, OpenMailboxFlags flags)
 Open a mailbox and parse it. More...
 
void mx_fastclose_mailbox (struct Mailbox *m)
 free up memory associated with the Mailbox More...
 
static enum MxStatus sync_mailbox (struct Mailbox *m)
 save changes to disk More...
 
static int trash_append (struct Mailbox *m)
 move deleted mails to the trash folder More...
 
enum MxStatus mx_mbox_close (struct Mailbox *m)
 Save changes and close mailbox. More...
 
enum MxStatus mx_mbox_sync (struct Mailbox *m)
 Save changes to mailbox. More...
 
struct Messagemx_msg_open_new (struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
 Open a new message. More...
 
enum MxStatus mx_mbox_check (struct Mailbox *m)
 Check for new mail - Wrapper for MxOps::mbox_check() More...
 
struct Messagemx_msg_open (struct Mailbox *m, int msgno)
 return a stream pointer for a message More...
 
int mx_msg_commit (struct Mailbox *m, struct Message *msg)
 Commit a message to a folder - Wrapper for MxOps::msg_commit() More...
 
int mx_msg_close (struct Mailbox *m, struct Message **msg)
 Close a message. More...
 
void mx_alloc_memory (struct Mailbox *m)
 Create storage for the emails. More...
 
int mx_path_is_empty (const char *path)
 Is the mailbox empty. More...
 
int mx_tags_edit (struct Mailbox *m, const char *tags, char *buf, size_t buflen)
 start the tag editor of the mailbox More...
 
int mx_tags_commit (struct Mailbox *m, struct Email *e, char *tags)
 Save tags to the Mailbox - Wrapper for MxOps::tags_commit() More...
 
bool mx_tags_is_supported (struct Mailbox *m)
 return true if mailbox support tagging More...
 
enum MailboxType mx_path_probe (const char *path)
 Find a mailbox that understands a path. More...
 
int mx_path_canon (char *buf, size_t buflen, const char *folder, enum MailboxType *type)
 Canonicalise a mailbox path - Wrapper for MxOps::path_canon() More...
 
int mx_path_canon2 (struct Mailbox *m, const char *folder)
 Canonicalise the path to realpath. More...
 
int mx_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a mailbox path - Wrapper for MxOps::path_pretty() More...
 
int mx_path_parent (char *buf, size_t buflen)
 Find the parent of a mailbox path - Wrapper for MxOps::path_parent() More...
 
int mx_msg_padding_size (struct Mailbox *m)
 Bytes of padding between messages - Wrapper for MxOps::msg_padding_size() More...
 
struct Accountmx_ac_find (struct Mailbox *m)
 Find the Account owning a Mailbox. More...
 
struct Mailboxmx_mbox_find (struct Account *a, const char *path)
 Find a Mailbox on an Account. More...
 
struct Mailboxmx_mbox_find2 (const char *path)
 Find a Mailbox on an Account. More...
 
struct Mailboxmx_path_resolve (const char *path)
 Get a Mailbox for a path. More...
 
static struct Mailboxmx_mbox_find_by_name_ac (struct Account *a, const char *name)
 Find a Mailbox with given name under an Account. More...
 
static struct Mailboxmx_mbox_find_by_name (const char *name)
 Find a Mailbox with given name. More...
 
struct Mailboxmx_resolve (const char *path_or_name)
 Get a Mailbox from either a path or name. More...
 
bool mx_ac_add (struct Account *a, struct Mailbox *m)
 Add a Mailbox to an Account - Wrapper for MxOps::ac_add() More...
 
int mx_ac_remove (struct Mailbox *m)
 Remove a Mailbox from an Account and delete Account if empty. More...
 
enum MxStatus mx_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the statistics for a mailbox - Wrapper for MxOps::mbox_check_stats() More...
 
int mx_save_hcache (struct Mailbox *m, struct Email *e)
 Save message to the header cache - Wrapper for MxOps::msg_save_hcache() More...
 
enum MailboxType mx_type (struct Mailbox *m)
 Return the type of the Mailbox. More...
 

Variables

static struct Mapping MboxTypeMap []
 
struct EnumDef MboxTypeDef
 
const struct MxOpsmx_ops []
 All the Mailbox backends. More...
 

Detailed Description

Mailbox multiplexor.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • 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 mx.c.

Function Documentation

◆ mx_get_ops()

const struct MxOps* mx_get_ops ( enum MailboxType  type)

Get mailbox operations.

Parameters
typeMailbox type
Return values
ptrMailbox function
NULLError

Definition at line 140 of file mx.c.

141 {
142  for (const struct MxOps **ops = mx_ops; *ops; ops++)
143  if ((*ops)->type == type)
144  return *ops;
145 
146  return NULL;
147 }
const struct MxOps * mx_ops[]
All the Mailbox backends.
Definition: mx.c:106
The Mailbox API.
Definition: mxapi.h:101
+ Here is the caller graph for this function:

◆ mutt_is_spool()

static bool mutt_is_spool ( const char *  str)
static

Is this the spool_file?

Parameters
strName to check
Return values
trueIt is the spool_file

Definition at line 154 of file mx.c.

155 {
156  const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
157  if (mutt_str_equal(str, c_spool_file))
158  return true;
159 
160  struct Url *ua = url_parse(str);
161  struct Url *ub = url_parse(c_spool_file);
162 
163  const bool is_spool =
164  ua && ub && (ua->scheme == ub->scheme) &&
165  mutt_istr_equal(ua->host, ub->host) && mutt_istr_equal(ua->path, ub->path) &&
166  (!ua->user || !ub->user || mutt_str_equal(ua->user, ub->user));
167 
168  url_free(&ua);
169  url_free(&ub);
170  return is_spool;
171 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
char * user
Username.
Definition: url.h:71
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
char * host
Host.
Definition: url.h:73
char * path
Path.
Definition: url.h:75
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_access()

int mx_access ( const char *  path,
int  flags 
)

Wrapper for access, checks permissions on a given mailbox.

Parameters
pathPath of mailbox
flagsFlags, e.g. W_OK
Return values
0Success, allowed
<0Failure, not allowed

We may be interested in using ACL-style flags at some point, currently we use the normal access() flags.

Definition at line 183 of file mx.c.

184 {
185 #ifdef USE_IMAP
186  if (imap_path_probe(path, NULL) == MUTT_IMAP)
187  return imap_access(path);
188 #endif
189 
190  return access(path, flags);
191 }
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2400
int imap_access(const char *path)
Check permissions on an IMAP mailbox with a new connection.
Definition: imap.c:471
char * path
Path.
Definition: url.h:75
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_open_mailbox_append()

static bool mx_open_mailbox_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a mailbox for appending.

Parameters
mMailbox
flagsFlags, see OpenMailboxFlags
Return values
trueSuccess
falseFailure

Definition at line 200 of file mx.c.

201 {
202  if (!m)
203  return false;
204 
205  struct stat sb;
206 
207  m->append = true;
208  if ((m->type == MUTT_UNKNOWN) || (m->type == MUTT_MAILBOX_ERROR))
209  {
211 
212  if (m->type == MUTT_UNKNOWN)
213  {
214  if (flags & (MUTT_APPEND | MUTT_NEWFOLDER))
215  {
217  }
218  else
219  {
220  mutt_error(_("%s is not a mailbox"), mailbox_path(m));
221  return false;
222  }
223  }
224 
225  if (m->type == MUTT_MAILBOX_ERROR)
226  {
227  if (stat(mailbox_path(m), &sb) == -1)
228  {
229  if (errno == ENOENT)
230  {
231 #ifdef USE_COMP_MBOX
232  if (mutt_comp_can_append(m))
233  m->type = MUTT_COMPRESSED;
234  else
235 #endif
236  m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
237  flags |= MUTT_APPENDNEW;
238  }
239  else
240  {
242  return false;
243  }
244  }
245  else
246  return false;
247  }
248 
249  m->mx_ops = mx_get_ops(m->type);
250  }
251 
252  if (!m->mx_ops || !m->mx_ops->mbox_open_append)
253  return false;
254 
255  const bool rc = m->mx_ops->mbox_open_append(m, flags);
256  m->opened++;
257  return rc;
258 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:206
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define mutt_perror(...)
Definition: logging.h:85
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
Error occurred examining Mailbox.
Definition: mailbox.h:46
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mxapi.h:62
#define MUTT_APPENDNEW
Set in mx_open_mailbox_append if the mailbox doesn&#39;t exist.
Definition: mxapi.h:69
Container for Accounts, Notifications.
Definition: neomutt.h:36
int opened
Number of times mailbox is opened.
Definition: mailbox.h:132
Compressed file Mailbox type.
Definition: mailbox.h:56
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mxapi.h:65
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1316
#define mutt_error(...)
Definition: logging.h:84
bool(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending.
Definition: mxapi.h:153
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:93
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition: compress.c:357
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_ac_link()

bool mx_mbox_ac_link ( struct Mailbox m)

Link a Mailbox to an existing or new Account.

Parameters
mMailbox to link
Return values
trueSuccess
falseFailure

Definition at line 266 of file mx.c.

267 {
268  if (!m)
269  return false;
270 
271  if (m->account)
272  return true;
273 
274  struct Account *a = mx_ac_find(m);
275  const bool new_account = !a;
276  if (new_account)
277  {
278  a = account_new(NULL, NeoMutt->sub);
279  a->type = m->type;
280  }
281  if (!mx_ac_add(a, m))
282  {
283  if (new_account)
284  {
285  FREE(&a);
286  }
287  return false;
288  }
289  if (new_account)
290  {
292  }
293  return true;
294 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
struct Account * mx_ac_find(struct Mailbox *m)
Find the Account owning a Mailbox.
Definition: mx.c:1553
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Account * account_new(const char *name, struct ConfigSubset *sub)
Create a new Account.
Definition: account.c:42
bool mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1755
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool neomutt_account_add(struct NeoMutt *n, struct Account *a)
Add an Account to the global list.
Definition: neomutt.c:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_open()

bool mx_mbox_open ( struct Mailbox m,
OpenMailboxFlags  flags 
)

Open a mailbox and parse it.

Parameters
mMailbox to open
flagsFlags, see OpenMailboxFlags
Return values
trueSuccess
falseError

Definition at line 303 of file mx.c.

304 {
305  if (!m)
306  return false;
307 
308  if ((m->type == MUTT_UNKNOWN) && (flags & (MUTT_NEWFOLDER | MUTT_APPEND)))
309  {
310  m->type = cs_subset_enum(NeoMutt->sub, "mbox_type");
311  m->mx_ops = mx_get_ops(m->type);
312  }
313 
314  const bool newly_linked_account = !m->account;
315  if (newly_linked_account)
316  {
317  if (!mx_mbox_ac_link(m))
318  {
319  return false;
320  }
321  }
322 
323  m->verbose = !(flags & MUTT_QUIET);
324  m->readonly = (flags & MUTT_READONLY);
325  m->peekonly = (flags & MUTT_PEEK);
326 
327  if (flags & (MUTT_APPEND | MUTT_NEWFOLDER))
328  {
329  if (!mx_open_mailbox_append(m, flags))
330  {
331  goto error;
332  }
333  return true;
334  }
335 
336  if (m->opened > 0)
337  {
338  m->opened++;
339  return true;
340  }
341 
342  m->size = 0;
343  m->msg_unread = 0;
344  m->msg_flagged = 0;
345  m->rights = MUTT_ACL_ALL;
346 
347  if (m->type == MUTT_UNKNOWN)
348  {
350  m->mx_ops = mx_get_ops(m->type);
351  }
352 
353  if ((m->type == MUTT_UNKNOWN) || (m->type == MUTT_MAILBOX_ERROR) || !m->mx_ops)
354  {
355  if (m->type == MUTT_MAILBOX_ERROR)
357  else if ((m->type == MUTT_UNKNOWN) || !m->mx_ops)
358  mutt_error(_("%s is not a mailbox"), mailbox_path(m));
359  goto error;
360  }
361 
363 
364  /* if the user has a 'push' command in their .neomuttrc, or in a folder-hook,
365  * it will cause the progress messages not to be displayed because
366  * mutt_refresh() will think we are in the middle of a macro. so set a
367  * flag to indicate that we should really refresh the screen. */
368  OptForceRefresh = true;
369 
370  if (m->verbose)
371  mutt_message(_("Reading %s..."), mailbox_path(m));
372 
373  // Clear out any existing emails
374  for (int i = 0; i < m->email_max; i++)
375  {
376  email_free(&m->emails[i]);
377  }
378 
379  m->msg_count = 0;
380  m->msg_unread = 0;
381  m->msg_flagged = 0;
382  m->msg_new = 0;
383  m->msg_deleted = 0;
384  m->msg_tagged = 0;
385  m->vcount = 0;
386 
387  enum MxOpenReturns rc = m->mx_ops->mbox_open(m);
388  m->opened++;
389 
390  if ((rc == MX_OPEN_OK) || (rc == MX_OPEN_ABORT))
391  {
392  if ((flags & MUTT_NOSORT) == 0)
393  {
394  /* avoid unnecessary work since the mailbox is completely unthreaded
395  * to begin with */
396  OptSortSubthreads = false;
397  OptNeedRescore = false;
398  }
399  if (m->verbose)
401  if (rc == MX_OPEN_ABORT)
402  {
403  mutt_error(_("Reading from %s interrupted..."), mailbox_path(m));
404  }
405  }
406  else
407  {
408  goto error;
409  }
410 
411  if (!m->peekonly)
412  m->has_new = false;
413  OptForceRefresh = false;
414 
415  return true;
416 
417 error:
419  if (newly_linked_account)
421  return false;
422 }
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:206
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define MUTT_ACL_ALL
Definition: mailbox.h:76
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
#define MUTT_PEEK
Revert atime back after taking a look (if applicable)
Definition: mxapi.h:68
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
#define mutt_perror(...)
Definition: logging.h:85
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:117
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
Error occurred examining Mailbox.
Definition: mailbox.h:46
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mxapi.h:62
MxOpenReturns
Return values for mbox_open()
Definition: mxapi.h:88
WHERE bool OptNeedRescore
(pseudo) set when the &#39;score&#39; command is used
Definition: options.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:36
Open succeeded.
Definition: mxapi.h:90
int vcount
The number of virtual messages.
Definition: mailbox.h:102
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:428
int opened
Number of times mailbox is opened.
Definition: mailbox.h:132
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
WHERE bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:37
enum MxOpenReturns(* mbox_open)(struct Mailbox *m)
Open a Mailbox.
Definition: mxapi.h:141
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
#define MUTT_READONLY
Open in read-only mode.
Definition: mxapi.h:63
Open was aborted.
Definition: mxapi.h:92
bool verbose
Display status messages?
Definition: mailbox.h:118
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mxapi.h:65
#define MUTT_QUIET
Do not print any messages.
Definition: mxapi.h:64
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
void mutt_make_label_hash(struct Mailbox *m)
Create a Hash Table to store the labels.
Definition: mutt_header.c:368
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1316
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
int msg_new
Number of new messages.
Definition: mailbox.h:95
#define mutt_error(...)
Definition: logging.h:84
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:93
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:93
bool mx_mbox_ac_link(struct Mailbox *m)
Link a Mailbox to an existing or new Account.
Definition: mx.c:266
WHERE bool OptSortSubthreads
(pseudo) used when $sort_aux changes
Definition: options.h:54
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
static bool mx_open_mailbox_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox for appending.
Definition: mx.c:200
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mxapi.h:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_fastclose_mailbox()

void mx_fastclose_mailbox ( struct Mailbox m)

free up memory associated with the Mailbox

Parameters
mMailbox

Definition at line 428 of file mx.c.

429 {
430  if (!m)
431  return;
432 
433  m->opened--;
434  if (m->opened != 0)
435  return;
436 
437  /* never announce that a mailbox we've just left has new mail.
438  * TODO: really belongs in mx_mbox_close, but this is a nice hook point */
439  if (!m->peekonly)
441 
442  if (m->mx_ops)
443  m->mx_ops->mbox_close(m);
444 
446  mutt_hash_free(&m->id_hash);
448 
449  if (m->emails)
450  {
451  for (int i = 0; i < m->msg_count; i++)
452  {
453  if (!m->emails[i])
454  break;
455  email_free(&m->emails[i]);
456  }
457  }
458 
459  if (m->flags & MB_HIDDEN)
460  {
461  mx_ac_remove(m);
462  }
463 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
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:447
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:117
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:127
int opened
Number of times mailbox is opened.
Definition: mailbox.h:132
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:128
#define MB_HIDDEN
Definition: mailbox.h:38
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
enum MxStatus(* mbox_close)(struct Mailbox *m)
Close a Mailbox.
Definition: mxapi.h:194
void mutt_mailbox_set_notified(struct Mailbox *m)
Note when the user was last notified of new mail.
Definition: mutt_mailbox.c:291
int mx_ac_remove(struct Mailbox *m)
Remove a Mailbox from an Account and delete Account if empty.
Definition: mx.c:1768
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sync_mailbox()

static enum MxStatus sync_mailbox ( struct Mailbox m)
static

save changes to disk

Parameters
mMailbox
Return values
enumMxStatus

Definition at line 470 of file mx.c.

471 {
472  if (!m || !m->mx_ops || !m->mx_ops->mbox_sync)
473  return MX_STATUS_ERROR;
474 
475  if (m->verbose)
476  {
477  /* L10N: Displayed before/as a mailbox is being synced */
478  mutt_message(_("Writing %s..."), mailbox_path(m));
479  }
480 
481  enum MxStatus rc = m->mx_ops->mbox_sync(m);
482  if (rc != MX_STATUS_OK)
483  {
484  mutt_debug(LL_DEBUG2, "mbox_sync returned: %d\n", rc);
485  if ((rc == MX_STATUS_ERROR) && m->verbose)
486  {
487  /* L10N: Displayed if a mailbox sync fails */
488  mutt_error(_("Unable to write %s"), mailbox_path(m));
489  }
490  }
491 
492  return rc;
493 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:206
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
Log at debug level 2.
Definition: logging.h:41
enum MxStatus(* mbox_sync)(struct Mailbox *m)
Save changes to the Mailbox.
Definition: mxapi.h:184
No changes.
Definition: mxapi.h:78
bool verbose
Display status messages?
Definition: mailbox.h:118
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trash_append()

static int trash_append ( struct Mailbox m)
static

move deleted mails to the trash folder

Parameters
mMailbox
Return values
0Success
-1Failure

Definition at line 501 of file mx.c.

502 {
503  if (!m)
504  return -1;
505 
506  struct stat st, stc;
507  int rc;
508 
509  const bool c_maildir_trash = cs_subset_bool(NeoMutt->sub, "maildir_trash");
510  const char *const c_trash = cs_subset_string(NeoMutt->sub, "trash");
511  if (!c_trash || (m->msg_deleted == 0) || ((m->type == MUTT_MAILDIR) && c_maildir_trash))
512  {
513  return 0;
514  }
515 
516  int delmsgcount = 0;
517  int first_del = -1;
518  for (int i = 0; i < m->msg_count; i++)
519  {
520  struct Email *e = m->emails[i];
521  if (!e)
522  break;
523 
524  if (e->deleted && !e->purge)
525  {
526  if (first_del < 0)
527  first_del = i;
528  delmsgcount++;
529  }
530  }
531 
532  if (delmsgcount == 0)
533  return 0; /* nothing to be done */
534 
535  /* avoid the "append messages" prompt */
536  const bool c_confirm_append = cs_subset_bool(NeoMutt->sub, "confirm_append");
537  cs_subset_str_native_set(NeoMutt->sub, "confirm_append", false, NULL);
538  rc = mutt_save_confirm(c_trash, &st);
539  cs_subset_str_native_set(NeoMutt->sub, "confirm_append", c_confirm_append, NULL);
540  if (rc != 0)
541  {
542  /* L10N: Although we know the precise number of messages, we do not show it to the user.
543  So feel free to use a "generic plural" as plural translation if your language has one. */
544  mutt_error(ngettext("message not deleted", "messages not deleted", delmsgcount));
545  return -1;
546  }
547 
548  if ((lstat(mailbox_path(m), &stc) == 0) && (stc.st_ino == st.st_ino) &&
549  (stc.st_dev == st.st_dev) && (stc.st_rdev == st.st_rdev))
550  {
551  return 0; /* we are in the trash folder: simple sync */
552  }
553 
554 #ifdef USE_IMAP
555  if ((m->type == MUTT_IMAP) && (imap_path_probe(c_trash, NULL) == MUTT_IMAP))
556  {
557  if (imap_fast_trash(m, c_trash) == 0)
558  return 0;
559  }
560 #endif
561 
562  struct Mailbox *m_trash = mx_path_resolve(c_trash);
563  const bool old_append = m_trash->append;
564  if (!mx_mbox_open(m_trash, MUTT_APPEND))
565  {
566  mutt_error(_("Can't open trash folder"));
567  mailbox_free(&m_trash);
568  return -1;
569  }
570 
571  /* continue from initial scan above */
572  for (int i = first_del; i < m->msg_count; i++)
573  {
574  struct Email *e = m->emails[i];
575  if (!e)
576  break;
577 
578  if (e->deleted && !e->purge)
579  {
580  if (mutt_append_message(m_trash, m, e, NULL, MUTT_CM_NO_FLAGS, CH_NO_FLAGS) == -1)
581  {
582  mx_mbox_close(m_trash);
583  m_trash->append = old_append;
584  return -1;
585  }
586  }
587  }
588 
589  mx_mbox_close(m_trash);
590  m_trash->append = old_append;
591 
592  return 0;
593 }
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:206
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
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:71
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
The envelope/body of an email.
Definition: email.h:37
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2400
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int mutt_append_message(struct Mailbox *m_dst, struct Mailbox *m_src, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:916
#define _(a)
Definition: message.h:28
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mxapi.h:62
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:609
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1360
int imap_fast_trash(struct Mailbox *m, const char *dest)
Use server COPY command to copy deleted messages to trash.
Definition: imap.c:1420
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:292
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
A mailbox.
Definition: mailbox.h:81
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:51
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
bool purge
Skip trash folder when deleting.
Definition: email.h:46
bool deleted
Email is deleted.
Definition: email.h:45
#define mutt_error(...)
Definition: logging.h:84
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1667
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_close()

enum MxStatus mx_mbox_close ( struct Mailbox m)

Save changes and close mailbox.

Parameters
mMailbox
Return values
enumMxStatus
Note
The flag retvals come from a call to a backend sync function
It's very important to ensure the mailbox is properly closed before free'ing the context. For selected mailboxes, IMAP will cache the context inside connection->adata until imap_close_mailbox() removes it. Readonly, dontwrite, and append mailboxes are guaranteed to call mx_fastclose_mailbox(), so for most of NeoMutt's code you won't see return value checks for temporary contexts.

Definition at line 609 of file mx.c.

610 {
611  if (!m)
612  return MX_STATUS_ERROR;
613 
614  const bool c_mail_check_recent =
615  cs_subset_bool(NeoMutt->sub, "mail_check_recent");
616  if (c_mail_check_recent && !m->peekonly)
617  m->has_new = false;
618 
619  if (m->readonly || m->dontwrite || m->append || m->peekonly)
620  {
622  return 0;
623  }
624 
625  int i, read_msgs = 0;
626  enum MxStatus rc = MX_STATUS_ERROR;
627  enum QuadOption move_messages = MUTT_NO;
628  enum QuadOption purge = MUTT_YES;
629  struct Buffer *mbox = NULL;
630  struct Buffer *buf = mutt_buffer_pool_get();
631 
632 #ifdef USE_NNTP
633  if ((m->msg_unread != 0) && (m->type == MUTT_NNTP))
634  {
635  struct NntpMboxData *mdata = m->mdata;
636 
637  if (mdata && mdata->adata && mdata->group)
638  {
639  const enum QuadOption c_catchup_newsgroup =
640  cs_subset_quad(NeoMutt->sub, "catchup_newsgroup");
641  enum QuadOption ans =
642  query_quadoption(c_catchup_newsgroup, _("Mark all articles read?"));
643  if (ans == MUTT_ABORT)
644  goto cleanup;
645  if (ans == MUTT_YES)
646  mutt_newsgroup_catchup(m, mdata->adata, mdata->group);
647  }
648  }
649 #endif
650 
651  const bool c_keep_flagged = cs_subset_bool(NeoMutt->sub, "keep_flagged");
652  for (i = 0; i < m->msg_count; i++)
653  {
654  struct Email *e = m->emails[i];
655  if (!e)
656  break;
657 
658  if (!e->deleted && e->read && !(e->flagged && c_keep_flagged))
659  read_msgs++;
660  }
661 
662 #ifdef USE_NNTP
663  /* don't need to move articles from newsgroup */
664  if (m->type == MUTT_NNTP)
665  read_msgs = 0;
666 #endif
667 
668  const enum QuadOption c_move = cs_subset_quad(NeoMutt->sub, "move");
669  if ((read_msgs != 0) && (c_move != MUTT_NO))
670  {
671  bool is_spool;
672  mbox = mutt_buffer_pool_get();
673 
675  if (p)
676  {
677  is_spool = true;
678  mutt_buffer_strcpy(mbox, p);
679  }
680  else
681  {
682  const char *const c_mbox = cs_subset_string(NeoMutt->sub, "mbox");
683  mutt_buffer_strcpy(mbox, c_mbox);
684  is_spool = mutt_is_spool(mailbox_path(m)) &&
686  }
687 
688  if (is_spool && !mutt_buffer_is_empty(mbox))
689  {
691  mutt_buffer_printf(buf,
692  /* L10N: The first argument is the number of read messages to be
693  moved, the second argument is the target mailbox. */
694  ngettext("Move %d read message to %s?",
695  "Move %d read messages to %s?", read_msgs),
696  read_msgs, mutt_buffer_string(mbox));
697  move_messages = query_quadoption(c_move, mutt_buffer_string(buf));
698  if (move_messages == MUTT_ABORT)
699  goto cleanup;
700  }
701  }
702 
703  /* There is no point in asking whether or not to purge if we are
704  * just marking messages as "trash". */
705  const bool c_maildir_trash = cs_subset_bool(NeoMutt->sub, "maildir_trash");
706  if ((m->msg_deleted != 0) && !((m->type == MUTT_MAILDIR) && c_maildir_trash))
707  {
708  mutt_buffer_printf(buf,
709  ngettext("Purge %d deleted message?",
710  "Purge %d deleted messages?", m->msg_deleted),
711  m->msg_deleted);
712  const enum QuadOption c_delete = cs_subset_quad(NeoMutt->sub, "delete");
713  purge = query_quadoption(c_delete, mutt_buffer_string(buf));
714  if (purge == MUTT_ABORT)
715  goto cleanup;
716  }
717 
718  const bool c_mark_old = cs_subset_bool(NeoMutt->sub, "mark_old");
719  if (c_mark_old && !m->peekonly)
720  {
721  for (i = 0; i < m->msg_count; i++)
722  {
723  struct Email *e = m->emails[i];
724  if (!e)
725  break;
726  if (!e->deleted && !e->old && !e->read)
727  mutt_set_flag(m, e, MUTT_OLD, true);
728  }
729  }
730 
731  if (move_messages)
732  {
733  if (m->verbose)
734  mutt_message(_("Moving read messages to %s..."), mutt_buffer_string(mbox));
735 
736 #ifdef USE_IMAP
737  /* try to use server-side copy first */
738  i = 1;
739 
740  if ((m->type == MUTT_IMAP) && (imap_path_probe(mutt_buffer_string(mbox), NULL) == MUTT_IMAP))
741  {
742  /* add messages for moving, and clear old tags, if any */
743  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
744  for (i = 0; i < m->msg_count; i++)
745  {
746  struct Email *e = m->emails[i];
747  if (!e)
748  break;
749 
750  if (e->read && !e->deleted && !(e->flagged && c_keep_flagged))
751  {
752  e->tagged = true;
753  emaillist_add_email(&el, e);
754  }
755  else
756  e->tagged = false;
757  }
758 
759  i = imap_copy_messages(m, &el, mutt_buffer_string(mbox), SAVE_MOVE);
760  emaillist_clear(&el);
761  }
762 
763  if (i == 0) /* success */
765  else if (i == -1) /* horrible error, bail */
766  goto cleanup;
767  else /* use regular append-copy mode */
768 #endif
769  {
770  struct Mailbox *m_read = mx_path_resolve(mutt_buffer_string(mbox));
771  if (!mx_mbox_open(m_read, MUTT_APPEND))
772  {
773  mailbox_free(&m_read);
774  goto cleanup;
775  }
776 
777  for (i = 0; i < m->msg_count; i++)
778  {
779  struct Email *e = m->emails[i];
780  if (!e)
781  break;
782  if (e->read && !e->deleted && !(e->flagged && c_keep_flagged))
783  {
784  if (mutt_append_message(m_read, m, e, NULL, MUTT_CM_NO_FLAGS, CH_UPDATE_LEN) == 0)
785  {
786  mutt_set_flag(m, e, MUTT_DELETE, true);
787  mutt_set_flag(m, e, MUTT_PURGE, true);
788  }
789  else
790  {
791  mx_mbox_close(m_read);
792  goto cleanup;
793  }
794  }
795  }
796 
797  mx_mbox_close(m_read);
798  }
799  }
800  else if (!m->changed && (m->msg_deleted == 0))
801  {
802  if (m->verbose)
803  mutt_message(_("Mailbox is unchanged"));
804  if ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF))
805  mbox_reset_atime(m, NULL);
807  rc = MX_STATUS_OK;
808  goto cleanup;
809  }
810 
811  /* copy mails to the trash before expunging */
812  const char *const c_trash = cs_subset_string(NeoMutt->sub, "trash");
813  const struct Mailbox *m_trash = mx_mbox_find(m->account, c_trash);
814  if (purge && (m->msg_deleted != 0) && (m != m_trash))
815  {
816  if (trash_append(m) != 0)
817  goto cleanup;
818  }
819 
820 #ifdef USE_IMAP
821  /* allow IMAP to preserve the deleted flag across sessions */
822  if (m->type == MUTT_IMAP)
823  {
824  const enum MxStatus check = imap_sync_mailbox(m, (purge != MUTT_NO), true);
825  if (check == MX_STATUS_ERROR)
826  {
827  rc = check;
828  goto cleanup;
829  }
830  }
831  else
832 #endif
833  {
834  if (purge == MUTT_NO)
835  {
836  for (i = 0; i < m->msg_count; i++)
837  {
838  struct Email *e = m->emails[i];
839  if (!e)
840  break;
841 
842  e->deleted = false;
843  e->purge = false;
844  }
845  m->msg_deleted = 0;
846  }
847 
848  if (m->changed || (m->msg_deleted != 0))
849  {
850  enum MxStatus check = sync_mailbox(m);
851  if (check != MX_STATUS_OK)
852  {
853  rc = check;
854  goto cleanup;
855  }
856  }
857  }
858 
859  if (m->verbose)
860  {
861  if (move_messages)
862  {
863  mutt_message(_("%d kept, %d moved, %d deleted"),
864  m->msg_count - m->msg_deleted, read_msgs, m->msg_deleted);
865  }
866  else
867  mutt_message(_("%d kept, %d deleted"), m->msg_count - m->msg_deleted, m->msg_deleted);
868  }
869 
870  const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
871  if ((m->msg_count == m->msg_deleted) &&
872  ((m->type == MUTT_MMDF) || (m->type == MUTT_MBOX)) &&
873  !mutt_is_spool(mailbox_path(m)) && !c_save_empty)
874  {
876  }
877 
878 #ifdef USE_SIDEBAR
879  if ((purge == MUTT_YES) && (m->msg_deleted != 0))
880  {
881  for (i = 0; i < m->msg_count; i++)
882  {
883  struct Email *e = m->emails[i];
884  if (!e)
885  break;
886  if (e->deleted && !e->read)
887  {
888  m->msg_unread--;
889  if (!e->old)
890  m->msg_new--;
891  }
892  if (e->deleted && e->flagged)
893  m->msg_flagged--;
894  }
895  }
896 #endif
897 
899 
900  rc = MX_STATUS_OK;
901 
902 cleanup:
905  return rc;
906 }
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:206
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
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2400
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
void mbox_reset_atime(struct Mailbox *m, struct stat *st)
Reset the access time on the mailbox file.
Definition: mbox.c:833
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
static int trash_append(struct Mailbox *m)
move deleted mails to the trash folder
Definition: mx.c:501
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:117
enum MxStatus imap_sync_mailbox(struct Mailbox *m, bool expunge, bool close)
Sync all the changes to the server.
Definition: imap.c:1531
struct NntpAccountData * adata
Definition: mdata.h:47
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
int mutt_append_message(struct Mailbox *m_dst, struct Mailbox *m_src, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:916
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1577
Messages to be purged (bypass trash)
Definition: mutt.h:96
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mxapi.h:62
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:137
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:609
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:36
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
int imap_copy_messages(struct Mailbox *m, struct EmailList *el, const char *dest, enum MessageSaveOpt save_opt)
Server COPY messages to another folder.
Definition: message.c:1629
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
static enum MxStatus sync_mailbox(struct Mailbox *m)
save changes to disk
Definition: mx.c:470
bool old
Email is seen, but unread.
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
void mutt_file_unlink_empty(const char *path)
Delete a file if it&#39;s empty.
Definition: file.c:1314
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:428
char * group
Definition: mdata.h:34
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
User aborted the question (with Ctrl-G)
Definition: quad.h:37
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:40
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
Old messages.
Definition: mutt.h:90
Messages to be deleted.
Definition: mutt.h:94
A mailbox.
Definition: mailbox.h:81
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition: hook.c:577
No changes.
Definition: mxapi.h:78
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
bool verbose
Display status messages?
Definition: mailbox.h:118
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:62
bool purge
Skip trash folder when deleting.
Definition: email.h:46
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:158
NNTP-specific Mailbox data -.
Definition: mdata.h:32
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:204
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:513
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:321
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
Move message to another mailbox, removing the original.
Definition: commands.h:52
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
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1667
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1308
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
static bool mutt_is_spool(const char *str)
Is this the spool_file?
Definition: mx.c:154
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_sync()

enum MxStatus mx_mbox_sync ( struct Mailbox m)

Save changes to mailbox.

Parameters
[in]mMailbox
Return values
enumMxStatus
Note
The flag retvals come from a call to a backend sync function

Definition at line 915 of file mx.c.

916 {
917  if (!m)
918  return MX_STATUS_ERROR;
919 
920  enum MxStatus rc = MX_STATUS_OK;
921  int purge = 1;
922  int msgcount, deleted;
923 
924  if (m->dontwrite)
925  {
926  char buf[256], tmp[256];
927  if (km_expand_key(buf, sizeof(buf), km_find_func(MENU_MAIN, OP_TOGGLE_WRITE)))
928  snprintf(tmp, sizeof(tmp), _(" Press '%s' to toggle write"), buf);
929  else
930  mutt_str_copy(tmp, _("Use 'toggle-write' to re-enable write"), sizeof(tmp));
931 
932  mutt_error(_("Mailbox is marked unwritable. %s"), tmp);
933  return MX_STATUS_ERROR;
934  }
935  else if (m->readonly)
936  {
937  mutt_error(_("Mailbox is read-only"));
938  return MX_STATUS_ERROR;
939  }
940 
941  if (!m->changed && (m->msg_deleted == 0))
942  {
943  if (m->verbose)
944  mutt_message(_("Mailbox is unchanged"));
945  return MX_STATUS_OK;
946  }
947 
948  if (m->msg_deleted != 0)
949  {
950  char buf[128];
951 
952  snprintf(buf, sizeof(buf),
953  ngettext("Purge %d deleted message?", "Purge %d deleted messages?", m->msg_deleted),
954  m->msg_deleted);
955  const enum QuadOption c_delete = cs_subset_quad(NeoMutt->sub, "delete");
956  purge = query_quadoption(c_delete, buf);
957  if (purge == MUTT_ABORT)
958  return MX_STATUS_ERROR;
959  if (purge == MUTT_NO)
960  {
961  if (!m->changed)
962  return MX_STATUS_OK; /* nothing to do! */
963  /* let IMAP servers hold on to D flags */
964  if (m->type != MUTT_IMAP)
965  {
966  for (int i = 0; i < m->msg_count; i++)
967  {
968  struct Email *e = m->emails[i];
969  if (!e)
970  break;
971  e->deleted = false;
972  e->purge = false;
973  }
974  m->msg_deleted = 0;
975  }
976  }
978  }
979 
980  /* really only for IMAP - imap_sync_mailbox results in a call to
981  * ctx_update_tables, so m->msg_deleted is 0 when it comes back */
982  msgcount = m->msg_count;
983  deleted = m->msg_deleted;
984 
985  const char *const c_trash = cs_subset_string(NeoMutt->sub, "trash");
986  const struct Mailbox *m_trash = mx_mbox_find(m->account, c_trash);
987  if (purge && (m->msg_deleted != 0) && (m != m_trash))
988  {
989  if (trash_append(m) != 0)
990  return MX_STATUS_OK;
991  }
992 
993 #ifdef USE_IMAP
994  if (m->type == MUTT_IMAP)
995  rc = imap_sync_mailbox(m, purge, false);
996  else
997 #endif
998  rc = sync_mailbox(m);
999  if (rc != MX_STATUS_ERROR)
1000  {
1001 #ifdef USE_IMAP
1002  if ((m->type == MUTT_IMAP) && !purge)
1003  {
1004  if (m->verbose)
1005  mutt_message(_("Mailbox checkpointed"));
1006  }
1007  else
1008 #endif
1009  {
1010  if (m->verbose)
1011  mutt_message(_("%d kept, %d deleted"), msgcount - deleted, deleted);
1012  }
1013 
1014  mutt_sleep(0);
1015 
1016  const bool c_save_empty = cs_subset_bool(NeoMutt->sub, "save_empty");
1017  if ((m->msg_count == m->msg_deleted) &&
1018  ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) &&
1019  !mutt_is_spool(mailbox_path(m)) && !c_save_empty)
1020  {
1021  unlink(mailbox_path(m));
1023  return MX_STATUS_OK;
1024  }
1025 
1026  /* if we haven't deleted any messages, we don't need to resort
1027  * ... except for certain folder formats which need "unsorted"
1028  * sort order in order to synchronize folders.
1029  *
1030  * MH and maildir are safe. mbox-style seems to need re-sorting,
1031  * at least with the new threading code. */
1032  if (purge || ((m->type != MUTT_MAILDIR) && (m->type != MUTT_MH)))
1033  {
1034  /* IMAP does this automatically after handling EXPUNGE */
1035  if (m->type != MUTT_IMAP)
1036  {
1039  }
1040  }
1041  }
1042 
1043  return rc;
1044 }
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:206
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
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:71
The envelope/body of an email.
Definition: email.h:37
Clear the &#39;last-tagged&#39; pointer.
Definition: mailbox.h:177
Update internal tables.
Definition: mailbox.h:176
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
#define mutt_message(...)
Definition: logging.h:83
static int trash_append(struct Mailbox *m)
move deleted mails to the trash folder
Definition: mx.c:501
enum MxStatus imap_sync_mailbox(struct Mailbox *m, bool expunge, bool close)
Sync all the changes to the server.
Definition: imap.c:1531
#define _(a)
Definition: message.h:28
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1577
Index panel (list of emails)
Definition: keymap.h:80
Container for Accounts, Notifications.
Definition: neomutt.h:36
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
static enum MxStatus sync_mailbox(struct Mailbox *m)
save changes to disk
Definition: mx.c:470
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:428
User aborted the question (with Ctrl-G)
Definition: quad.h:37
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
struct Keymap * km_find_func(enum MenuType menu, int func)
Find a function&#39;s mapping in a Menu.
Definition: keymap.c:949
Email list needs resorting.
Definition: mailbox.h:174
A mailbox.
Definition: mailbox.h:81
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:921
No changes.
Definition: mxapi.h:78
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
bool verbose
Display status messages?
Definition: mailbox.h:118
bool purge
Skip trash folder when deleting.
Definition: email.h:46
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:204
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:513
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
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:716
bool deleted
Email is deleted.
Definition: email.h:45
#define mutt_error(...)
Definition: logging.h:84
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:186
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
static bool mutt_is_spool(const char *str)
Is this the spool_file?
Definition: mx.c:154
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_msg_open_new()

struct Message* mx_msg_open_new ( struct Mailbox m,
const struct Email e,
MsgOpenFlags  flags 
)

Open a new message.

Parameters
mDestination mailbox
eMessage being copied (required for maildir support, because the filename depends on the message flags)
flagsFlags, see MsgOpenFlags
Return values
ptrNew Message

Definition at line 1053 of file mx.c.

1054 {
1055  if (!m)
1056  return NULL;
1057 
1058  struct Address *p = NULL;
1059  struct Message *msg = NULL;
1060 
1061  if (!m->mx_ops || !m->mx_ops->msg_open_new)
1062  {
1063  mutt_debug(LL_DEBUG1, "function unimplemented for mailbox type %d\n", m->type);
1064  return NULL;
1065  }
1066 
1067  msg = mutt_mem_calloc(1, sizeof(struct Message));
1068  msg->write = true;
1069 
1070  if (e)
1071  {
1072  msg->flags.flagged = e->flagged;
1073  msg->flags.replied = e->replied;
1074  msg->flags.read = e->read;
1075  msg->flags.draft = (flags & MUTT_SET_DRAFT);
1076  msg->received = e->received;
1077  }
1078 
1079  if (msg->received == 0)
1080  msg->received = mutt_date_epoch();
1081 
1082  if (m->mx_ops->msg_open_new(m, msg, e))
1083  {
1084  if (m->type == MUTT_MMDF)
1085  fputs(MMDF_SEP, msg->fp);
1086 
1087  if (((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) && (flags & MUTT_ADD_FROM))
1088  {
1089  if (e)
1090  {
1091  p = TAILQ_FIRST(&e->env->return_path);
1092  if (!p)
1093  p = TAILQ_FIRST(&e->env->sender);
1094  if (!p)
1095  p = TAILQ_FIRST(&e->env->from);
1096  }
1097 
1098  // Force a 'C' locale for the date, so that day/month names are in English
1099  locale_t loc = newlocale(LC_TIME_MASK, "C", 0);
1100  char buf[64] = { 0 };
1101  struct tm tm = mutt_date_localtime(msg->received);
1102  strftime_l(buf, sizeof(buf), "%a %b %e %H:%M:%S %Y", &tm, loc);
1103  freelocale(loc);
1104  fprintf(msg->fp, "From %s %s\n", p ? p->mailbox : NONULL(Username), buf);
1105  }
1106  }
1107  else
1108  FREE(&msg);
1109 
1110  return msg;
1111 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:643
bool replied
Definition: mxapi.h:51
An email address.
Definition: address.h:35
char * mailbox
Mailbox and host address.
Definition: address.h:38
#define MUTT_SET_DRAFT
set the message draft flag
Definition: mx.h:43
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:48
bool read
Email is read.
Definition: email.h:51
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
bool flagged
Definition: mxapi.h:50
A local copy of an email.
Definition: mxapi.h:41
struct Message::@1 flags
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
bool draft
Definition: mxapi.h:52
#define MMDF_SEP
Definition: lib.h:60
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
bool write
nonzero if message is open for writing
Definition: mxapi.h:46
bool(* msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e)
Open a new message in a Mailbox.
Definition: mxapi.h:223
struct AddressList return_path
Return path for the Email.
Definition: envelope.h:56
Log at debug level 1.
Definition: logging.h:40
bool flagged
Marked important?
Definition: email.h:43
bool replied
Email has been replied to.
Definition: email.h:54
FILE * fp
pointer to the message data
Definition: mxapi.h:43
#define FREE(x)
Definition: memory.h:40
time_t received
the time at which this message was received
Definition: mxapi.h:54
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool read
Definition: mxapi.h:49
#define MUTT_ADD_FROM
add a From_ line
Definition: mx.h:42
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:

◆ mx_mbox_check()

enum MxStatus mx_mbox_check ( struct Mailbox m)

Check for new mail - Wrapper for MxOps::mbox_check()

Parameters
mMailbox
Return values
enumMxStatus

Definition at line 1118 of file mx.c.

1119 {
1120  if (!m || !m->mx_ops)
1121  return MX_STATUS_ERROR;
1122 
1123  enum MxStatus rc = m->mx_ops->mbox_check(m);
1124  if ((rc == MX_STATUS_NEW_MAIL) || (rc == MX_STATUS_REOPENED))
1125  {
1127  }
1128 
1129  return rc;
1130 }
New mail received in Mailbox.
Definition: mxapi.h:79
Email list was changed.
Definition: mailbox.h:173
Mailbox was reopened.
Definition: mxapi.h:81
enum MxStatus(* mbox_check)(struct Mailbox *m)
Check for new mail.
Definition: mxapi.h:163
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:186
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
An error occurred.
Definition: mxapi.h:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_msg_open()

struct Message* mx_msg_open ( struct Mailbox m,
int  msgno 
)

return a stream pointer for a message

Parameters
mMailbox
msgnoMessage number
Return values
ptrMessage
NULLError

Definition at line 1139 of file mx.c.

1140 {
1141  if (!m || !m->emails || (msgno < 0) || (msgno >= m->msg_count))
1142  return NULL;
1143 
1144  if (!m->mx_ops || !m->mx_ops->msg_open)
1145  {
1146  mutt_debug(LL_DEBUG1, "function not implemented for mailbox type %d\n", m->type);
1147  return NULL;
1148  }
1149 
1150  struct Message *msg = mutt_mem_calloc(1, sizeof(struct Message));
1151  if (!m->mx_ops->msg_open(m, msg, msgno))
1152  FREE(&msg);
1153 
1154  return msg;
1155 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool(* msg_open)(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox.
Definition: mxapi.h:209
A local copy of an email.
Definition: mxapi.h:41
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_msg_commit()

int mx_msg_commit ( struct Mailbox m,
struct Message msg 
)

Commit a message to a folder - Wrapper for MxOps::msg_commit()

Parameters
mMailbox
msgMessage to commit
Return values
0Success
-1Failure

Definition at line 1164 of file mx.c.

1165 {
1166  if (!m || !m->mx_ops || !m->mx_ops->msg_commit || !msg)
1167  return -1;
1168 
1169  if (!(msg->write && m->append))
1170  {
1171  mutt_debug(LL_DEBUG1, "msg->write = %d, m->append = %d\n", msg->write, m->append);
1172  return -1;
1173  }
1174 
1175  return m->mx_ops->msg_commit(m, msg);
1176 }
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Save changes to an email.
Definition: mxapi.h:236
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
bool write
nonzero if message is open for writing
Definition: mxapi.h:46
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ mx_msg_close()

int mx_msg_close ( struct Mailbox m,
struct Message **  msg 
)

Close a message.

Parameters
[in]mMailbox
[out]msgMessage to close
Return values
0Success
-1Failure

Definition at line 1185 of file mx.c.

1186 {
1187  if (!m || !msg || !*msg)
1188  return 0;
1189 
1190  int rc = 0;
1191 
1192  if (m->mx_ops && m->mx_ops->msg_close)
1193  rc = m->mx_ops->msg_close(m, *msg);
1194 
1195  if ((*msg)->path)
1196  {
1197  mutt_debug(LL_DEBUG1, "unlinking %s\n", (*msg)->path);
1198  unlink((*msg)->path);
1199  FREE(&(*msg)->path);
1200  }
1201 
1202  FREE(&(*msg)->committed_path);
1203  FREE(msg);
1204  return rc;
1205 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:40
int(* msg_close)(struct Mailbox *m, struct Message *msg)
Close an email.
Definition: mxapi.h:249
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ mx_alloc_memory()

void mx_alloc_memory ( struct Mailbox m)

Create storage for the emails.

Parameters
mMailbox

Definition at line 1211 of file mx.c.

1212 {
1213  size_t s = MAX(sizeof(struct Email *), sizeof(int));
1214 
1215  if ((m->email_max + 25) * s < m->email_max * s)
1216  {
1217  mutt_error(_("Out of memory"));
1218  mutt_exit(1);
1219  }
1220 
1221  m->email_max += 25;
1222  if (m->emails)
1223  {
1224  mutt_mem_realloc(&m->emails, sizeof(struct Email *) * m->email_max);
1225  mutt_mem_realloc(&m->v2r, sizeof(int) * m->email_max);
1226  }
1227  else
1228  {
1229  m->emails = mutt_mem_calloc(m->email_max, sizeof(struct Email *));
1230  m->v2r = mutt_mem_calloc(m->email_max, sizeof(int));
1231  }
1232  for (int i = m->email_max - 25; i < m->email_max; i++)
1233  {
1234  m->emails[i] = NULL;
1235  m->v2r[i] = -1;
1236  }
1237 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
The envelope/body of an email.
Definition: email.h:37
#define _(a)
Definition: message.h:28
#define MAX(a, b)
Definition: memory.h:30
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:141
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
#define mutt_error(...)
Definition: logging.h:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_path_is_empty()

int mx_path_is_empty ( const char *  path)

Is the mailbox empty.

Parameters
pathMailbox to check
Return values
1Mailbox is empty
0Mailbox contains mail
-1Error

Definition at line 1246 of file mx.c.

1247 {
1248  if (!path || (*path == '\0'))
1249  return -1;
1250 
1251  enum MailboxType type = mx_path_probe(path);
1252  const struct MxOps *ops = mx_get_ops(type);
1253  if (!ops || !ops->path_is_empty)
1254  return -1;
1255 
1256  return ops->path_is_empty(path);
1257 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
int(* path_is_empty)(const char *path)
Is the Mailbox empty?
Definition: mxapi.h:363
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1316
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
char * path
path to temp file
Definition: mxapi.h:44
The Mailbox API.
Definition: mxapi.h:101
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_tags_edit()

int mx_tags_edit ( struct Mailbox m,
const char *  tags,
char *  buf,
size_t  buflen 
)

start the tag editor of the mailbox

Parameters
mMailbox
tagsExisting tags
bufBuffer for the results
buflenLength of the buffer
Return values
-1Error
0No valid user input
1Buffer set

Definition at line 1269 of file mx.c.

1270 {
1271  if (!m || !buf)
1272  return -1;
1273 
1274  if (m->mx_ops->tags_edit)
1275  return m->mx_ops->tags_edit(m, tags, buf, buflen);
1276 
1277  mutt_message(_("Folder doesn't support tagging, aborting"));
1278  return -1;
1279 }
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mxapi.h:288
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ Here is the caller graph for this function:

◆ mx_tags_commit()

int mx_tags_commit ( struct Mailbox m,
struct Email e,
char *  tags 
)

Save tags to the Mailbox - Wrapper for MxOps::tags_commit()

Parameters
mMailbox
eEmail
tagsTags to save
Return values
0Success
-1Failure

Definition at line 1289 of file mx.c.

1290 {
1291  if (!m || !e || !tags)
1292  return -1;
1293 
1294  if (m->mx_ops->tags_commit)
1295  return m->mx_ops->tags_commit(m, e, tags);
1296 
1297  mutt_message(_("Folder doesn't support tagging, aborting"));
1298  return -1;
1299 }
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
int(* tags_commit)(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message.
Definition: mxapi.h:303
+ Here is the caller graph for this function:

◆ mx_tags_is_supported()

bool mx_tags_is_supported ( struct Mailbox m)

return true if mailbox support tagging

Parameters
mMailbox
Return values
trueTagging is supported

Definition at line 1306 of file mx.c.

1307 {
1308  return m && m->mx_ops->tags_commit && m->mx_ops->tags_edit;
1309 }
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mxapi.h:288
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
int(* tags_commit)(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message.
Definition: mxapi.h:303
+ Here is the caller graph for this function:

◆ mx_path_probe()

enum MailboxType mx_path_probe ( const char *  path)

Find a mailbox that understands a path.

Parameters
pathPath to examine
Return values
numType, e.g. MUTT_IMAP

Definition at line 1316 of file mx.c.

1317 {
1318  if (!path)
1319  return MUTT_UNKNOWN;
1320 
1321  enum MailboxType rc = MUTT_UNKNOWN;
1322 
1323  // First, search the non-local Mailbox types (is_local == false)
1324  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1325  {
1326  if ((*ops)->is_local)
1327  continue;
1328  rc = (*ops)->path_probe(path, NULL);
1329  if (rc != MUTT_UNKNOWN)
1330  return rc;
1331  }
1332 
1333  struct stat st = { 0 };
1334  if (stat(path, &st) != 0)
1335  {
1336  mutt_debug(LL_DEBUG1, "unable to stat %s: %s (errno %d)\n", path, strerror(errno), errno);
1337  return MUTT_UNKNOWN;
1338  }
1339 
1340  if (S_ISFIFO(st.st_mode))
1341  {
1342  mutt_error(_("Can't open %s: it is a pipe"), path);
1343  return MUTT_UNKNOWN;
1344  }
1345 
1346  // Next, search the local Mailbox types (is_local == true)
1347  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1348  {
1349  if (!(*ops)->is_local)
1350  continue;
1351  rc = (*ops)->path_probe(path, &st);
1352  if (rc != MUTT_UNKNOWN)
1353  return rc;
1354  }
1355 
1356  return rc;
1357 }
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
const struct MxOps * mx_ops[]
All the Mailbox backends.
Definition: mx.c:106
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
The Mailbox API.
Definition: mxapi.h:101
+ Here is the caller graph for this function:

◆ mx_path_canon()

int mx_path_canon ( char *  buf,
size_t  buflen,
const char *  folder,
enum MailboxType type 
)

Canonicalise a mailbox path - Wrapper for MxOps::path_canon()

Definition at line 1362 of file mx.c.

1363 {
1364  if (!buf)
1365  return -1;
1366 
1367  for (size_t i = 0; i < 3; i++)
1368  {
1369  /* Look for !! ! - < > or ^ followed by / or NUL */
1370  if ((buf[0] == '!') && (buf[1] == '!'))
1371  {
1372  if (((buf[2] == '/') || (buf[2] == '\0')))
1373  {
1374  mutt_str_inline_replace(buf, buflen, 2, LastFolder);
1375  }
1376  }
1377  else if ((buf[0] == '+') || (buf[0] == '='))
1378  {
1379  size_t folder_len = mutt_str_len(folder);
1380  if ((folder_len > 0) && (folder[folder_len - 1] != '/'))
1381  {
1382  buf[0] = '/';
1383  mutt_str_inline_replace(buf, buflen, 0, folder);
1384  }
1385  else
1386  {
1387  mutt_str_inline_replace(buf, buflen, 1, folder);
1388  }
1389  }
1390  else if ((buf[1] == '/') || (buf[1] == '\0'))
1391  {
1392  if (buf[0] == '!')
1393  {
1394  const char *const c_spool_file =
1395  cs_subset_string(NeoMutt->sub, "spool_file");
1396  mutt_str_inline_replace(buf, buflen, 1, c_spool_file);
1397  }
1398  else if (buf[0] == '-')
1399  {
1400  mutt_str_inline_replace(buf, buflen, 1, LastFolder);
1401  }
1402  else if (buf[0] == '<')
1403  {
1404  const char *const c_record = cs_subset_string(NeoMutt->sub, "record");
1405  mutt_str_inline_replace(buf, buflen, 1, c_record);
1406  }
1407  else if (buf[0] == '>')
1408  {
1409  const char *const c_mbox = cs_subset_string(NeoMutt->sub, "mbox");
1410  mutt_str_inline_replace(buf, buflen, 1, c_mbox);
1411  }
1412  else if (buf[0] == '^')
1413  {
1414  mutt_str_inline_replace(buf, buflen, 1, CurrentFolder);
1415  }
1416  else if (buf[0] == '~')
1417  {
1418  mutt_str_inline_replace(buf, buflen, 1, HomeDir);
1419  }
1420  }
1421  else if (buf[0] == '@')
1422  {
1423  /* elm compatibility, @ expands alias to user name */
1424  struct AddressList *al = alias_lookup(buf + 1);
1425  if (!al || TAILQ_EMPTY(al))
1426  break;
1427 
1428  struct Email *e = email_new();
1429  e->env = mutt_env_new();
1430  mutt_addrlist_copy(&e->env->from, al, false);
1431  mutt_addrlist_copy(&e->env->to, al, false);
1432  mutt_default_save(buf, buflen, e);
1433  email_free(&e);
1434  break;
1435  }
1436  else
1437  {
1438  break;
1439  }
1440  }
1441 
1442  // if (!folder) //XXX - use inherited version, or pass NULL to backend?
1443  // return -1;
1444 
1445  enum MailboxType type2 = mx_path_probe(buf);
1446  if (type)
1447  *type = type2;
1448  const struct MxOps *ops = mx_get_ops(type2);
1449  if (!ops || !ops->path_canon)
1450  return -1;
1451 
1452  if (ops->path_canon(buf, buflen) < 0)
1453  {
1454  mutt_path_canon(buf, buflen, HomeDir, true);
1455  }
1456 
1457  return 0;
1458 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
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
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:677
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * HomeDir
User&#39;s home directory.
Definition: mutt_globals.h:45
struct Email * email_new(void)
Create a new Email.
Definition: email.c:77
int(* path_canon)(char *buf, size_t buflen)
Canonicalise a Mailbox path.
Definition: mxapi.h:326
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:281
struct Envelope * env
Envelope information.
Definition: email.h:90
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:51
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1316
bool mutt_path_canon(char *buf, size_t buflen, const char *homedir, bool is_dir)
Create the canonical version of a path.
Definition: path.c:285
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:50
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool mutt_str_inline_replace(char *buf, size_t buflen, size_t xlen, const char *rstr)
Replace the beginning of a string.
Definition: string.c:1013
#define TAILQ_EMPTY(head)
Definition: queue.h:714
The Mailbox API.
Definition: mxapi.h:101
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_path_canon2()

int mx_path_canon2 ( struct Mailbox m,
const char *  folder 
)

Canonicalise the path to realpath.

Parameters
mMailbox
folderPath to canonicalise
Return values
0Success
-1Failure

Definition at line 1467 of file mx.c.

1468 {
1469  if (!m)
1470  return -1;
1471 
1472  char buf[PATH_MAX];
1473 
1474  if (m->realpath)
1475  mutt_str_copy(buf, m->realpath, sizeof(buf));
1476  else
1477  mutt_str_copy(buf, mailbox_path(m), sizeof(buf));
1478 
1479  int rc = mx_path_canon(buf, sizeof(buf), folder, &m->type);
1480 
1481  mutt_str_replace(&m->realpath, buf);
1482 
1483  if (rc >= 0)
1484  {
1485  m->mx_ops = mx_get_ops(m->type);
1487  }
1488 
1489  return rc;
1490 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:206
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
#define PATH_MAX
Definition: mutt.h:40
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
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:716
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
struct Buffer pathbuf
Definition: mailbox.h:83
int mx_path_canon(char *buf, size_t buflen, const char *folder, enum MailboxType *type)
Canonicalise a mailbox path - Wrapper for MxOps::path_canon()
Definition: mx.c:1362
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_path_pretty()

int mx_path_pretty ( char *  buf,
size_t  buflen,
const char *  folder 
)

Abbreviate a mailbox path - Wrapper for MxOps::path_pretty()

Definition at line 1495 of file mx.c.

1496 {
1497  if (!buf)
1498  return -1;
1499 
1500  enum MailboxType type = mx_path_probe(buf);
1501  const struct MxOps *ops = mx_get_ops(type);
1502  if (!ops)
1503  return -1;
1504 
1505  if (!ops->path_canon)
1506  return -1;
1507 
1508  if (ops->path_canon(buf, buflen) < 0)
1509  return -1;
1510 
1511  if (!ops->path_pretty)
1512  return -1;
1513 
1514  if (ops->path_pretty(buf, buflen, folder) < 0)
1515  return -1;
1516 
1517  return 0;
1518 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:140
int(* path_canon)(char *buf, size_t buflen)
Canonicalise a Mailbox path.
Definition: mxapi.h:326
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mxapi.h:103
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1316
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
int(* path_pretty)(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path.
Definition: mxapi.h:339
The Mailbox API.
Definition: mxapi.h:101
+ Here is the call graph for this function:

◆ mx_path_parent()

int mx_path_parent ( char *  buf,
size_t  buflen 
)

Find the parent of a mailbox path - Wrapper for MxOps::path_parent()

Definition at line 1523 of file mx.c.

1524 {
1525  if (!buf)
1526  return -1;
1527 
1528  return 0;
1529 }

◆ mx_msg_padding_size()

int mx_msg_padding_size ( struct Mailbox m)

Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()

Parameters
mMailbox
Return values
numNumber of bytes of padding

mmdf and mbox add separators, which leads a small discrepancy when computing vsize for a limited view.

Definition at line 1539 of file mx.c.

1540 {
1541  if (!m || !m->mx_ops || !m->mx_ops->msg_padding_size)
1542  return 0;
1543 
1544  return m->mx_ops->msg_padding_size(m);
1545 }
int(* msg_padding_size)(struct Mailbox *m)
Bytes of padding between messages.
Definition: mxapi.h:259
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ Here is the caller graph for this function:

◆ mx_ac_find()

struct Account* mx_ac_find ( struct Mailbox m)

Find the Account owning a Mailbox.

Parameters
mMailbox
Return values
ptrAccount
NULLNone found

Definition at line 1553 of file mx.c.

1554 {
1555  if (!m || !m->mx_ops || !m->realpath)
1556  return NULL;
1557 
1558  struct Account *np = NULL;
1559  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1560  {
1561  if (np->type != m->type)
1562  continue;
1563 
1564  if (m->mx_ops->ac_owns_path(np, m->realpath))
1565  return np;
1566  }
1567 
1568  return NULL;
1569 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
A group of associated Mailboxes.
Definition: account.h:36
bool(* ac_owns_path)(struct Account *a, const char *path)
Check whether an Account owns a Mailbox path.
Definition: mxapi.h:118
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ Here is the caller graph for this function:

◆ mx_mbox_find()

struct Mailbox* mx_mbox_find ( struct Account a,
const char *  path 
)

Find a Mailbox on an Account.

Parameters
aAccount to search
pathPath to find
Return values
ptrMailbox

Definition at line 1577 of file mx.c.

1578 {
1579  if (!a || !path)
1580  return NULL;
1581 
1582  struct MailboxNode *np = NULL;
1583  struct Url *url_p = NULL;
1584  struct Url *url_a = NULL;
1585 
1586  const bool use_url = (a->type == MUTT_IMAP);
1587  if (use_url)
1588  {
1589  url_p = url_parse(path);
1590  if (!url_p)
1591  goto done;
1592  }
1593 
1594  STAILQ_FOREACH(np, &a->mailboxes, entries)
1595  {
1596  if (!use_url)
1597  {
1598  if (mutt_str_equal(np->mailbox->realpath, path))
1599  return np->mailbox;
1600  continue;
1601  }
1602 
1603  url_free(&url_a);
1604  url_a = url_parse(np->mailbox->realpath);
1605  if (!url_a)
1606  continue;
1607 
1608  if (!mutt_istr_equal(url_a->host, url_p->host))
1609  continue;
1610  if (url_p->user && !mutt_istr_equal(url_a->user, url_p->user))
1611  continue;
1612  if (a->type == MUTT_IMAP)
1613  {
1614  if (imap_mxcmp(url_a->path, url_p->path) == 0)
1615  break;
1616  }
1617  else
1618  {
1619  if (mutt_str_equal(url_a->path, url_p->path))
1620  break;
1621  }
1622  }
1623 
1624 done:
1625  url_free(&url_p);
1626  url_free(&url_a);
1627 
1628  if (!np)
1629  return NULL;
1630  return np->mailbox;
1631 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
struct MailboxList mailboxes
List of Mailboxes.
Definition: account.h:41
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:554
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
char * user
Username.
Definition: url.h:71
char * host
Host.
Definition: url.h:73
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * path
Path.
Definition: url.h:75
List of Mailboxes.
Definition: mailbox.h:152
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_find2()

struct Mailbox* mx_mbox_find2 ( const char *  path)

Find a Mailbox on an Account.

Parameters
pathPath to find
Return values
ptrMailbox
NULLNo match

Definition at line 1639 of file mx.c.

1640 {
1641  if (!path)
1642  return NULL;
1643 
1644  char buf[PATH_MAX];
1645  mutt_str_copy(buf, path, sizeof(buf));
1646  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1647  mx_path_canon(buf, sizeof(buf), c_folder, NULL);
1648 
1649  struct Account *np = NULL;
1650  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1651  {
1652  struct Mailbox *m = mx_mbox_find(np, buf);
1653  if (m)
1654  return m;
1655  }
1656 
1657  return NULL;
1658 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
A group of associated Mailboxes.
Definition: account.h:36
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1577
Container for Accounts, Notifications.
Definition: neomutt.h:36
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:40
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
char * path
Path.
Definition: url.h:75
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:716
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mx_path_canon(char *buf, size_t buflen, const char *folder, enum MailboxType *type)
Canonicalise a mailbox path - Wrapper for MxOps::path_canon()
Definition: mx.c:1362
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_path_resolve()

struct Mailbox* mx_path_resolve ( const char *  path)

Get a Mailbox for a path.

Parameters
pathMailbox path
Return values
ptrMailbox

If there isn't a Mailbox for the path, one will be created.

Definition at line 1667 of file mx.c.

1668 {
1669  if (!path)
1670  return NULL;
1671 
1672  struct Mailbox *m = mx_mbox_find2(path);
1673  if (m)
1674  return m;
1675 
1676  m = mailbox_new();
1677  m->flags = MB_HIDDEN;
1678  mutt_buffer_strcpy(&m->pathbuf, path);
1679  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1680  mx_path_canon2(m, c_folder);
1681 
1682  return m;
1683 }
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1467
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1639
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MB_HIDDEN
Definition: mailbox.h:38
A mailbox.
Definition: mailbox.h:81
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:52
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Buffer pathbuf
Definition: mailbox.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_find_by_name_ac()

static struct Mailbox* mx_mbox_find_by_name_ac ( struct Account a,
const char *  name 
)
static

Find a Mailbox with given name under an Account.

Parameters
aAccount to search
nameName to find
Return values
ptrMailbox

Definition at line 1691 of file mx.c.

1692 {
1693  if (!a || !name)
1694  return NULL;
1695 
1696  struct MailboxNode *np = NULL;
1697 
1698  STAILQ_FOREACH(np, &a->mailboxes, entries)
1699  {
1700  if (mutt_str_equal(np->mailbox->name, name))
1701  return np->mailbox;
1702  }
1703 
1704  return NULL;
1705 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
struct MailboxList mailboxes
List of Mailboxes.
Definition: account.h:41
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
List of Mailboxes.
Definition: mailbox.h:152
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_find_by_name()

static struct Mailbox* mx_mbox_find_by_name ( const char *  name)
static

Find a Mailbox with given name.

Parameters
nameName to search
Return values
ptrMailbox

Definition at line 1712 of file mx.c.

1713 {
1714  if (!name)
1715  return NULL;
1716 
1717  struct Account *np = NULL;
1718  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1719  {
1720  struct Mailbox *m = mx_mbox_find_by_name_ac(np, name);
1721  if (m)
1722  return m;
1723  }
1724 
1725  return NULL;
1726 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
A group of associated Mailboxes.
Definition: account.h:36
static struct Mailbox * mx_mbox_find_by_name_ac(struct Account *a, const char *name)
Find a Mailbox with given name under an Account.
Definition: mx.c:1691
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
A mailbox.
Definition: mailbox.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_resolve()

struct Mailbox* mx_resolve ( const char *  path_or_name)

Get a Mailbox from either a path or name.

Parameters
path_or_nameMailbox path or name
Return values
ptrMailbox

Order of resolving:

  1. Name
  2. Path

Definition at line 1737 of file mx.c.

1738 {
1739  if (!path_or_name)
1740  return NULL;
1741 
1742  // Order is name first because you can create a Mailbox from
1743  // a path, but can't from a name. So fallback behavior creates
1744  // a new Mailbox for us.
1745  struct Mailbox *m = mx_mbox_find_by_name(path_or_name);
1746  if (!m)
1747  m = mx_path_resolve(path_or_name);
1748 
1749  return m;
1750 }
static struct Mailbox * mx_mbox_find_by_name(const char *name)
Find a Mailbox with given name.
Definition: mx.c:1712
A mailbox.
Definition: mailbox.h:81
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1667
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_ac_add()

bool mx_ac_add ( struct Account a,
struct Mailbox m 
)

Add a Mailbox to an Account - Wrapper for MxOps::ac_add()

Definition at line 1755 of file mx.c.

1756 {
1757  if (!a || !m || !m->mx_ops || !m->mx_ops->ac_add)
1758  return false;
1759 
1760  return m->mx_ops->ac_add(a, m) && account_mailbox_add(a, m);
1761 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
bool account_mailbox_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account.
Definition: account.c:65
bool(* ac_add)(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account.
Definition: mxapi.h:131
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_ac_remove()

int mx_ac_remove ( struct Mailbox m)

Remove a Mailbox from an Account and delete Account if empty.

Parameters
mMailbox to remove
Note
The mailbox is NOT free'd

Definition at line 1768 of file mx.c.

1769 {
1770  if (!m || !m->account)
1771  return -1;
1772 
1773  struct Account *a = m->account;
1775  if (STAILQ_EMPTY(&a->mailboxes))
1776  {
1778  }
1779  return 0;
1780 }
struct MailboxList mailboxes
List of Mailboxes.
Definition: account.h:41
A group of associated Mailboxes.
Definition: account.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:93
#define STAILQ_EMPTY(head)
Definition: queue.h:345
bool neomutt_account_remove(struct NeoMutt *n, struct Account *a)
Remove an Account from the global list.
Definition: neomutt.c:105
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_check_stats()

enum MxStatus mx_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)

Check the statistics for a mailbox - Wrapper for MxOps::mbox_check_stats()

Definition at line 1785 of file mx.c.

1786 {
1787  if (!m)
1788  return MX_STATUS_ERROR;
1789 
1790  return m->mx_ops->mbox_check_stats(m, flags);
1791 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
enum MxStatus(* mbox_check_stats)(struct Mailbox *m, uint8_t flags)
Check the Mailbox statistics.
Definition: mxapi.h:174
An error occurred.
Definition: mxapi.h:77
+ Here is the caller graph for this function:

◆ mx_save_hcache()

int mx_save_hcache ( struct Mailbox m,
struct Email e 
)

Save message to the header cache - Wrapper for MxOps::msg_save_hcache()

Parameters
mMailbox
eEmail
Return values
0Success
-1Failure

Write a single header out to the header cache.

Definition at line 1802 of file mx.c.

1803 {
1804  if (!m || !m->mx_ops || !m->mx_ops->msg_save_hcache || !e)
1805  return 0;
1806 
1807  return m->mx_ops->msg_save_hcache(m, e);
1808 }
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Save message to the header cache.
Definition: mxapi.h:272
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ Here is the caller graph for this function:

◆ mx_type()

enum MailboxType mx_type ( struct Mailbox m)

Return the type of the Mailbox.

Parameters
mMailbox
Return values
enumMailboxType

Definition at line 1815 of file mx.c.

1816 {
1817  return m ? m->type : MUTT_MAILBOX_ERROR;
1818 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
Error occurred examining Mailbox.
Definition: mailbox.h:46
+ Here is the caller graph for this function:

Variable Documentation

◆ MboxTypeMap

struct Mapping MboxTypeMap[]
static
Initial value:
= {
{ "mbox", MUTT_MBOX, },
{ "MMDF", MUTT_MMDF, },
{ "MH", MUTT_MH, },
{ "Maildir", MUTT_MAILDIR, },
{ NULL, 0, },
}
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48

Definition at line 88 of file mx.c.

◆ MboxTypeDef

struct EnumDef MboxTypeDef
Initial value:
= {
"mbox_type",
4,
(struct Mapping *) &MboxTypeMap,
}
static struct Mapping MboxTypeMap[]
Definition: mx.c:88
Mapping between user-readable string and a constant.
Definition: mapping.h:31

Definition at line 97 of file mx.c.

◆ mx_ops

const struct MxOps* mx_ops[]
Initial value:
= {
NULL,
}
struct MxOps MxNotmuchOps
Notmuch Mailbox - Implements MxOps.
Definition: notmuch.c:2552
struct MxOps MxMhOps
MH Mailbox - Implements MxOps.
Definition: mh.c:1237
struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps.
Definition: compress.c:930
struct MxOps MxMaildirOps
Maildir Mailbox - Implements MxOps.
Definition: maildir.c:1637
struct MxOps MxNntpOps
NNTP Mailbox - Implements MxOps.
Definition: nntp.c:2747
struct MxOps MxImapOps
IMAP Mailbox - Implements MxOps.
Definition: imap.c:2487
struct MxOps MxPopOps
POP Mailbox - Implements MxOps.
Definition: pop.c:1199
struct MxOps MxMmdfOps
MMDF Mailbox - Implements MxOps.
Definition: mbox.c:1850
struct MxOps MxMboxOps
Mbox Mailbox - Implements MxOps.
Definition: mbox.c:1820

All the Mailbox backends.

Definition at line 106 of file mx.c.