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

API for mailboxes. More...

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "config/lib.h"
#include "core/lib.h"
+ Include dependency graph for mx.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MUTT_MSG_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_ADD_FROM   (1 << 0)
 add a From_ line More...
 
#define MUTT_SET_DRAFT   (1 << 1)
 set the message draft flag More...
 

Typedefs

typedef uint8_t MsgOpenFlags
 Flags for mx_msg_open_new(), e.g. MUTT_ADD_FROM. More...
 

Functions

enum MxStatus mx_mbox_check (struct Mailbox *m)
 Check for new mail - Wrapper for MxOps::mbox_check() More...
 
enum MxStatus mx_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the statistics for a mailbox - Wrapper for MxOps::mbox_check_stats() More...
 
enum MxStatus mx_mbox_close (struct Mailbox *m)
 Save changes and close mailbox. More...
 
bool mx_mbox_open (struct Mailbox *m, OpenMailboxFlags flags)
 Open a mailbox and parse it. More...
 
enum MxStatus mx_mbox_sync (struct Mailbox *m)
 Save changes to mailbox. More...
 
int mx_msg_close (struct Mailbox *m, struct Message **msg)
 Close 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...
 
struct Messagemx_msg_open_new (struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
 Open a new message. More...
 
struct Messagemx_msg_open (struct Mailbox *m, int msgno)
 return a stream pointer for a message More...
 
int mx_msg_padding_size (struct Mailbox *m)
 Bytes of padding between messages - Wrapper for MxOps::msg_padding_size() More...
 
int mx_save_hcache (struct Mailbox *m, struct Email *e)
 Save message to the header cache - Wrapper for MxOps::msg_save_hcache() 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_parent (char *buf, size_t buflen)
 Find the parent of a mailbox path - Wrapper for MxOps::path_parent() More...
 
int mx_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a mailbox path - Wrapper for MxOps::path_pretty() More...
 
enum MailboxType mx_path_probe (const char *path)
 Find a mailbox that understands a path. More...
 
struct Mailboxmx_path_resolve (const char *path)
 Get a Mailbox for a path. More...
 
struct Mailboxmx_resolve (const char *path_or_name)
 Get a Mailbox from either a path or name. More...
 
int mx_tags_commit (struct Mailbox *m, struct Email *e, char *tags)
 Save tags to the Mailbox - Wrapper for MxOps::tags_commit() More...
 
int mx_tags_edit (struct Mailbox *m, const char *tags, char *buf, size_t buflen)
 start the tag editor of the mailbox More...
 
enum MailboxType mx_type (struct Mailbox *m)
 Return the type of the Mailbox. 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...
 
bool mx_mbox_ac_link (struct Mailbox *m)
 Link a Mailbox to an existing or new Account. More...
 
bool mx_ac_add (struct Account *a, struct Mailbox *m)
 Add a Mailbox to an Account - Wrapper for MxOps::ac_add() More...
 
int mx_ac_remove (struct Mailbox *m)
 Remove a Mailbox from an Account and delete Account if empty. More...
 
int mx_access (const char *path, int flags)
 Wrapper for access, checks permissions on a given mailbox. 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...
 
void mx_fastclose_mailbox (struct Mailbox *m)
 free up memory associated with the Mailbox More...
 
const struct MxOpsmx_get_ops (enum MailboxType type)
 Get mailbox operations. More...
 
bool mx_tags_is_supported (struct Mailbox *m)
 return true if mailbox support tagging More...
 
int mx_toggle_write (struct Mailbox *m)
 Toggle the mailbox's readonly flag. More...
 

Variables

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

Detailed Description

API for mailboxes.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • Richard Russon

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.h.

Macro Definition Documentation

◆ MUTT_MSG_NO_FLAGS

#define MUTT_MSG_NO_FLAGS   0

No flags are set.

Definition at line 41 of file mx.h.

◆ MUTT_ADD_FROM

#define MUTT_ADD_FROM   (1 << 0)

add a From_ line

Definition at line 42 of file mx.h.

◆ MUTT_SET_DRAFT

#define MUTT_SET_DRAFT   (1 << 1)

set the message draft flag

Definition at line 43 of file mx.h.

Typedef Documentation

◆ MsgOpenFlags

typedef uint8_t MsgOpenFlags

Flags for mx_msg_open_new(), e.g. MUTT_ADD_FROM.

Definition at line 40 of file mx.h.

Function Documentation

◆ mx_mbox_check()

enum MxStatus mx_mbox_check ( struct Mailbox m)

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

Parameters
mMailbox
Return values
enumMxStatus

Definition at line 1119 of file mx.c.

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

◆ mx_mbox_check_stats()

enum MxStatus mx_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)

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

Definition at line 1789 of file mx.c.

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

◆ mx_mbox_close()

enum MxStatus mx_mbox_close ( struct Mailbox m)

Save changes and close mailbox.

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

Definition at line 610 of file mx.c.

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

◆ mx_mbox_open()

bool mx_mbox_open ( struct Mailbox m,
OpenMailboxFlags  flags 
)

Open a mailbox and parse it.

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

Definition at line 304 of file mx.c.

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

◆ mx_mbox_sync()

enum MxStatus mx_mbox_sync ( struct Mailbox m)

Save changes to mailbox.

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

Definition at line 916 of file mx.c.

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

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

1187 {
1188  if (!m || !msg || !*msg)
1189  return 0;
1190 
1191  int rc = 0;
1192 
1193  if (m->mx_ops && m->mx_ops->msg_close)
1194  rc = m->mx_ops->msg_close(m, *msg);
1195 
1196  if ((*msg)->path)
1197  {
1198  mutt_debug(LL_DEBUG1, "unlinking %s\n", (*msg)->path);
1199  unlink((*msg)->path);
1200  FREE(&(*msg)->path);
1201  }
1202 
1203  FREE(&(*msg)->committed_path);
1204  FREE(msg);
1205  return rc;
1206 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
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)
Definition: mxapi.h:287
+ 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 1165 of file mx.c.

1166 {
1167  if (!m || !m->mx_ops || !m->mx_ops->msg_commit || !msg)
1168  return -1;
1169 
1170  if (!(msg->write && m->append))
1171  {
1172  mutt_debug(LL_DEBUG1, "msg->write = %d, m->append = %d\n", msg->write, m->append);
1173  return -1;
1174  }
1175 
1176  return m->mx_ops->msg_commit(m, msg);
1177 }
int(* msg_commit)(struct Mailbox *m, struct Message *msg)
Definition: mxapi.h:271
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
bool write
nonzero if message is open for writing
Definition: mxapi.h:46
Log at debug level 1.
Definition: logging.h:40
+ 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 1054 of file mx.c.

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

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

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

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

1541 {
1542  if (!m || !m->mx_ops || !m->mx_ops->msg_padding_size)
1543  return 0;
1544 
1545  return m->mx_ops->msg_padding_size(m);
1546 }
int(* msg_padding_size)(struct Mailbox *m)
Definition: mxapi.h:300
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ 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 1806 of file mx.c.

1807 {
1808  if (!m || !m->mx_ops || !m->mx_ops->msg_save_hcache || !e)
1809  return 0;
1810 
1811  return m->mx_ops->msg_save_hcache(m, e);
1812 }
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Definition: mxapi.h:316
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ 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 1363 of file mx.c.

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

1469 {
1470  if (!m)
1471  return -1;
1472 
1473  char buf[PATH_MAX];
1474 
1475  if (m->realpath)
1476  mutt_str_copy(buf, m->realpath, sizeof(buf));
1477  else
1478  mutt_str_copy(buf, mailbox_path(m), sizeof(buf));
1479 
1480  int rc = mx_path_canon(buf, sizeof(buf), folder, &m->type);
1481 
1482  mutt_str_replace(&m->realpath, buf);
1483 
1484  if (rc >= 0)
1485  {
1486  m->mx_ops = mx_get_ops(m->type);
1488  }
1489 
1490  return rc;
1491 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
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:40
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
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:1363
+ Here is the call graph for this function:
+ Here is the caller 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 1524 of file mx.c.

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

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

1497 {
1498  if (!buf)
1499  return -1;
1500 
1501  enum MailboxType type = mx_path_probe(buf);
1502  const struct MxOps *ops = mx_get_ops(type);
1503  if (!ops)
1504  return -1;
1505 
1506  if (!ops->path_canon)
1507  return -1;
1508 
1509  if (ops->path_canon(buf, buflen) < 0)
1510  return -1;
1511 
1512  if (!ops->path_pretty)
1513  return -1;
1514 
1515  if (ops->path_pretty(buf, buflen, folder) < 0)
1516  return -1;
1517 
1518  return 0;
1519 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
int(* path_canon)(char *buf, size_t buflen)
Definition: mxapi.h:382
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mxapi.h:105
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1317
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
int(* path_pretty)(char *buf, size_t buflen, const char *folder)
Definition: mxapi.h:398
Definition: mxapi.h:103
+ Here is the call 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 1317 of file mx.c.

1318 {
1319  if (!path)
1320  return MUTT_UNKNOWN;
1321 
1322  enum MailboxType rc = MUTT_UNKNOWN;
1323 
1324  // First, search the non-local Mailbox types (is_local == false)
1325  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1326  {
1327  if ((*ops)->is_local)
1328  continue;
1329  rc = (*ops)->path_probe(path, NULL);
1330  if (rc != MUTT_UNKNOWN)
1331  return rc;
1332  }
1333 
1334  struct stat st = { 0 };
1335  if (stat(path, &st) != 0)
1336  {
1337  mutt_debug(LL_DEBUG1, "unable to stat %s: %s (errno %d)\n", path, strerror(errno), errno);
1338  return MUTT_UNKNOWN;
1339  }
1340 
1341  if (S_ISFIFO(st.st_mode))
1342  {
1343  mutt_error(_("Can't open %s: it is a pipe"), path);
1344  return MUTT_UNKNOWN;
1345  }
1346 
1347  // Next, search the local Mailbox types (is_local == true)
1348  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1349  {
1350  if (!(*ops)->is_local)
1351  continue;
1352  rc = (*ops)->path_probe(path, &st);
1353  if (rc != MUTT_UNKNOWN)
1354  return rc;
1355  }
1356 
1357  return rc;
1358 }
#define mutt_error(...)
Definition: logging.h:88
#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
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Log at debug level 1.
Definition: logging.h:40
Definition: mxapi.h:103
+ 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 1668 of file mx.c.

1669 {
1670  if (!path)
1671  return NULL;
1672 
1673  struct Mailbox *m = mx_mbox_find2(path);
1674  if (m)
1675  return m;
1676 
1677  m = mailbox_new();
1678  m->flags = MB_HIDDEN;
1679  mutt_buffer_strcpy(&m->pathbuf, path);
1680  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1681  mx_path_canon2(m, c_folder);
1682 
1683  return m;
1684 }
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1468
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1640
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MB_HIDDEN
Definition: mailbox.h:38
A mailbox.
Definition: mailbox.h:81
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
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:68
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Buffer pathbuf
Definition: mailbox.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

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

1291 {
1292  if (!m || !e || !tags)
1293  return -1;
1294 
1295  if (m->mx_ops->tags_commit)
1296  return m->mx_ops->tags_commit(m, e, tags);
1297 
1298  mutt_message(_("Folder doesn't support tagging, aborting"));
1299  return -1;
1300 }
#define _(a)
Definition: message.h:28
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
#define mutt_message(...)
Definition: logging.h:87
int(* tags_commit)(struct Mailbox *m, struct Email *e, char *buf)
Definition: mxapi.h:353
+ 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 1270 of file mx.c.

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

◆ mx_type()

enum MailboxType mx_type ( struct Mailbox m)

Return the type of the Mailbox.

Parameters
mMailbox
Return values
enumMailboxType

Definition at line 1819 of file mx.c.

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

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

1555 {
1556  if (!m || !m->mx_ops || !m->realpath)
1557  return NULL;
1558 
1559  struct Account *np = NULL;
1560  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1561  {
1562  if (np->type != m->type)
1563  continue;
1564 
1565  if (m->mx_ops->ac_owns_path(np, m->realpath))
1566  return np;
1567  }
1568 
1569  return NULL;
1570 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
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)
Definition: mxapi.h:123
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 1578 of file mx.c.

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

1641 {
1642  if (!path)
1643  return NULL;
1644 
1645  char buf[PATH_MAX];
1646  mutt_str_copy(buf, path, sizeof(buf));
1647  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
1648  mx_path_canon(buf, sizeof(buf), c_folder, NULL);
1649 
1650  struct Account *np = NULL;
1651  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1652  {
1653  struct Mailbox *m = mx_mbox_find(np, buf);
1654  if (m)
1655  return m;
1656  }
1657 
1658  return NULL;
1659 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
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:1578
Container for Accounts, Notifications.
Definition: neomutt.h:36
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:40
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
char * path
Path.
Definition: url.h:75
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mx_path_canon(char *buf, size_t buflen, const char *folder, enum MailboxType *type)
Canonicalise a mailbox path - Wrapper for MxOps::path_canon()
Definition: mx.c:1363
+ 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 267 of file mx.c.

268 {
269  if (!m)
270  return false;
271 
272  if (m->account)
273  return true;
274 
275  struct Account *a = mx_ac_find(m);
276  const bool new_account = !a;
277  if (new_account)
278  {
279  a = account_new(NULL, NeoMutt->sub);
280  a->type = m->type;
281  }
282  if (!mx_ac_add(a, m))
283  {
284  if (new_account)
285  {
286  FREE(&a);
287  }
288  return false;
289  }
290  if (new_account)
291  {
293  }
294  return true;
295 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
struct Account * mx_ac_find(struct Mailbox *m)
Find the Account owning a Mailbox.
Definition: mx.c:1554
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Account * account_new(const char *name, struct ConfigSubset *sub)
Create a new Account.
Definition: account.c:42
bool mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1756
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_ac_add()

bool mx_ac_add ( struct Account a,
struct Mailbox m 
)

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

Definition at line 1756 of file mx.c.

1757 {
1758  if (!a || !m || !m->mx_ops || !m->mx_ops->ac_add)
1759  return false;
1760 
1761  return m->mx_ops->ac_add(a, m) && account_mailbox_add(a, m);
1762 }
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
bool account_mailbox_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account.
Definition: account.c:65
bool(* ac_add)(struct Account *a, struct Mailbox *m)
Definition: mxapi.h:139
+ 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
Return values
0Success
-1Error
Note
The mailbox is NOT free'd

Definition at line 1772 of file mx.c.

1773 {
1774  if (!m || !m->account)
1775  return -1;
1776 
1777  struct Account *a = m->account;
1779  if (STAILQ_EMPTY(&a->mailboxes))
1780  {
1782  }
1783  return 0;
1784 }
struct MailboxList mailboxes
List of Mailboxes.
Definition: account.h:41
A group of associated Mailboxes.
Definition: account.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:95
#define STAILQ_EMPTY(head)
Definition: queue.h:348
bool neomutt_account_remove(struct NeoMutt *n, struct Account *a)
Remove an Account from the global list.
Definition: neomutt.c:106
+ 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 184 of file mx.c.

185 {
186 #ifdef USE_IMAP
187  if (imap_path_probe(path, NULL) == MUTT_IMAP)
188  return imap_access(path);
189 #endif
190 
191  return access(path, flags);
192 }
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
int imap_access(const char *path)
Check permissions on an IMAP mailbox with a new connection.
Definition: imap.c:474
&#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_alloc_memory()

void mx_alloc_memory ( struct Mailbox m)

Create storage for the emails.

Parameters
mMailbox

Definition at line 1212 of file mx.c.

1213 {
1214  size_t s = MAX(sizeof(struct Email *), sizeof(int));
1215 
1216  if ((m->email_max + 25) * s < m->email_max * s)
1217  {
1218  mutt_error(_("Out of memory"));
1219  mutt_exit(1);
1220  }
1221 
1222  m->email_max += 25;
1223  if (m->emails)
1224  {
1225  mutt_mem_realloc(&m->emails, sizeof(struct Email *) * m->email_max);
1226  mutt_mem_realloc(&m->v2r, sizeof(int) * m->email_max);
1227  }
1228  else
1229  {
1230  m->emails = mutt_mem_calloc(m->email_max, sizeof(struct Email *));
1231  m->v2r = mutt_mem_calloc(m->email_max, sizeof(int));
1232  }
1233  for (int i = m->email_max - 25; i < m->email_max; i++)
1234  {
1235  m->emails[i] = NULL;
1236  m->v2r[i] = -1;
1237  }
1238 }
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 mutt_error(...)
Definition: logging.h:88
#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:279
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
+ 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 1247 of file mx.c.

1248 {
1249  if (!path || (*path == '\0'))
1250  return -1;
1251 
1252  enum MailboxType type = mx_path_probe(path);
1253  const struct MxOps *ops = mx_get_ops(type);
1254  if (!ops || !ops->path_is_empty)
1255  return -1;
1256 
1257  return ops->path_is_empty(path);
1258 }
const struct MxOps * mx_get_ops(enum MailboxType type)
Get mailbox operations.
Definition: mx.c:141
int(* path_is_empty)(const char *path)
Definition: mxapi.h:428
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1317
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Definition: mxapi.h:103
+ 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 429 of file mx.c.

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

◆ 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 }
enum MailboxType type
Mailbox type, e.g. MUTT_IMAP.
Definition: mxapi.h:105
const struct MxOps * mx_ops[]
All the Mailbox backends.
Definition: mx.c:107
Definition: mxapi.h:103
+ 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 1307 of file mx.c.

1308 {
1309  return m && m->mx_ops->tags_commit && m->mx_ops->tags_edit;
1310 }
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Definition: mxapi.h:335
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
int(* tags_commit)(struct Mailbox *m, struct Email *e, char *buf)
Definition: mxapi.h:353
+ Here is the caller graph for this function:

◆ mx_toggle_write()

int mx_toggle_write ( struct Mailbox m)

Toggle the mailbox's readonly flag.

Parameters
mMailbox
Return values
0Success
-1Error

Definition at line 1830 of file mx.c.

1831 {
1832  if (!m)
1833  return -1;
1834 
1835  if (m->readonly)
1836  {
1837  mutt_error(_("Can't toggle write on a readonly mailbox"));
1838  return -1;
1839  }
1840 
1841  if (m->dontwrite)
1842  {
1843  m->dontwrite = false;
1844  mutt_message(_("Changes to folder will be written on folder exit"));
1845  }
1846  else
1847  {
1848  m->dontwrite = true;
1849  mutt_message(_("Changes to folder will not be written"));
1850  }
1851 
1852  return 0;
1853 }
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
#define mutt_message(...)
Definition: logging.h:87

Variable Documentation

◆ mx_ops

const struct MxOps* mx_ops[]

All the Mailbox backends.

Definition at line 107 of file mx.c.

◆ MboxTypeDef

struct EnumDef MboxTypeDef

Definition at line 98 of file mx.c.