NeoMutt  2021-02-05
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 <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 "context.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 "sort.h"
#include "compmbox/lib.h"
#include "imap/lib.h"
#include "pop/lib.h"
#include "nntp/lib.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 spoolfile? More...
 
int mx_access (const char *path, int flags)
 Wrapper for access, checks permissions on a given mailbox. More...
 
static int 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...
 
struct Contextmx_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 int 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...
 
int mx_mbox_close (struct Context **ptr)
 Save changes and close mailbox. More...
 
int 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...
 
int 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...
 
int 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...
 
int 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...
 

Variables

bool C_KeepFlagged
 Config: Don't move flagged messages from $spoolfile to $mbox More...
 
unsigned char C_MboxType
 Config: Default type for creating new mailboxes. More...
 
unsigned char C_Move
 Config: Move emails from $spoolfile to $mbox when read. More...
 
char * C_Trash
 Config: Folder to put deleted emails. More...
 
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 141 of file mx.c.

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

◆ mutt_is_spool()

static bool mutt_is_spool ( const char *  str)
static

Is this the spoolfile?

Parameters
strName to check
Return values
trueIt is the spoolfile

Definition at line 155 of file mx.c.

156 {
157  if (mutt_str_equal(str, C_Spoolfile))
158  return true;
159 
160  struct Url *ua = url_parse(str);
161  struct Url *ub = url_parse(C_Spoolfile);
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:67
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:69
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
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:70
char * host
Host.
Definition: url.h:72
char * path
Path.
Definition: url.h:74
WHERE char * C_Spoolfile
Config: Inbox.
Definition: mutt_globals.h:108
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:2367
int imap_access(const char *path)
Check permissions on an IMAP mailbox with a new connection.
Definition: imap.c:470
char * path
Path.
Definition: url.h:74
&#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 int mx_open_mailbox_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a mailbox for appending.

Parameters
mMailbox
flagsFlags, see OpenMailboxFlags
Return values
0Success
-1Failure

Definition at line 200 of file mx.c.

201 {
202  if (!m)
203  return -1;
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 -1;
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 = C_MboxType;
237  flags |= MUTT_APPENDNEW;
238  }
239  else
240  {
242  return -1;
243  }
244  }
245  else
246  return -1;
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 -1;
254 
255  int rc = m->mx_ops->mbox_open_append(m, flags);
256  m->opened++;
257  return rc;
258 }
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:53
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
#define MUTT_APPENDNEW
Set in mx_open_mailbox_append if the mailbox doesn&#39;t exist.
Definition: mx.h:60
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
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
int(* mbox_open_append)(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending.
Definition: mx.h:158
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
unsigned char C_MboxType
Config: Default type for creating new mailboxes.
Definition: mx.c:84
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1336
#define mutt_error(...)
Definition: logging.h:84
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mx.h:56
bool mutt_comp_can_append(struct Mailbox *m)
Can we append to this path?
Definition: compress.c:356
+ 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) < 0)
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
int mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1769
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:1569
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:43
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()

struct Context* mx_mbox_open ( struct Mailbox m,
OpenMailboxFlags  flags 
)

Open a mailbox and parse it.

Parameters
mMailbox to open
flagsFlags, see OpenMailboxFlags
Return values
ptrMailbox context
NULLError

Definition at line 303 of file mx.c.

304 {
305  if (!m)
306  return NULL;
307 
308  struct Context *ctx = ctx_new(m);
309 
310  struct EventContext ev_ctx = { ctx };
311  notify_send(ctx->notify, NT_CONTEXT, NT_CONTEXT_OPEN, &ev_ctx);
312 
313  // If the Mailbox is closed, Context->mailbox must be set to NULL
315 
316  if ((m->type == MUTT_UNKNOWN) && (flags & (MUTT_NEWFOLDER | MUTT_APPEND)))
317  {
318  m->type = C_MboxType;
319  m->mx_ops = mx_get_ops(m->type);
320  }
321 
322  const bool newly_linked_account = !m->account;
323  if (newly_linked_account)
324  {
325  if (!mx_mbox_ac_link(m))
326  {
327  ctx_free(&ctx);
328  return NULL;
329  }
330  }
331 
332  ctx->msg_in_pager = -1;
333  ctx->collapsed = false;
334 
335  m->verbose = !(flags & MUTT_QUIET);
336  if (flags & MUTT_READONLY)
337  m->readonly = true;
338  m->peekonly = (flags & MUTT_PEEK);
339 
340  if (flags & (MUTT_APPEND | MUTT_NEWFOLDER))
341  {
342  if (mx_open_mailbox_append(ctx->mailbox, flags) != 0)
343  {
344  goto error;
345  }
346  return ctx;
347  }
348 
349  if (m->opened > 0)
350  {
351  m->opened++;
352  return ctx;
353  }
354 
355  m->size = 0;
356  m->msg_unread = 0;
357  m->msg_flagged = 0;
358  m->rights = MUTT_ACL_ALL;
359 
360  if (m->type == MUTT_UNKNOWN)
361  {
363  m->mx_ops = mx_get_ops(m->type);
364  }
365 
366  if ((m->type == MUTT_UNKNOWN) || (m->type == MUTT_MAILBOX_ERROR) || !m->mx_ops)
367  {
368  if (m->type == MUTT_MAILBOX_ERROR)
370  else if ((m->type == MUTT_UNKNOWN) || !m->mx_ops)
371  mutt_error(_("%s is not a mailbox"), mailbox_path(m));
372  goto error;
373  }
374 
376 
377  /* if the user has a 'push' command in their .neomuttrc, or in a folder-hook,
378  * it will cause the progress messages not to be displayed because
379  * mutt_refresh() will think we are in the middle of a macro. so set a
380  * flag to indicate that we should really refresh the screen. */
381  OptForceRefresh = true;
382 
383  if (m->verbose)
384  mutt_message(_("Reading %s..."), mailbox_path(m));
385 
386  // Clear out any existing emails
387  for (int i = 0; i < m->email_max; i++)
388  {
389  email_free(&m->emails[i]);
390  }
391 
392  m->msg_count = 0;
393  m->msg_unread = 0;
394  m->msg_flagged = 0;
395  m->msg_new = 0;
396  m->msg_deleted = 0;
397  m->msg_tagged = 0;
398  m->vcount = 0;
399 
400  int rc = m->mx_ops->mbox_open(ctx->mailbox);
401  m->opened++;
402  if (rc == 0)
403  ctx_update(ctx);
404 
405  if ((rc == 0) || (rc == -2))
406  {
407  if ((flags & MUTT_NOSORT) == 0)
408  {
409  /* avoid unnecessary work since the mailbox is completely unthreaded
410  * to begin with */
411  OptSortSubthreads = false;
412  OptNeedRescore = false;
413  }
414  if (m->verbose)
416  if (rc == -2)
417  {
418  mutt_error(_("Reading from %s interrupted..."), mailbox_path(m));
419  mutt_sort_headers(ctx->mailbox, ctx->threads, true, &ctx->vsize);
420  }
421  }
422  else
423  {
424  goto error;
425  }
426 
427  if (!m->peekonly)
428  m->has_new = false;
429  OptForceRefresh = false;
430 
431  return ctx;
432 
433 error:
435  if (newly_linked_account)
437  ctx_free(&ctx);
438  return NULL;
439 }
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:53
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
The "current" mailbox.
Definition: context.h:38
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
int ctx_mailbox_observer(struct NotifyCallback *nc)
Watch for changes affecting the Context - Implements observer_t.
Definition: context.c:297
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
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
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:44
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
#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
void mutt_sort_headers(struct Mailbox *m, struct ThreadsContext *threads, bool init, off_t *vsize)
Sort emails by their headers.
Definition: sort.c:367
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:117
struct ThreadsContext * threads
Threads context.
Definition: context.h:43
#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_READONLY
Open in read-only mode.
Definition: mx.h:54
WHERE bool OptNeedRescore
(pseudo) set when the &#39;score&#39; command is used
Definition: options.h:42
int vcount
The number of virtual messages.
Definition: mailbox.h:102
int(* mbox_open)(struct Mailbox *m)
Open a Mailbox.
Definition: mx.h:146
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Definition: context.h:50
#define MUTT_PEEK
Revert atime back after taking a look (if applicable)
Definition: mx.h:59
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
The Context has been opened.
Definition: context.h:61
struct Notify * notify
Notifications handler.
Definition: context.h:51
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:445
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:113
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:169
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:40
WHERE bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:37
struct Context * ctx_new(struct Mailbox *m)
Create a new Context.
Definition: context.c:76
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
void ctx_update(struct Context *ctx)
Update the Context&#39;s message counts.
Definition: context.c:112
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mx.h:52
bool verbose
Display status messages?
Definition: mailbox.h:118
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
unsigned char C_MboxType
Config: Default type for creating new mailboxes.
Definition: mx.c:84
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:55
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:365
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1336
Context has changed, NotifyContext, EventContext.
Definition: notify_type.h:38
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
static int mx_open_mailbox_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox for appending.
Definition: mx.c:200
int msg_new
Number of new messages.
Definition: mailbox.h:95
bool collapsed
Are all threads collapsed?
Definition: context.h:48
#define mutt_error(...)
Definition: logging.h:84
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:94
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:42
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
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:50
struct Notify * notify
Notifications handler.
Definition: mailbox.h:144
An Event that happened to an Context.
Definition: context.h:68
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mx.h:56
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:152
+ 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 445 of file mx.c.

446 {
447  if (!m)
448  return;
449 
450  m->opened--;
451  if (m->opened != 0)
452  return;
453 
454  /* never announce that a mailbox we've just left has new mail.
455  * TODO: really belongs in mx_mbox_close, but this is a nice hook point */
456  if (!m->peekonly)
458 
459  if (m->mx_ops)
460  m->mx_ops->mbox_close(m);
461 
463  mutt_hash_free(&m->id_hash);
465 
466  if (m->emails)
467  {
468  for (int i = 0; i < m->msg_count; i++)
469  {
470  if (!m->emails[i])
471  break;
472  email_free(&m->emails[i]);
473  }
474  }
475 }
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:43
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
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
int(* mbox_close)(struct Mailbox *m)
Close a Mailbox.
Definition: mx.h:204
void mutt_mailbox_set_notified(struct Mailbox *m)
Note when the user was last notified of new mail.
Definition: mutt_mailbox.c:286
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sync_mailbox()

static int sync_mailbox ( struct Mailbox m)
static

save changes to disk

Parameters
mMailbox
Return values
0Success
-1Failure

Definition at line 483 of file mx.c.

484 {
485  if (!m || !m->mx_ops || !m->mx_ops->mbox_sync)
486  return -1;
487 
488  if (m->verbose)
489  {
490  /* L10N: Displayed before/as a mailbox is being synced */
491  mutt_message(_("Writing %s..."), mailbox_path(m));
492  }
493 
494  int rc = m->mx_ops->mbox_sync(m);
495  if (rc != 0)
496  {
497  mutt_debug(LL_DEBUG2, "mbox_sync returned: %d\n", rc);
498  if ((rc < 0) && m->verbose)
499  {
500  /* L10N: Displayed if a mailbox sync fails */
501  mutt_error(_("Unable to write %s"), mailbox_path(m));
502  }
503  }
504 
505  return rc;
506 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
Log at debug level 2.
Definition: logging.h:41
int(* mbox_sync)(struct Mailbox *m)
Save changes to the Mailbox.
Definition: mx.h:193
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
+ 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 514 of file mx.c.

515 {
516  if (!m)
517  return -1;
518 
519  struct stat st, stc;
520  int opt_confappend, rc;
521 
522  if (!C_Trash || (m->msg_deleted == 0) || ((m->type == MUTT_MAILDIR) && C_MaildirTrash))
523  {
524  return 0;
525  }
526 
527  int delmsgcount = 0;
528  int first_del = -1;
529  for (int i = 0; i < m->msg_count; i++)
530  {
531  struct Email *e = m->emails[i];
532  if (!e)
533  break;
534 
535  if (e->deleted && !e->purge)
536  {
537  if (first_del < 0)
538  first_del = i;
539  delmsgcount++;
540  }
541  }
542 
543  if (delmsgcount == 0)
544  return 0; /* nothing to be done */
545 
546  /* avoid the "append messages" prompt */
547  opt_confappend = C_Confirmappend;
548  if (opt_confappend)
549  C_Confirmappend = false;
550  rc = mutt_save_confirm(C_Trash, &st);
551  if (opt_confappend)
552  C_Confirmappend = true;
553  if (rc != 0)
554  {
555  /* L10N: Although we know the precise number of messages, we do not show it to the user.
556  So feel free to use a "generic plural" as plural translation if your language has one. */
557  mutt_error(ngettext("message not deleted", "messages not deleted", delmsgcount));
558  return -1;
559  }
560 
561  if ((lstat(mailbox_path(m), &stc) == 0) && (stc.st_ino == st.st_ino) &&
562  (stc.st_dev == st.st_dev) && (stc.st_rdev == st.st_rdev))
563  {
564  return 0; /* we are in the trash folder: simple sync */
565  }
566 
567 #ifdef USE_IMAP
568  if ((m->type == MUTT_IMAP) && (imap_path_probe(C_Trash, NULL) == MUTT_IMAP))
569  {
570  if (imap_fast_trash(m, C_Trash) == 0)
571  return 0;
572  }
573 #endif
574 
575  struct Mailbox *m_trash = mx_path_resolve(C_Trash);
576  const bool old_append = m_trash->append;
577  struct Context *ctx_trash = mx_mbox_open(m_trash, MUTT_APPEND);
578  if (ctx_trash)
579  {
580  /* continue from initial scan above */
581  for (int i = first_del; i < m->msg_count; i++)
582  {
583  struct Email *e = m->emails[i];
584  if (!e)
585  break;
586 
587  if (e->deleted && !e->purge)
588  {
589  if (mutt_append_message(ctx_trash->mailbox, m, e, MUTT_CM_NO_FLAGS, CH_NO_FLAGS) == -1)
590  {
591  mx_mbox_close(&ctx_trash);
592  m_trash->append = old_append;
593  return -1;
594  }
595  }
596  }
597 
598  mx_mbox_close(&ctx_trash);
599  m_trash->append = old_append;
600  }
601  else
602  {
603  mutt_error(_("Can't open trash folder"));
604  mailbox_free(&m_trash);
605  return -1;
606  }
607 
608  return 0;
609 }
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:53
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
The "current" mailbox.
Definition: context.h:38
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
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:2367
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:630
#define _(a)
Definition: message.h:28
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1350
char * C_Trash
Config: Folder to put deleted emails.
Definition: mx.c:86
struct Mailbox * mailbox
Definition: context.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:70
&#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:50
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
bool C_MaildirTrash
Config: Use the maildir &#39;trashed&#39; flag, rather than deleting.
Definition: config.c:42
#define mutt_error(...)
Definition: logging.h:84
int mutt_append_message(struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:905
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1682
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
int imap_fast_trash(struct Mailbox *m, char *dest)
Use server COPY command to copy deleted messages to trash.
Definition: imap.c:1397
WHERE bool C_Confirmappend
Config: Confirm before appending emails to a mailbox.
Definition: mutt_globals.h:141
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_close()

int mx_mbox_close ( struct Context **  ptr)

Save changes and close mailbox.

Parameters
[out]ptrMailbox
Return values
MUTT_REOPENEDmailbox has been externally modified
MUTT_NEW_MAILnew mail has arrived
0Success
-1Failure
Note
The flag retvals come from a call to a backend sync function
Context will be freed after it's closed
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 630 of file mx.c.

631 {
632  if (!ptr || !*ptr)
633  return 0;
634 
635  struct Context *ctx = *ptr;
636  if (!ctx || !ctx->mailbox)
637  return -1;
638 
639  struct Mailbox *m = ctx->mailbox;
640 
641  if (C_MailCheckRecent && !m->peekonly)
642  m->has_new = false;
643 
644  if (m->readonly || m->dontwrite || m->append || m->peekonly)
645  {
647  ctx_free(ptr);
648  return 0;
649  }
650 
651  int i, read_msgs = 0;
652  int rc = -1;
653  enum QuadOption move_messages = MUTT_NO;
654  enum QuadOption purge = MUTT_YES;
655  struct Buffer *mbox = NULL;
656  struct Buffer *buf = mutt_buffer_pool_get();
657 
658 #ifdef USE_NNTP
659  if ((m->msg_unread != 0) && (m->type == MUTT_NNTP))
660  {
661  struct NntpMboxData *mdata = m->mdata;
662 
663  if (mdata && mdata->adata && mdata->group)
664  {
665  enum QuadOption ans =
666  query_quadoption(C_CatchupNewsgroup, _("Mark all articles read?"));
667  if (ans == MUTT_ABORT)
668  goto cleanup;
669  if (ans == MUTT_YES)
670  mutt_newsgroup_catchup(m, mdata->adata, mdata->group);
671  }
672  }
673 #endif
674 
675  for (i = 0; i < m->msg_count; i++)
676  {
677  struct Email *e = m->emails[i];
678  if (!e)
679  break;
680 
681  if (!e->deleted && e->read && !(e->flagged && C_KeepFlagged))
682  read_msgs++;
683  }
684 
685 #ifdef USE_NNTP
686  /* don't need to move articles from newsgroup */
687  if (m->type == MUTT_NNTP)
688  read_msgs = 0;
689 #endif
690 
691  if ((read_msgs != 0) && (C_Move != MUTT_NO))
692  {
693  bool is_spool;
694  mbox = mutt_buffer_pool_get();
695 
697  if (p)
698  {
699  is_spool = true;
700  mutt_buffer_strcpy(mbox, p);
701  }
702  else
703  {
704  mutt_buffer_strcpy(mbox, C_Mbox);
705  is_spool = mutt_is_spool(mailbox_path(m)) &&
707  }
708 
709  if (is_spool && !mutt_buffer_is_empty(mbox))
710  {
712  mutt_buffer_printf(buf,
713  /* L10N: The first argument is the number of read messages to be
714  moved, the second argument is the target mailbox. */
715  ngettext("Move %d read message to %s?",
716  "Move %d read messages to %s?", read_msgs),
717  read_msgs, mutt_buffer_string(mbox));
718  move_messages = query_quadoption(C_Move, mutt_buffer_string(buf));
719  if (move_messages == MUTT_ABORT)
720  goto cleanup;
721  }
722  }
723 
724  /* There is no point in asking whether or not to purge if we are
725  * just marking messages as "trash". */
726  if ((m->msg_deleted != 0) && !((m->type == MUTT_MAILDIR) && C_MaildirTrash))
727  {
728  mutt_buffer_printf(buf,
729  ngettext("Purge %d deleted message?",
730  "Purge %d deleted messages?", m->msg_deleted),
731  m->msg_deleted);
733  if (purge == MUTT_ABORT)
734  goto cleanup;
735  }
736 
737  if (C_MarkOld && !m->peekonly)
738  {
739  for (i = 0; i < m->msg_count; i++)
740  {
741  struct Email *e = m->emails[i];
742  if (!e)
743  break;
744  if (!e->deleted && !e->old && !e->read)
745  mutt_set_flag(m, e, MUTT_OLD, true);
746  }
747  }
748 
749  if (move_messages)
750  {
751  if (m->verbose)
752  mutt_message(_("Moving read messages to %s..."), mutt_buffer_string(mbox));
753 
754 #ifdef USE_IMAP
755  /* try to use server-side copy first */
756  i = 1;
757 
758  if ((m->type == MUTT_IMAP) && (imap_path_probe(mutt_buffer_string(mbox), NULL) == MUTT_IMAP))
759  {
760  /* add messages for moving, and clear old tags, if any */
761  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
762  for (i = 0; i < m->msg_count; i++)
763  {
764  struct Email *e = m->emails[i];
765  if (!e)
766  break;
767 
768  if (e->read && !e->deleted && !(e->flagged && C_KeepFlagged))
769  {
770  e->tagged = true;
771  emaillist_add_email(&el, e);
772  }
773  else
774  e->tagged = false;
775  }
776 
777  i = imap_copy_messages(ctx->mailbox, &el, mutt_buffer_string(mbox), true);
778  emaillist_clear(&el);
779  }
780 
781  if (i == 0) /* success */
783  else if (i == -1) /* horrible error, bail */
784  goto cleanup;
785  else /* use regular append-copy mode */
786 #endif
787  {
788  struct Mailbox *m_read = mx_path_resolve(mutt_buffer_string(mbox));
789  struct Context *ctx_read = mx_mbox_open(m_read, MUTT_APPEND);
790  if (!ctx_read)
791  {
792  mailbox_free(&m_read);
793  goto cleanup;
794  }
795 
796  for (i = 0; i < m->msg_count; i++)
797  {
798  struct Email *e = m->emails[i];
799  if (!e)
800  break;
801  if (e->read && !e->deleted && !(e->flagged && C_KeepFlagged))
802  {
803  if (mutt_append_message(ctx_read->mailbox, ctx->mailbox, e,
805  {
806  mutt_set_flag(m, e, MUTT_DELETE, true);
807  mutt_set_flag(m, e, MUTT_PURGE, true);
808  }
809  else
810  {
811  mx_mbox_close(&ctx_read);
812  goto cleanup;
813  }
814  }
815  }
816 
817  mx_mbox_close(&ctx_read);
818  }
819  }
820  else if (!m->changed && (m->msg_deleted == 0))
821  {
822  if (m->verbose)
823  mutt_message(_("Mailbox is unchanged"));
824  if ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF))
825  mbox_reset_atime(m, NULL);
827  ctx_free(ptr);
828  rc = 0;
829  goto cleanup;
830  }
831 
832  /* copy mails to the trash before expunging */
833  const struct Mailbox *m_trash = mx_mbox_find(m->account, C_Trash);
834  if (purge && (m->msg_deleted != 0) && (m != m_trash))
835  {
836  if (trash_append(ctx->mailbox) != 0)
837  goto cleanup;
838  }
839 
840 #ifdef USE_IMAP
841  /* allow IMAP to preserve the deleted flag across sessions */
842  if (m->type == MUTT_IMAP)
843  {
844  int check = imap_sync_mailbox(ctx->mailbox, (purge != MUTT_NO), true);
845  if (check < 0)
846  {
847  rc = check;
848  goto cleanup;
849  }
850  }
851  else
852 #endif
853  {
854  if (purge == MUTT_NO)
855  {
856  for (i = 0; i < m->msg_count; i++)
857  {
858  struct Email *e = m->emails[i];
859  if (!e)
860  break;
861 
862  e->deleted = false;
863  e->purge = false;
864  }
865  m->msg_deleted = 0;
866  }
867 
868  if (m->changed || (m->msg_deleted != 0))
869  {
870  int check = sync_mailbox(ctx->mailbox);
871  if (check != 0)
872  {
873  rc = check;
874  goto cleanup;
875  }
876  }
877  }
878 
879  if (m->verbose)
880  {
881  if (move_messages)
882  {
883  mutt_message(_("%d kept, %d moved, %d deleted"),
884  m->msg_count - m->msg_deleted, read_msgs, m->msg_deleted);
885  }
886  else
887  mutt_message(_("%d kept, %d deleted"), m->msg_count - m->msg_deleted, m->msg_deleted);
888  }
889 
890  if ((m->msg_count == m->msg_deleted) &&
891  ((m->type == MUTT_MMDF) || (m->type == MUTT_MBOX)) &&
893  {
895  }
896 
897 #ifdef USE_SIDEBAR
898  if ((purge == MUTT_YES) && (m->msg_deleted != 0))
899  {
900  for (i = 0; i < m->msg_count; i++)
901  {
902  struct Email *e = m->emails[i];
903  if (!e)
904  break;
905  if (e->deleted && !e->read)
906  {
907  m->msg_unread--;
908  if (!e->old)
909  m->msg_new--;
910  }
911  if (e->deleted && e->flagged)
912  m->msg_flagged--;
913  }
914  }
915 #endif
916 
918  ctx_free(ptr);
919 
920  rc = 0;
921 
922 cleanup:
925  return rc;
926 }
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:53
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
The "current" mailbox.
Definition: context.h:38
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
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:67
bool C_MarkOld
Config: Mark new emails as old when leaving the mailbox.
Definition: globals.c:36
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
WHERE bool C_SaveEmpty
Config: (mbox,mmdf) Preserve empty mailboxes.
Definition: mutt_globals.h:158
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2367
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
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:630
void mbox_reset_atime(struct Mailbox *m, struct stat *st)
Reset the access time on the mailbox file.
Definition: mbox.c:837
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
static int sync_mailbox(struct Mailbox *m)
save changes to disk
Definition: mx.c:483
static int trash_append(struct Mailbox *m)
move deleted mails to the trash folder
Definition: mx.c:514
bool peekonly
Just taking a glance, revert atime.
Definition: mailbox.h:117
struct NntpAccountData * adata
Definition: lib.h:153
unsigned char C_Move
Config: Move emails from $spoolfile to $mbox when read.
Definition: mx.c:85
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
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:1593
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
Messages to be purged (bypass trash)
Definition: mutt.h:100
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:130
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:34
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
int imap_sync_mailbox(struct Mailbox *m, bool expunge, bool close)
Sync all the changes to the server.
Definition: imap.c:1509
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
char * C_Trash
Config: Folder to put deleted emails.
Definition: mx.c:86
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
struct Mailbox * mailbox
Definition: context.h:50
bool old
Email is seen, but unread.
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:70
void mutt_file_unlink_empty(const char *path)
Delete a file if it&#39;s empty.
Definition: file.c:1311
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:445
char * group
Definition: lib.h:140
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
User aborted the question (with Ctrl-G)
Definition: quad.h:38
unsigned char C_CatchupNewsgroup
Config: (nntp) Mark all articles as read when leaving a newsgroup.
Definition: config.c:37
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:46
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
Old messages.
Definition: mutt.h:94
int imap_copy_messages(struct Mailbox *m, struct EmailList *el, const char *dest, bool delete_original)
Server COPY messages to another folder.
Definition: message.c:1564
Messages to be deleted.
Definition: mutt.h:98
A mailbox.
Definition: mailbox.h:81
char * mutt_find_hook(HookFlags type, const char *pat)
Find a matching hook.
Definition: hook.c:552
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
bool verbose
Display status messages?
Definition: mailbox.h:118
bool purge
Skip trash folder when deleting.
Definition: email.h:46
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
WHERE bool C_MailCheckRecent
Config: Notify the user about new mail since the last time the mailbox was opened.
Definition: mutt_globals.h:150
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:151
NNTP-specific Mailbox data -.
Definition: lib.h:138
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:517
WHERE unsigned char C_Delete
Config: Really delete messages, when the mailbox is closed.
Definition: mutt_globals.h:125
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:95
bool deleted
Email is deleted.
Definition: email.h:45
bool C_MaildirTrash
Config: Use the maildir &#39;trashed&#39; flag, rather than deleting.
Definition: config.c:42
int mutt_append_message(struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:905
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1682
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:50
bool C_KeepFlagged
Config: Don&#39;t move flagged messages from $spoolfile to $mbox
Definition: mx.c:83
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1294
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
WHERE char * C_Mbox
Config: Folder that receives read emails (see Move)
Definition: mutt_globals.h:94
static bool mutt_is_spool(const char *str)
Is this the spoolfile?
Definition: mx.c:155
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_mbox_sync()

int mx_mbox_sync ( struct Mailbox m)

Save changes to mailbox.

Parameters
[in]mMailbox
Return values
MUTT_REOPENEDmailbox has been externally modified
MUTT_NEW_MAILnew mail has arrived
0Success
-1Error
Note
The flag retvals come from a call to a backend sync function

Definition at line 938 of file mx.c.

939 {
940  if (!m)
941  return -1;
942 
943  int rc;
944  int purge = 1;
945  int msgcount, deleted;
946 
947  if (m->dontwrite)
948  {
949  char buf[256], tmp[256];
950  if (km_expand_key(buf, sizeof(buf), km_find_func(MENU_MAIN, OP_TOGGLE_WRITE)))
951  snprintf(tmp, sizeof(tmp), _(" Press '%s' to toggle write"), buf);
952  else
953  mutt_str_copy(tmp, _("Use 'toggle-write' to re-enable write"), sizeof(tmp));
954 
955  mutt_error(_("Mailbox is marked unwritable. %s"), tmp);
956  return -1;
957  }
958  else if (m->readonly)
959  {
960  mutt_error(_("Mailbox is read-only"));
961  return -1;
962  }
963 
964  if (!m->changed && (m->msg_deleted == 0))
965  {
966  if (m->verbose)
967  mutt_message(_("Mailbox is unchanged"));
968  return 0;
969  }
970 
971  if (m->msg_deleted != 0)
972  {
973  char buf[128];
974 
975  snprintf(buf, sizeof(buf),
976  ngettext("Purge %d deleted message?", "Purge %d deleted messages?", m->msg_deleted),
977  m->msg_deleted);
978  purge = query_quadoption(C_Delete, buf);
979  if (purge == MUTT_ABORT)
980  return -1;
981  if (purge == MUTT_NO)
982  {
983  if (!m->changed)
984  return 0; /* nothing to do! */
985  /* let IMAP servers hold on to D flags */
986  if (m->type != MUTT_IMAP)
987  {
988  for (int i = 0; i < m->msg_count; i++)
989  {
990  struct Email *e = m->emails[i];
991  if (!e)
992  break;
993  e->deleted = false;
994  e->purge = false;
995  }
996  m->msg_deleted = 0;
997  }
998  }
1000  }
1001 
1002  /* really only for IMAP - imap_sync_mailbox results in a call to
1003  * ctx_update_tables, so m->msg_deleted is 0 when it comes back */
1004  msgcount = m->msg_count;
1005  deleted = m->msg_deleted;
1006 
1007  const struct Mailbox *m_trash = mx_mbox_find(m->account, C_Trash);
1008  if (purge && (m->msg_deleted != 0) && (m != m_trash))
1009  {
1010  if (trash_append(m) != 0)
1011  return -1;
1012  }
1013 
1014 #ifdef USE_IMAP
1015  if (m->type == MUTT_IMAP)
1016  rc = imap_sync_mailbox(m, purge, false);
1017  else
1018 #endif
1019  rc = sync_mailbox(m);
1020  if (rc >= 0)
1021  {
1022 #ifdef USE_IMAP
1023  if ((m->type == MUTT_IMAP) && !purge)
1024  {
1025  if (m->verbose)
1026  mutt_message(_("Mailbox checkpointed"));
1027  }
1028  else
1029 #endif
1030  {
1031  if (m->verbose)
1032  mutt_message(_("%d kept, %d deleted"), msgcount - deleted, deleted);
1033  }
1034 
1035  mutt_sleep(0);
1036 
1037  if ((m->msg_count == m->msg_deleted) &&
1038  ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) &&
1040  {
1041  unlink(mailbox_path(m));
1043  return 0;
1044  }
1045 
1046  /* if we haven't deleted any messages, we don't need to resort */
1047  /* ... except for certain folder formats which need "unsorted"
1048  * sort order in order to synchronize folders.
1049  *
1050  * MH and maildir are safe. mbox-style seems to need re-sorting,
1051  * at least with the new threading code. */
1052  if (purge || ((m->type != MUTT_MAILDIR) && (m->type != MUTT_MH)))
1053  {
1054  /* IMAP does this automatically after handling EXPUNGE */
1055  if (m->type != MUTT_IMAP)
1056  {
1059  }
1060  }
1061  }
1062 
1063  return rc;
1064 }
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:204
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
Clear the &#39;last-tagged&#39; pointer.
Definition: mailbox.h:177
WHERE bool C_SaveEmpty
Config: (mbox,mmdf) Preserve empty mailboxes.
Definition: mutt_globals.h:158
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 sync_mailbox(struct Mailbox *m)
save changes to disk
Definition: mx.c:483
static int trash_append(struct Mailbox *m)
move deleted mails to the trash folder
Definition: mx.c:514
#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:1593
Index panel (list of emails)
Definition: keymap.h:80
int imap_sync_mailbox(struct Mailbox *m, bool expunge, bool close)
Sync all the changes to the server.
Definition: imap.c:1509
char * C_Trash
Config: Folder to put deleted emails.
Definition: mx.c:86
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1447
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:445
User aborted the question (with Ctrl-G)
Definition: quad.h:38
&#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:939
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:911
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
&#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
&#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:517
WHERE unsigned char C_Delete
Config: Really delete messages, when the mailbox is closed.
Definition: mutt_globals.h:125
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:39
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
&#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:184
static bool mutt_is_spool(const char *str)
Is this the spoolfile?
Definition: mx.c:155
+ 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 1073 of file mx.c.

1074 {
1075  if (!m)
1076  return NULL;
1077 
1078  struct Address *p = NULL;
1079  struct Message *msg = NULL;
1080 
1081  if (!m->mx_ops || !m->mx_ops->msg_open_new)
1082  {
1083  mutt_debug(LL_DEBUG1, "function unimplemented for mailbox type %d\n", m->type);
1084  return NULL;
1085  }
1086 
1087  msg = mutt_mem_calloc(1, sizeof(struct Message));
1088  msg->write = true;
1089 
1090  if (e)
1091  {
1092  msg->flags.flagged = e->flagged;
1093  msg->flags.replied = e->replied;
1094  msg->flags.read = e->read;
1095  msg->flags.draft = (flags & MUTT_SET_DRAFT);
1096  msg->received = e->received;
1097  }
1098 
1099  if (msg->received == 0)
1100  msg->received = mutt_date_epoch();
1101 
1102  if (m->mx_ops->msg_open_new(m, msg, e) == 0)
1103  {
1104  if (m->type == MUTT_MMDF)
1105  fputs(MMDF_SEP, msg->fp);
1106 
1107  if (((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) && (flags & MUTT_ADD_FROM))
1108  {
1109  if (e)
1110  {
1111  p = TAILQ_FIRST(&e->env->return_path);
1112  if (!p)
1113  p = TAILQ_FIRST(&e->env->sender);
1114  if (!p)
1115  p = TAILQ_FIRST(&e->env->from);
1116  }
1117 
1118  // Force a 'C' locale for the date, so that day/month names are in English
1119  locale_t loc = newlocale(LC_TIME_MASK, "C", 0);
1120  char buf[64] = { 0 };
1121  struct tm tm = mutt_date_localtime(msg->received);
1122  strftime_l(buf, sizeof(buf), "%a %b %e %H:%M:%S %Y", &tm, loc);
1123  freelocale(loc);
1124  fprintf(msg->fp, "From %s %s\n", p ? p->mailbox : NONULL(Username), buf);
1125  }
1126  }
1127  else
1128  FREE(&msg);
1129 
1130  return msg;
1131 }
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: mx.h:92
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
#define MUTT_SET_DRAFT
set the message draft flag
Definition: mx.h:66
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:52
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: mx.h:91
A local copy of an email.
Definition: mx.h:82
struct Message::@0 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: mx.h:93
#define MMDF_SEP
Definition: lib.h:64
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
bool write
nonzero if message is open for writing
Definition: mx.h:87
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
int(* msg_open_new)(struct Mailbox *m, struct Message *msg, const struct Email *e)
Open a new message in a Mailbox.
Definition: mx.h:233
bool replied
Email has been replied to.
Definition: email.h:54
FILE * fp
pointer to the message data
Definition: mx.h:84
#define FREE(x)
Definition: memory.h:40
time_t received
the time at which this message was received
Definition: mx.h:95
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool read
Definition: mx.h:90
#define MUTT_ADD_FROM
add a From_ line
Definition: mx.h:65
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()

int mx_mbox_check ( struct Mailbox m)

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

Parameters
mMailbox
Return values
>0Success, e.g. MUTT_NEW_MAIL
0Success, no change
-1Failure

Definition at line 1140 of file mx.c.

1141 {
1142  if (!m || !m->mx_ops)
1143  return -1;
1144 
1145  int rc = m->mx_ops->mbox_check(m);
1146  if ((rc == MUTT_NEW_MAIL) || (rc == MUTT_REOPENED))
1148 
1149  return rc;
1150 }
Email list was changed.
Definition: mailbox.h:173
int(* mbox_check)(struct Mailbox *m)
Check for new mail.
Definition: mx.h:169
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
New mail received in Mailbox.
Definition: mx.h:73
Mailbox was reopened.
Definition: mx.h:75
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:184
+ 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 1159 of file mx.c.

1160 {
1161  if (!m || !m->emails || (msgno < 0) || (msgno >= m->msg_count))
1162  return NULL;
1163 
1164  if (!m->mx_ops || !m->mx_ops->msg_open)
1165  {
1166  mutt_debug(LL_DEBUG1, "function not implemented for mailbox type %d\n", m->type);
1167  return NULL;
1168  }
1169 
1170  struct Message *msg = mutt_mem_calloc(1, sizeof(struct Message));
1171  if (m->mx_ops->msg_open(m, msg, msgno) < 0)
1172  FREE(&msg);
1173 
1174  return msg;
1175 }
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
A local copy of an email.
Definition: mx.h:82
int(* msg_open)(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox.
Definition: mx.h:219
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 1184 of file mx.c.

1185 {
1186  if (!m || !m->mx_ops || !m->mx_ops->msg_commit || !msg)
1187  return -1;
1188 
1189  if (!(msg->write && m->append))
1190  {
1191  mutt_debug(LL_DEBUG1, "msg->write = %d, m->append = %d\n", msg->write, m->append);
1192  return -1;
1193  }
1194 
1195  return m->mx_ops->msg_commit(m, msg);
1196 }
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Save changes to an email.
Definition: mx.h:246
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: mx.h:87
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 1205 of file mx.c.

1206 {
1207  if (!m || !msg || !*msg)
1208  return 0;
1209 
1210  int rc = 0;
1211 
1212  if (m->mx_ops && m->mx_ops->msg_close)
1213  rc = m->mx_ops->msg_close(m, *msg);
1214 
1215  if ((*msg)->path)
1216  {
1217  mutt_debug(LL_DEBUG1, "unlinking %s\n", (*msg)->path);
1218  unlink((*msg)->path);
1219  FREE(&(*msg)->path);
1220  }
1221 
1222  FREE(&(*msg)->committed_path);
1223  FREE(msg);
1224  return rc;
1225 }
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: mx.h:259
#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 1231 of file mx.c.

1232 {
1233  size_t s = MAX(sizeof(struct Email *), sizeof(int));
1234 
1235  if ((m->email_max + 25) * s < m->email_max * s)
1236  {
1237  mutt_error(_("Out of memory"));
1238  mutt_exit(1);
1239  }
1240 
1241  m->email_max += 25;
1242  if (m->emails)
1243  {
1244  mutt_mem_realloc(&m->emails, sizeof(struct Email *) * m->email_max);
1245  mutt_mem_realloc(&m->v2r, sizeof(int) * m->email_max);
1246  }
1247  else
1248  {
1249  m->emails = mutt_mem_calloc(m->email_max, sizeof(struct Email *));
1250  m->v2r = mutt_mem_calloc(m->email_max, sizeof(int));
1251  }
1252  for (int i = m->email_max - 25; i < m->email_max; i++)
1253  {
1254  m->emails[i] = NULL;
1255  m->v2r[i] = -1;
1256  }
1257 }
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:138
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 1266 of file mx.c.

1267 {
1268  if (!path || (*path == '\0'))
1269  return -1;
1270 
1271  enum MailboxType type = mx_path_probe(path);
1272  const struct MxOps *ops = mx_get_ops(type);
1273  if (!ops || !ops->path_is_empty)
1274  return -1;
1275 
1276  return ops->path_is_empty(path);
1277 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
int(* path_is_empty)(const char *path)
Is the Mailbox empty?
Definition: mx.h:373
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1336
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
char * path
path to temp file
Definition: mx.h:85
The Mailbox API.
Definition: mx.h:104
+ 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 1289 of file mx.c.

1290 {
1291  if (!m || !buf)
1292  return -1;
1293 
1294  if (m->mx_ops->tags_edit)
1295  return m->mx_ops->tags_edit(m, tags, buf, buflen);
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
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mx.h:298
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 1309 of file mx.c.

1310 {
1311  if (!m || !e || !tags)
1312  return -1;
1313 
1314  if (m->mx_ops->tags_commit)
1315  return m->mx_ops->tags_commit(m, e, tags);
1316 
1317  mutt_message(_("Folder doesn't support tagging, aborting"));
1318  return -1;
1319 }
#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: mx.h:313
+ 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 1326 of file mx.c.

1327 {
1328  return m && m->mx_ops->tags_commit && m->mx_ops->tags_edit;
1329 }
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mx.h:298
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: mx.h:313
+ 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 1336 of file mx.c.

1337 {
1338  if (!path)
1339  return MUTT_UNKNOWN;
1340 
1341  enum MailboxType rc;
1342 
1343  // First, search the non-local Mailbox types (is_local == false)
1344  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1345  {
1346  if ((*ops)->is_local)
1347  continue;
1348  rc = (*ops)->path_probe(path, NULL);
1349  if (rc != MUTT_UNKNOWN)
1350  return rc;
1351  }
1352 
1353  struct stat st = { 0 };
1354  if (stat(path, &st) != 0)
1355  {
1356  mutt_debug(LL_DEBUG1, "unable to stat %s: %s (errno %d)\n", path, strerror(errno), errno);
1357  return MUTT_UNKNOWN;
1358  }
1359 
1360  if (S_ISFIFO(st.st_mode))
1361  {
1362  mutt_error(_("Can't open %s: it is a pipe"), path);
1363  return MUTT_UNKNOWN;
1364  }
1365 
1366  // Next, search the local Mailbox types (is_local == true)
1367  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1368  {
1369  if (!(*ops)->is_local)
1370  continue;
1371  rc = (*ops)->path_probe(path, &st);
1372  if (rc != MUTT_UNKNOWN)
1373  return rc;
1374  }
1375 
1376  return rc;
1377 }
#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:107
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: mx.h:104
+ 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 1382 of file mx.c.

1383 {
1384  if (!buf)
1385  return -1;
1386 
1387  for (size_t i = 0; i < 3; i++)
1388  {
1389  /* Look for !! ! - < > or ^ followed by / or NUL */
1390  if ((buf[0] == '!') && (buf[1] == '!'))
1391  {
1392  if (((buf[2] == '/') || (buf[2] == '\0')))
1393  {
1394  mutt_str_inline_replace(buf, buflen, 2, LastFolder);
1395  }
1396  }
1397  else if ((buf[0] == '+') || (buf[0] == '='))
1398  {
1399  size_t folder_len = mutt_str_len(folder);
1400  if ((folder_len > 0) && (folder[folder_len - 1] != '/'))
1401  {
1402  buf[0] = '/';
1403  mutt_str_inline_replace(buf, buflen, 0, folder);
1404  }
1405  else
1406  {
1407  mutt_str_inline_replace(buf, buflen, 1, folder);
1408  }
1409  }
1410  else if ((buf[1] == '/') || (buf[1] == '\0'))
1411  {
1412  if (buf[0] == '!')
1413  {
1414  mutt_str_inline_replace(buf, buflen, 1, C_Spoolfile);
1415  }
1416  else if (buf[0] == '-')
1417  {
1418  mutt_str_inline_replace(buf, buflen, 1, LastFolder);
1419  }
1420  else if (buf[0] == '<')
1421  {
1422  mutt_str_inline_replace(buf, buflen, 1, C_Record);
1423  }
1424  else if (buf[0] == '>')
1425  {
1426  mutt_str_inline_replace(buf, buflen, 1, C_Mbox);
1427  }
1428  else if (buf[0] == '^')
1429  {
1430  mutt_str_inline_replace(buf, buflen, 1, CurrentFolder);
1431  }
1432  else if (buf[0] == '~')
1433  {
1434  mutt_str_inline_replace(buf, buflen, 1, HomeDir);
1435  }
1436  }
1437  else if (buf[0] == '@')
1438  {
1439  /* elm compatibility, @ expands alias to user name */
1440  struct AddressList *al = alias_lookup(buf + 1);
1441  if (!al || TAILQ_EMPTY(al))
1442  break;
1443 
1444  struct Email *e = email_new();
1445  e->env = mutt_env_new();
1446  mutt_addrlist_copy(&e->env->from, al, false);
1447  mutt_addrlist_copy(&e->env->to, al, false);
1448  mutt_default_save(buf, buflen, e);
1449  email_free(&e);
1450  break;
1451  }
1452  else
1453  {
1454  break;
1455  }
1456  }
1457 
1458  // if (!folder) //XXX - use inherited version, or pass NULL to backend?
1459  // return -1;
1460 
1461  enum MailboxType type2 = mx_path_probe(buf);
1462  if (type)
1463  *type = type2;
1464  const struct MxOps *ops = mx_get_ops(type2);
1465  if (!ops || !ops->path_canon)
1466  return -1;
1467 
1468  if (ops->path_canon(buf, buflen) < 0)
1469  {
1470  mutt_path_canon(buf, buflen, HomeDir, true);
1471  }
1472 
1473  return 0;
1474 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
The envelope/body of an email.
Definition: email.h:37
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
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:654
char * HomeDir
User&#39;s home directory.
Definition: mutt_globals.h:49
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
int(* path_canon)(char *buf, size_t buflen)
Canonicalise a Mailbox path.
Definition: mx.h:336
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:276
struct Envelope * env
Envelope information.
Definition: email.h:90
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
WHERE char * C_Record
Config: Folder to save &#39;sent&#39; messages.
Definition: mutt_globals.h:98
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:1336
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 * C_Spoolfile
Config: Inbox.
Definition: mutt_globals.h:108
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
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
WHERE char * C_Mbox
Config: Folder that receives read emails (see Move)
Definition: mutt_globals.h:94
The Mailbox API.
Definition: mx.h:104
+ 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 1483 of file mx.c.

1484 {
1485  if (!m)
1486  return -1;
1487 
1488  char buf[PATH_MAX];
1489 
1490  if (m->realpath)
1491  mutt_str_copy(buf, m->realpath, sizeof(buf));
1492  else
1493  mutt_str_copy(buf, mailbox_path(m), sizeof(buf));
1494 
1495  int rc = mx_path_canon(buf, sizeof(buf), folder, &m->type);
1496 
1497  mutt_str_replace(&m->realpath, buf);
1498 
1499  if (rc >= 0)
1500  {
1501  m->mx_ops = mx_get_ops(m->type);
1503  }
1504 
1505  return rc;
1506 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:204
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
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:44
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:1382
+ 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 1511 of file mx.c.

1512 {
1513  if (!buf)
1514  return -1;
1515 
1516  enum MailboxType type = mx_path_probe(buf);
1517  const struct MxOps *ops = mx_get_ops(type);
1518  if (!ops)
1519  return -1;
1520 
1521  if (!ops->path_canon)
1522  return -1;
1523 
1524  if (ops->path_canon(buf, buflen) < 0)
1525  return -1;
1526 
1527  if (!ops->path_pretty)
1528  return -1;
1529 
1530  if (ops->path_pretty(buf, buflen, folder) < 0)
1531  return -1;
1532 
1533  return 0;
1534 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
int(* path_canon)(char *buf, size_t buflen)
Canonicalise a Mailbox path.
Definition: mx.h:336
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mx.h:106
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1336
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
int(* path_pretty)(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path.
Definition: mx.h:349
The Mailbox API.
Definition: mx.h:104
+ 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 1539 of file mx.c.

1540 {
1541  if (!buf)
1542  return -1;
1543 
1544  return 0;
1545 }

◆ 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 1555 of file mx.c.

1556 {
1557  if (!m || !m->mx_ops || !m->mx_ops->msg_padding_size)
1558  return 0;
1559 
1560  return m->mx_ops->msg_padding_size(m);
1561 }
int(* msg_padding_size)(struct Mailbox *m)
Bytes of padding between messages.
Definition: mx.h:269
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 1569 of file mx.c.

1570 {
1571  if (!m || !m->mx_ops || !m->realpath)
1572  return NULL;
1573 
1574  struct Account *np = NULL;
1575  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1576  {
1577  if (np->type != m->type)
1578  continue;
1579 
1580  if (m->mx_ops->ac_owns_path(np, m->realpath))
1581  return np;
1582  }
1583 
1584  return NULL;
1585 }
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: mx.h:121
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 1593 of file mx.c.

1594 {
1595  if (!a || !path)
1596  return NULL;
1597 
1598  struct MailboxNode *np = NULL;
1599  struct Url *url_p = NULL;
1600  struct Url *url_a = NULL;
1601 
1602  const bool use_url = (a->type == MUTT_IMAP);
1603  if (use_url)
1604  {
1605  url_p = url_parse(path);
1606  if (!url_p)
1607  goto done;
1608  }
1609 
1610  STAILQ_FOREACH(np, &a->mailboxes, entries)
1611  {
1612  if (!use_url)
1613  {
1614  if (mutt_str_equal(np->mailbox->realpath, path))
1615  return np->mailbox;
1616  continue;
1617  }
1618 
1619  url_free(&url_a);
1620  url_a = url_parse(np->mailbox->realpath);
1621  if (!url_a)
1622  continue;
1623 
1624  if (!mutt_istr_equal(url_a->host, url_p->host))
1625  continue;
1626  if (url_p->user && !mutt_istr_equal(url_a->user, url_p->user))
1627  continue;
1628  if (a->type == MUTT_IMAP)
1629  {
1630  if (imap_mxcmp(url_a->path, url_p->path) == 0)
1631  break;
1632  }
1633  else
1634  {
1635  if (mutt_str_equal(url_a->path, url_p->path))
1636  break;
1637  }
1638  }
1639 
1640 done:
1641  url_free(&url_p);
1642  url_free(&url_a);
1643 
1644  if (!np)
1645  return NULL;
1646  return np->mailbox;
1647 }
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:67
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:690
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:70
char * host
Host.
Definition: url.h:72
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * path
Path.
Definition: url.h:74
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 1655 of file mx.c.

1656 {
1657  if (!path)
1658  return NULL;
1659 
1660  char buf[PATH_MAX];
1661  mutt_str_copy(buf, path, sizeof(buf));
1662  mx_path_canon(buf, sizeof(buf), C_Folder, NULL);
1663 
1664  struct Account *np = NULL;
1665  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1666  {
1667  struct Mailbox *m = mx_mbox_find(np, buf);
1668  if (m)
1669  return m;
1670  }
1671 
1672  return NULL;
1673 }
#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:1593
Container for Accounts, Notifications.
Definition: neomutt.h:36
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:44
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
char * path
Path.
Definition: url.h:74
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
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:1382
+ 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 1682 of file mx.c.

1683 {
1684  if (!path)
1685  return NULL;
1686 
1687  struct Mailbox *m = mx_mbox_find2(path);
1688  if (m)
1689  return m;
1690 
1691  m = mailbox_new();
1692  m->flags = MB_HIDDEN;
1693  mutt_buffer_strcpy(&m->pathbuf, path);
1695 
1696  return m;
1697 }
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1483
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1655
#define MB_HIDDEN
Definition: mailbox.h:38
A mailbox.
Definition: mailbox.h:81
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
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:51
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 1705 of file mx.c.

1706 {
1707  if (!a || !name)
1708  return NULL;
1709 
1710  struct MailboxNode *np = NULL;
1711 
1712  STAILQ_FOREACH(np, &a->mailboxes, entries)
1713  {
1714  if (mutt_str_equal(np->mailbox->name, name))
1715  return np->mailbox;
1716  }
1717 
1718  return NULL;
1719 }
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 1726 of file mx.c.

1727 {
1728  if (!name)
1729  return NULL;
1730 
1731  struct Account *np = NULL;
1732  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1733  {
1734  struct Mailbox *m = mx_mbox_find_by_name_ac(np, name);
1735  if (m)
1736  return m;
1737  }
1738 
1739  return NULL;
1740 }
#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:1705
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 1751 of file mx.c.

1752 {
1753  if (!path_or_name)
1754  return NULL;
1755 
1756  // Order is name first because you can create a Mailbox from
1757  // a path, but can't from a name. So fallback behavior creates
1758  // a new Mailbox for us.
1759  struct Mailbox *m = mx_mbox_find_by_name(path_or_name);
1760  if (!m)
1761  m = mx_path_resolve(path_or_name);
1762 
1763  return m;
1764 }
static struct Mailbox * mx_mbox_find_by_name(const char *name)
Find a Mailbox with given name.
Definition: mx.c:1726
A mailbox.
Definition: mailbox.h:81
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1682
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mx_ac_add()

int mx_ac_add ( struct Account a,
struct Mailbox m 
)

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

Definition at line 1769 of file mx.c.

1770 {
1771  if (!a || !m || !m->mx_ops || !m->mx_ops->ac_add)
1772  return -1;
1773 
1774  if (m->mx_ops->ac_add(a, m) < 0)
1775  return -1;
1776 
1777  account_mailbox_add(a, m);
1778  return 0;
1779 }
int(* ac_add)(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account.
Definition: mx.h:134
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:66
+ 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

Definition at line 1785 of file mx.c.

1786 {
1787  if (!m || !m->account)
1788  return -1;
1789 
1790  struct Account *a = m->account;
1792  mailbox_free(&m);
1793  if (STAILQ_EMPTY(&a->mailboxes))
1794  {
1796  }
1797  return 0;
1798 }
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
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:70
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:94
#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()

int 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 1803 of file mx.c.

1804 {
1805  if (!m)
1806  return -1;
1807 
1808  return m->mx_ops->mbox_check_stats(m, flags);
1809 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
int(* mbox_check_stats)(struct Mailbox *m, uint8_t flags)
Check the Mailbox statistics.
Definition: mx.h:182
+ 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 1820 of file mx.c.

1821 {
1822  if (!m || !m->mx_ops || !m->mx_ops->msg_save_hcache || !e)
1823  return 0;
1824 
1825  return m->mx_ops->msg_save_hcache(m, e);
1826 }
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Save message to the header cache.
Definition: mx.h:282
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ Here is the caller graph for this function:

Variable Documentation

◆ C_KeepFlagged

bool C_KeepFlagged

Config: Don't move flagged messages from $spoolfile to $mbox

Definition at line 83 of file mx.c.

◆ C_MboxType

unsigned char C_MboxType

Config: Default type for creating new mailboxes.

Definition at line 84 of file mx.c.

◆ C_Move

unsigned char C_Move

Config: Move emails from $spoolfile to $mbox when read.

Definition at line 85 of file mx.c.

◆ C_Trash

char* C_Trash

Config: Folder to put deleted emails.

Definition at line 86 of file mx.c.

◆ 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 89 of file mx.c.

◆ MboxTypeDef

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

Definition at line 98 of file mx.c.

◆ mx_ops

const struct MxOps* mx_ops[]
Initial value:
= {
NULL,
}
struct MxOps MxNotmuchOps
Notmuch Mailbox - Implements MxOps.
Definition: notmuch.c:2656
struct MxOps MxMhOps
MH Mailbox - Implements MxOps.
Definition: mh.c:1242
struct MxOps MxCompOps
Compressed Mailbox - Implements MxOps.
Definition: compress.c:932
struct MxOps MxMaildirOps
Maildir Mailbox - Implements MxOps.
Definition: maildir.c:1632
struct MxOps MxNntpOps
NNTP Mailbox - Implements MxOps.
Definition: nntp.c:2834
struct MxOps MxImapOps
IMAP Mailbox - Implements MxOps.
Definition: imap.c:2454
struct MxOps MxPopOps
POP Mailbox - Implements MxOps.
Definition: pop.c:1242
struct MxOps MxMmdfOps
MMDF Mailbox - Implements MxOps.
Definition: mbox.c:1843
struct MxOps MxMboxOps
Mbox Mailbox - Implements MxOps.
Definition: mbox.c:1813

All the Mailbox backends.

Definition at line 107 of file mx.c.