NeoMutt  2020-08-21-74-g346364
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 <time.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.

Data Structures

struct  Message
 A local copy of an email. More...
 
struct  MxOps
 The Mailbox API. More...
 

Macros

#define MUTT_OPEN_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_NOSORT   (1 << 0)
 Do not sort the mailbox after opening it. More...
 
#define MUTT_APPEND   (1 << 1)
 Open mailbox for appending messages. More...
 
#define MUTT_READONLY   (1 << 2)
 Open in read-only mode. More...
 
#define MUTT_QUIET   (1 << 3)
 Do not print any messages. More...
 
#define MUTT_NEWFOLDER   (1 << 4)
 Create a new folder - same as MUTT_APPEND,. More...
 
#define MUTT_PEEK   (1 << 5)
 Revert atime back after taking a look (if applicable) More...
 
#define MUTT_APPENDNEW   (1 << 6)
 Set in mx_open_mailbox_append if the mailbox doesn't exist. More...
 
#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 OpenMailboxFlags
 Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT. More...
 
typedef uint8_t MsgOpenFlags
 Flags for mx_msg_open_new(), e.g. MUTT_ADD_FROM. More...
 

Enumerations

enum  MxCheckReturns { MUTT_NEW_MAIL = 1, MUTT_LOCKED, MUTT_REOPENED, MUTT_FLAGS }
 Return values from mx_mbox_check() More...
 

Functions

int mx_mbox_check (struct Mailbox *m)
 Check for new mail - Wrapper for MxOps::mbox_check() More...
 
int mx_mbox_check_stats (struct Mailbox *m, int flags)
 Check the statistics for a mailbox - Wrapper for MxOps::mbox_check_stats() More...
 
int mx_mbox_close (struct Context **ptr)
 Save changes and close mailbox. More...
 
struct Contextmx_mbox_open (struct Mailbox *m, OpenMailboxFlags flags)
 Open a mailbox and parse it. More...
 
int 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...
 
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...
 
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_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_check_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...
 

Variables

const struct MxOpsmx_ops []
 All the Mailbox backends. More...
 
bool C_KeepFlagged
 Config: Don't move flagged messages from C_Spoolfile to C_Mbox. More...
 
unsigned char C_MboxType
 Config: Default type for creating new mailboxes. More...
 
unsigned char C_Move
 Config: Move emails from C_Spoolfile to C_Mbox when read. More...
 
char * C_Trash
 Config: Folder to put deleted emails. 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_OPEN_NO_FLAGS

#define MUTT_OPEN_NO_FLAGS   0

No flags are set.

Definition at line 51 of file mx.h.

◆ MUTT_NOSORT

#define MUTT_NOSORT   (1 << 0)

Do not sort the mailbox after opening it.

Definition at line 52 of file mx.h.

◆ MUTT_APPEND

#define MUTT_APPEND   (1 << 1)

Open mailbox for appending messages.

Definition at line 53 of file mx.h.

◆ MUTT_READONLY

#define MUTT_READONLY   (1 << 2)

Open in read-only mode.

Definition at line 54 of file mx.h.

◆ MUTT_QUIET

#define MUTT_QUIET   (1 << 3)

Do not print any messages.

Definition at line 55 of file mx.h.

◆ MUTT_NEWFOLDER

#define MUTT_NEWFOLDER   (1 << 4)

Create a new folder - same as MUTT_APPEND,.

but uses mutt_file_fopen() with mode "w" for mbox-style folders. This will truncate an existing file.

Definition at line 56 of file mx.h.

◆ MUTT_PEEK

#define MUTT_PEEK   (1 << 5)

Revert atime back after taking a look (if applicable)

Definition at line 59 of file mx.h.

◆ MUTT_APPENDNEW

#define MUTT_APPENDNEW   (1 << 6)

Set in mx_open_mailbox_append if the mailbox doesn't exist.

Used by maildir/mh to create the mailbox.

Definition at line 60 of file mx.h.

◆ MUTT_MSG_NO_FLAGS

#define MUTT_MSG_NO_FLAGS   0

No flags are set.

Definition at line 64 of file mx.h.

◆ MUTT_ADD_FROM

#define MUTT_ADD_FROM   (1 << 0)

add a From_ line

Definition at line 65 of file mx.h.

◆ MUTT_SET_DRAFT

#define MUTT_SET_DRAFT   (1 << 1)

set the message draft flag

Definition at line 66 of file mx.h.

Typedef Documentation

◆ OpenMailboxFlags

typedef uint8_t OpenMailboxFlags

Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.

Definition at line 50 of file mx.h.

◆ MsgOpenFlags

typedef uint8_t MsgOpenFlags

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

Definition at line 63 of file mx.h.

Enumeration Type Documentation

◆ MxCheckReturns

Return values from mx_mbox_check()

Enumerator
MUTT_NEW_MAIL 

New mail received in Mailbox.

MUTT_LOCKED 

Couldn't lock the Mailbox.

MUTT_REOPENED 

Mailbox was reopened.

MUTT_FLAGS 

Nondestructive flags change (IMAP)

Definition at line 71 of file mx.h.

72 {
73  MUTT_NEW_MAIL = 1,
74  MUTT_LOCKED,
76  MUTT_FLAGS,
77 };
Nondestructive flags change (IMAP)
Definition: mx.h:76
Couldn&#39;t lock the Mailbox.
Definition: mx.h:74
New mail received in Mailbox.
Definition: mx.h:73
Mailbox was reopened.
Definition: mx.h:75

Function Documentation

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

1140 {
1141  if (!m || !m->mx_ops)
1142  return -1;
1143 
1144  int rc = m->mx_ops->mbox_check(m);
1145  if ((rc == MUTT_NEW_MAIL) || (rc == MUTT_REOPENED))
1147 
1148  return rc;
1149 }
Email list was changed.
Definition: mailbox.h:171
int(* mbox_check)(struct Mailbox *m)
Check for new mail.
Definition: mx.h:152
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:174
+ 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,
int  flags 
)

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

Definition at line 1817 of file mx.c.

1818 {
1819  if (!m)
1820  return -1;
1821 
1822  return m->mx_ops->mbox_check_stats(m, flags);
1823 }
int(* mbox_check_stats)(struct Mailbox *m, int flags)
Check the Mailbox statistics.
Definition: mx.h:162
const struct MxOps * mx_ops
MXAPI callback functions.
Definition: mailbox.h:111
+ 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)) && !mutt_is_spool(mutt_b2s(mbox));
706  }
707 
708  if (is_spool && !mutt_buffer_is_empty(mbox))
709  {
711  mutt_buffer_printf(buf,
712  /* L10N: The first argument is the number of read messages to be
713  moved, the second argument is the target mailbox. */
714  ngettext("Move %d read message to %s?",
715  "Move %d read messages to %s?", read_msgs),
716  read_msgs, mutt_b2s(mbox));
717  move_messages = query_quadoption(C_Move, mutt_b2s(buf));
718  if (move_messages == MUTT_ABORT)
719  goto cleanup;
720  }
721  }
722 
723  /* There is no point in asking whether or not to purge if we are
724  * just marking messages as "trash". */
725  if ((m->msg_deleted != 0) && !((m->type == MUTT_MAILDIR) && C_MaildirTrash))
726  {
727  mutt_buffer_printf(buf,
728  ngettext("Purge %d deleted message?",
729  "Purge %d deleted messages?", m->msg_deleted),
730  m->msg_deleted);
731  purge = query_quadoption(C_Delete, mutt_b2s(buf));
732  if (purge == MUTT_ABORT)
733  goto cleanup;
734  }
735 
736  if (C_MarkOld && !m->peekonly)
737  {
738  for (i = 0; i < m->msg_count; i++)
739  {
740  struct Email *e = m->emails[i];
741  if (!e)
742  break;
743  if (!e->deleted && !e->old && !e->read)
744  mutt_set_flag(m, e, MUTT_OLD, true);
745  }
746  }
747 
748  if (move_messages)
749  {
750  if (m->verbose)
751  mutt_message(_("Moving read messages to %s..."), mutt_b2s(mbox));
752 
753 #ifdef USE_IMAP
754  /* try to use server-side copy first */
755  i = 1;
756 
757  if ((m->type == MUTT_IMAP) && (imap_path_probe(mutt_b2s(mbox), NULL) == MUTT_IMAP))
758  {
759  /* add messages for moving, and clear old tags, if any */
760  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
761  for (i = 0; i < m->msg_count; i++)
762  {
763  struct Email *e = m->emails[i];
764  if (!e)
765  break;
766 
767  if (e->read && !e->deleted && !(e->flagged && C_KeepFlagged))
768  {
769  e->tagged = true;
770  emaillist_add_email(&el, e);
771  }
772  else
773  e->tagged = false;
774  }
775 
776  i = imap_copy_messages(ctx->mailbox, &el, mutt_b2s(mbox), true);
777  emaillist_clear(&el);
778  }
779 
780  if (i == 0) /* success */
782  else if (i == -1) /* horrible error, bail */
783  goto cleanup;
784  else /* use regular append-copy mode */
785 #endif
786  {
787  struct Mailbox *m_read = mx_path_resolve(mutt_b2s(mbox));
788  struct Context *ctx_read = mx_mbox_open(m_read, MUTT_APPEND);
789  if (!ctx_read)
790  {
791  mailbox_free(&m_read);
792  goto cleanup;
793  }
794 
795  for (i = 0; i < m->msg_count; i++)
796  {
797  struct Email *e = m->emails[i];
798  if (!e)
799  break;
800  if (e->read && !e->deleted && !(e->flagged && C_KeepFlagged))
801  {
802  if (mutt_append_message(ctx_read->mailbox, ctx->mailbox, e,
804  {
805  mutt_set_flag(m, e, MUTT_DELETE, true);
806  mutt_set_flag(m, e, MUTT_PURGE, true);
807  }
808  else
809  {
810  mx_mbox_close(&ctx_read);
811  goto cleanup;
812  }
813  }
814  }
815 
816  mx_mbox_close(&ctx_read);
817  }
818  }
819  else if (!m->changed && (m->msg_deleted == 0))
820  {
821  if (m->verbose)
822  mutt_message(_("Mailbox is unchanged"));
823  if ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF))
824  mbox_reset_atime(m, NULL);
826  ctx_free(ptr);
827  rc = 0;
828  goto cleanup;
829  }
830 
831  /* copy mails to the trash before expunging */
832  const struct Mailbox *m_trash = mx_mbox_find(m->account, C_Trash);
833  if (purge && (m->msg_deleted != 0) && (m != m_trash))
834  {
835  if (trash_append(ctx->mailbox) != 0)
836  goto cleanup;
837  }
838 
839 #ifdef USE_IMAP
840  /* allow IMAP to preserve the deleted flag across sessions */
841  if (m->type == MUTT_IMAP)
842  {
843  int check = imap_sync_mailbox(ctx->mailbox, (purge != MUTT_NO), true);
844  if (check < 0)
845  {
846  rc = check;
847  goto cleanup;
848  }
849  }
850  else
851 #endif
852  {
853  if (purge == MUTT_NO)
854  {
855  for (i = 0; i < m->msg_count; i++)
856  {
857  struct Email *e = m->emails[i];
858  if (!e)
859  break;
860 
861  e->deleted = false;
862  e->purge = false;
863  }
864  m->msg_deleted = 0;
865  }
866 
867  if (m->changed || (m->msg_deleted != 0))
868  {
869  int check = sync_mailbox(ctx->mailbox);
870  if (check != 0)
871  {
872  rc = check;
873  goto cleanup;
874  }
875  }
876  }
877 
878  if (m->verbose)
879  {
880  if (move_messages)
881  {
882  mutt_message(_("%d kept, %d moved, %d deleted"),
883  m->msg_count - m->msg_deleted, read_msgs, m->msg_deleted);
884  }
885  else
886  mutt_message(_("%d kept, %d deleted"), m->msg_count - m->msg_deleted, m->msg_deleted);
887  }
888 
889  if ((m->msg_count == m->msg_deleted) &&
890  ((m->type == MUTT_MMDF) || (m->type == MUTT_MBOX)) &&
892  {
894  }
895 
896 #ifdef USE_SIDEBAR
897  if ((purge == MUTT_YES) && (m->msg_deleted != 0))
898  {
899  for (i = 0; i < m->msg_count; i++)
900  {
901  struct Email *e = m->emails[i];
902  if (!e)
903  break;
904  if (e->deleted && !e->read)
905  {
906  m->msg_unread--;
907  if (!e->old)
908  m->msg_new--;
909  }
910  if (e->deleted && e->flagged)
911  m->msg_flagged--;
912  }
913  }
914 #endif
915 
917  ctx_free(ptr);
918 
919  rc = 0;
920 
921 cleanup:
924  return rc;
925 }
#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:201
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:157
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2370
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
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:151
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 C_Spoolfile to C_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:1607
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
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:1494
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:60
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
#define mutt_b2s(buf)
Definition: buffer.h:41
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:1560
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:149
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
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:130
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:39
int mutt_append_message(struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:898
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1696
#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 C_Spoolfile to C_Mbox.
Definition: mx.c:83
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1293
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_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:201
int ctx_mailbox_observer(struct NotifyCallback *nc)
Watch for changes affecting the Context - Implements observer_t.
Definition: context.c:302
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
#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:366
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:135
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:74
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:110
#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:1353
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:41
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
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
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_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 937 of file mx.c.

938 {
939  if (!m)
940  return -1;
941 
942  int rc;
943  int purge = 1;
944  int msgcount, deleted;
945 
946  if (m->dontwrite)
947  {
948  char buf[256], tmp[256];
949  if (km_expand_key(buf, sizeof(buf), km_find_func(MENU_MAIN, OP_TOGGLE_WRITE)))
950  snprintf(tmp, sizeof(tmp), _(" Press '%s' to toggle write"), buf);
951  else
952  mutt_str_copy(tmp, _("Use 'toggle-write' to re-enable write"), sizeof(tmp));
953 
954  mutt_error(_("Mailbox is marked unwritable. %s"), tmp);
955  return -1;
956  }
957  else if (m->readonly)
958  {
959  mutt_error(_("Mailbox is read-only"));
960  return -1;
961  }
962 
963  if (!m->changed && (m->msg_deleted == 0))
964  {
965  if (m->verbose)
966  mutt_message(_("Mailbox is unchanged"));
967  return 0;
968  }
969 
970  if (m->msg_deleted != 0)
971  {
972  char buf[128];
973 
974  snprintf(buf, sizeof(buf),
975  ngettext("Purge %d deleted message?", "Purge %d deleted messages?", m->msg_deleted),
976  m->msg_deleted);
977  purge = query_quadoption(C_Delete, buf);
978  if (purge == MUTT_ABORT)
979  return -1;
980  if (purge == MUTT_NO)
981  {
982  if (!m->changed)
983  return 0; /* nothing to do! */
984  /* let IMAP servers hold on to D flags */
985  if (m->type != MUTT_IMAP)
986  {
987  for (int i = 0; i < m->msg_count; i++)
988  {
989  struct Email *e = m->emails[i];
990  if (!e)
991  break;
992  e->deleted = false;
993  e->purge = false;
994  }
995  m->msg_deleted = 0;
996  }
997  }
999  }
1000 
1001  /* really only for IMAP - imap_sync_mailbox results in a call to
1002  * ctx_update_tables, so m->msg_deleted is 0 when it comes back */
1003  msgcount = m->msg_count;
1004  deleted = m->msg_deleted;
1005 
1006  const struct Mailbox *m_trash = mx_mbox_find(m->account, C_Trash);
1007  if (purge && (m->msg_deleted != 0) && (m != m_trash))
1008  {
1009  if (trash_append(m) != 0)
1010  return -1;
1011  }
1012 
1013 #ifdef USE_IMAP
1014  if (m->type == MUTT_IMAP)
1015  rc = imap_sync_mailbox(m, purge, false);
1016  else
1017 #endif
1018  rc = sync_mailbox(m);
1019  if (rc >= 0)
1020  {
1021 #ifdef USE_IMAP
1022  if ((m->type == MUTT_IMAP) && !purge)
1023  {
1024  if (m->verbose)
1025  mutt_message(_("Mailbox checkpointed"));
1026  }
1027  else
1028 #endif
1029  {
1030  if (m->verbose)
1031  mutt_message(_("%d kept, %d deleted"), msgcount - deleted, deleted);
1032  }
1033 
1034  mutt_sleep(0);
1035 
1036  if ((m->msg_count == m->msg_deleted) &&
1037  ((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) &&
1039  {
1040  unlink(mailbox_path(m));
1042  return 0;
1043  }
1044 
1045  /* if we haven't deleted any messages, we don't need to resort */
1046  /* ... except for certain folder formats which need "unsorted"
1047  * sort order in order to synchronize folders.
1048  *
1049  * MH and maildir are safe. mbox-style seems to need re-sorting,
1050  * at least with the new threading code. */
1051  if (purge || ((m->type != MUTT_MAILDIR) && (m->type != MUTT_MH)))
1052  {
1053  /* IMAP does this automatically after handling EXPUNGE */
1054  if (m->type != MUTT_IMAP)
1055  {
1058  }
1059  }
1060  }
1061 
1062  return rc;
1063 }
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:201
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:175
WHERE bool C_SaveEmpty
Config: (mbox,mmdf) Preserve empty mailboxes.
Definition: mutt_globals.h:157
Update internal tables.
Definition: mailbox.h:174
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:1607
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:1494
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:1446
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:172
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:174
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_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 1206 of file mx.c.

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

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

1073 {
1074  if (!m)
1075  return NULL;
1076 
1077  struct Address *p = NULL;
1078  struct Message *msg = NULL;
1079 
1080  if (!m->mx_ops || !m->mx_ops->msg_open_new)
1081  {
1082  mutt_debug(LL_DEBUG1, "function unimplemented for mailbox type %d\n", m->type);
1083  return NULL;
1084  }
1085 
1086  msg = mutt_mem_calloc(1, sizeof(struct Message));
1087  msg->write = true;
1088 
1089  if (e)
1090  {
1091  msg->flags.flagged = e->flagged;
1092  msg->flags.replied = e->replied;
1093  msg->flags.read = e->read;
1094  msg->flags.draft = (flags & MUTT_SET_DRAFT);
1095  msg->received = e->received;
1096  }
1097 
1098  if (msg->received == 0)
1099  msg->received = mutt_date_epoch();
1100 
1101  if (m->mx_ops->msg_open_new(m, msg, e) == 0)
1102  {
1103  if (m->type == MUTT_MMDF)
1104  fputs(MMDF_SEP, msg->fp);
1105 
1106  if (((m->type == MUTT_MBOX) || (m->type == MUTT_MMDF)) && (flags & MUTT_ADD_FROM))
1107  {
1108  if (e)
1109  {
1110  p = TAILQ_FIRST(&e->env->return_path);
1111  if (!p)
1112  p = TAILQ_FIRST(&e->env->sender);
1113  if (!p)
1114  p = TAILQ_FIRST(&e->env->from);
1115  }
1116 
1117  // Force a 'C' locale for the date, so that day/month names are in English
1118  locale_t loc = newlocale(LC_TIME_MASK, "C", 0);
1119  char buf[64] = { 0 };
1120  struct tm tm = mutt_date_localtime(msg->received);
1121  strftime_l(buf, sizeof(buf), "%a %b %e %H:%M:%S %Y", &tm, loc);
1122  freelocale(loc);
1123  fprintf(msg->fp, "From %s %s\n", p ? p->mailbox : NONULL(Username), buf);
1124  }
1125  }
1126  else
1127  FREE(&msg);
1128 
1129  return msg;
1130 }
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:198
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_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 1158 of file mx.c.

1159 {
1160  if (!m)
1161  return NULL;
1162 
1163  struct Message *msg = NULL;
1164 
1165  if (!m->mx_ops || !m->mx_ops->msg_open)
1166  {
1167  mutt_debug(LL_DEBUG1, "function not implemented for mailbox type %d\n", m->type);
1168  return NULL;
1169  }
1170 
1171  msg = mutt_mem_calloc(1, sizeof(struct Message));
1172  if (m->mx_ops->msg_open(m, msg, msgno) < 0)
1173  FREE(&msg);
1174 
1175  return msg;
1176 }
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
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:188
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_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 1569 of file mx.c.

1570 {
1571  if (!m || !m->mx_ops || !m->mx_ops->msg_padding_size)
1572  return 0;
1573 
1574  return m->mx_ops->msg_padding_size(m);
1575 }
int(* msg_padding_size)(struct Mailbox *m)
Bytes of padding between messages.
Definition: mx.h:223
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 1834 of file mx.c.

1835 {
1836  if (!m->mx_ops || !m->mx_ops->msg_save_hcache)
1837  return 0;
1838 
1839  return m->mx_ops->msg_save_hcache(m, e);
1840 }
int(* msg_save_hcache)(struct Mailbox *m, struct Email *e)
Save message to the header cache.
Definition: mx.h:232
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 1399 of file mx.c.

1400 {
1401  if (!buf)
1402  return -1;
1403 
1404  for (size_t i = 0; i < 3; i++)
1405  {
1406  /* Look for !! ! - < > or ^ followed by / or NUL */
1407  if ((buf[0] == '!') && (buf[1] == '!'))
1408  {
1409  if (((buf[2] == '/') || (buf[2] == '\0')))
1410  {
1411  mutt_str_inline_replace(buf, buflen, 2, LastFolder);
1412  }
1413  }
1414  else if ((buf[0] == '+') || (buf[0] == '='))
1415  {
1416  size_t folder_len = mutt_str_len(folder);
1417  if ((folder_len > 0) && (folder[folder_len - 1] != '/'))
1418  {
1419  buf[0] = '/';
1420  mutt_str_inline_replace(buf, buflen, 0, folder);
1421  }
1422  else
1423  {
1424  mutt_str_inline_replace(buf, buflen, 1, folder);
1425  }
1426  }
1427  else if ((buf[1] == '/') || (buf[1] == '\0'))
1428  {
1429  if (buf[0] == '!')
1430  {
1431  mutt_str_inline_replace(buf, buflen, 1, C_Spoolfile);
1432  }
1433  else if (buf[0] == '-')
1434  {
1435  mutt_str_inline_replace(buf, buflen, 1, LastFolder);
1436  }
1437  else if (buf[0] == '<')
1438  {
1439  mutt_str_inline_replace(buf, buflen, 1, C_Record);
1440  }
1441  else if (buf[0] == '>')
1442  {
1443  mutt_str_inline_replace(buf, buflen, 1, C_Mbox);
1444  }
1445  else if (buf[0] == '^')
1446  {
1447  mutt_str_inline_replace(buf, buflen, 1, CurrentFolder);
1448  }
1449  else if (buf[0] == '~')
1450  {
1451  mutt_str_inline_replace(buf, buflen, 1, HomeDir);
1452  }
1453  }
1454  else if (buf[0] == '@')
1455  {
1456  /* elm compatibility, @ expands alias to user name */
1457  struct AddressList *al = alias_lookup(buf + 1);
1458  if (!al || TAILQ_EMPTY(al))
1459  break;
1460 
1461  struct Email *e = email_new();
1462  e->env = mutt_env_new();
1463  mutt_addrlist_copy(&e->env->from, al, false);
1464  mutt_addrlist_copy(&e->env->to, al, false);
1465  mutt_default_save(buf, buflen, e);
1466  email_free(&e);
1467  break;
1468  }
1469  else
1470  {
1471  break;
1472  }
1473  }
1474 
1475  // if (!folder) //XXX - use inherited version, or pass NULL to backend?
1476  // return -1;
1477 
1478  enum MailboxType type2 = mx_path_probe(buf);
1479  if (type)
1480  *type = type2;
1481  const struct MxOps *ops = mx_get_ops(type2);
1482  if (!ops || !ops->path_canon)
1483  return -1;
1484 
1485  if (ops->path_canon(buf, buflen) < 0)
1486  {
1487  mutt_path_canon(buf, buflen, HomeDir, true);
1488  }
1489 
1490  return 0;
1491 }
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 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
int(* path_canon)(char *buf, size_t buflen)
Canonicalise a Mailbox path.
Definition: mx.h:271
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:1353
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
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
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
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
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 1500 of file mx.c.

1501 {
1502  if (!m)
1503  return -1;
1504 
1505  char buf[PATH_MAX];
1506 
1507  if (m->realpath)
1508  mutt_str_copy(buf, m->realpath, sizeof(buf));
1509  else
1510  mutt_str_copy(buf, mailbox_path(m), sizeof(buf));
1511 
1512  int rc = mx_path_canon(buf, sizeof(buf), folder, &m->type);
1513 
1514  mutt_str_replace(&m->realpath, buf);
1515 
1516  if (rc >= 0)
1517  {
1518  m->mx_ops = mx_get_ops(m->type);
1520  }
1521 
1522  return rc;
1523 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:201
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:1399
+ 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 1553 of file mx.c.

1554 {
1555  if (!buf)
1556  return -1;
1557 
1558  return 0;
1559 }

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

1529 {
1530  enum MailboxType type = mx_path_probe(buf);
1531  const struct MxOps *ops = mx_get_ops(type);
1532  if (!ops)
1533  return -1;
1534 
1535  if (!ops->path_canon)
1536  return -1;
1537 
1538  if (ops->path_canon(buf, buflen) < 0)
1539  return -1;
1540 
1541  if (!ops->path_pretty)
1542  return -1;
1543 
1544  if (ops->path_pretty(buf, buflen, folder) < 0)
1545  return -1;
1546 
1547  return 0;
1548 }
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:271
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:1353
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:281
The Mailbox API.
Definition: mx.h:104
+ 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 1353 of file mx.c.

1354 {
1355  if (!path)
1356  return MUTT_UNKNOWN;
1357 
1358  enum MailboxType rc;
1359 
1360  // First, search the non-local Mailbox types (is_local == false)
1361  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1362  {
1363  if ((*ops)->is_local)
1364  continue;
1365  rc = (*ops)->path_probe(path, NULL);
1366  if (rc != MUTT_UNKNOWN)
1367  return rc;
1368  }
1369 
1370  struct stat st = { 0 };
1371  if (stat(path, &st) != 0)
1372  {
1373  mutt_debug(LL_DEBUG1, "unable to stat %s: %s (errno %d)\n", path, strerror(errno), errno);
1374  return MUTT_UNKNOWN;
1375  }
1376 
1377  if (S_ISFIFO(st.st_mode))
1378  {
1379  mutt_error(_("Can't open %s: it is a pipe"), path);
1380  return MUTT_UNKNOWN;
1381  }
1382 
1383  // Next, search the local Mailbox types (is_local == true)
1384  for (const struct MxOps **ops = mx_ops; *ops; ops++)
1385  {
1386  if (!(*ops)->is_local)
1387  continue;
1388  rc = (*ops)->path_probe(path, &st);
1389  if (rc != MUTT_UNKNOWN)
1390  return rc;
1391  }
1392 
1393  return rc;
1394 }
#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_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 1696 of file mx.c.

1697 {
1698  if (!path)
1699  return NULL;
1700 
1701  struct Mailbox *m = mx_mbox_find2(path);
1702  if (m)
1703  return m;
1704 
1705  m = mailbox_new();
1706  m->flags = MB_HIDDEN;
1707  mutt_buffer_strcpy(&m->pathbuf, path);
1709 
1710  return m;
1711 }
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1500
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1669
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
#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
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:42
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 1765 of file mx.c.

1766 {
1767  if (!path_or_name)
1768  return NULL;
1769 
1770  // Order is name first because you can create a Mailbox from
1771  // a path, but can't from a name. So fallback behavior creates
1772  // a new Mailbox for us.
1773  struct Mailbox *m = mx_mbox_find_by_name(path_or_name);
1774  if (!m)
1775  m = mx_path_resolve(path_or_name);
1776 
1777  return m;
1778 }
static struct Mailbox * mx_mbox_find_by_name(const char *name)
Find a Mailbox with given name.
Definition: mx.c:1740
A mailbox.
Definition: mailbox.h:81
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1696
+ 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 1326 of file mx.c.

1327 {
1328  if (!m)
1329  return -1;
1330 
1331  if (m->mx_ops->tags_commit)
1332  return m->mx_ops->tags_commit(m, e, tags);
1333 
1334  mutt_message(_("Folder doesn't support tagging, aborting"));
1335  return -1;
1336 }
#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:254
+ 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 1306 of file mx.c.

1307 {
1308  if (!m)
1309  return -1;
1310 
1311  if (m->mx_ops->tags_edit)
1312  return m->mx_ops->tags_edit(m, tags, buf, buflen);
1313 
1314  mutt_message(_("Folder doesn't support tagging, aborting"));
1315  return -1;
1316 }
#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:244
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 1583 of file mx.c.

1584 {
1585  if (!m || !m->mx_ops)
1586  return NULL;
1587 
1588  struct Account *np = NULL;
1589  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1590  {
1591  if (np->type != m->type)
1592  continue;
1593 
1594  if (m->mx_ops->ac_find(np, m->realpath))
1595  return np;
1596  }
1597 
1598  return NULL;
1599 }
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
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
struct Account *(* ac_find)(struct Account *a, const char *path)
Find an Account that matches a Mailbox path.
Definition: mx.h:117
+ 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 1607 of file mx.c.

1608 {
1609  if (!a || !path)
1610  return NULL;
1611 
1612  struct MailboxNode *np = NULL;
1613  struct Url *url_p = NULL;
1614  struct Url *url_a = NULL;
1615 
1616  const bool use_url = (a->type == MUTT_IMAP);
1617  if (use_url)
1618  {
1619  url_p = url_parse(path);
1620  if (!url_p)
1621  goto done;
1622  }
1623 
1624  STAILQ_FOREACH(np, &a->mailboxes, entries)
1625  {
1626  if (!use_url)
1627  {
1628  if (mutt_str_equal(np->mailbox->realpath, path))
1629  return np->mailbox;
1630  continue;
1631  }
1632 
1633  url_free(&url_a);
1634  url_a = url_parse(np->mailbox->realpath);
1635  if (!url_a)
1636  continue;
1637 
1638  if (!mutt_istr_equal(url_a->host, url_p->host))
1639  continue;
1640  if (url_p->user && !mutt_istr_equal(url_a->user, url_p->user))
1641  continue;
1642  if (a->type == MUTT_IMAP)
1643  {
1644  if (imap_mxcmp(url_a->path, url_p->path) == 0)
1645  break;
1646  }
1647  else
1648  {
1649  if (mutt_str_equal(url_a->path, url_p->path))
1650  break;
1651  }
1652  }
1653 
1654 done:
1655  url_free(&url_p);
1656  url_free(&url_a);
1657 
1658  if (!np)
1659  return NULL;
1660  return np->mailbox;
1661 }
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:66
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:689
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:69
char * host
Host.
Definition: url.h:71
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * path
Path.
Definition: url.h:73
List of Mailboxes.
Definition: mailbox.h:150
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:152
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 1669 of file mx.c.

1670 {
1671  if (!path)
1672  return NULL;
1673 
1674  char buf[PATH_MAX];
1675  mutt_str_copy(buf, path, sizeof(buf));
1676  mx_path_canon(buf, sizeof(buf), C_Folder, NULL);
1677 
1678  struct Account *np = NULL;
1679  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1680  {
1681  struct Mailbox *m = mx_mbox_find(np, buf);
1682  if (m)
1683  return m;
1684  }
1685 
1686  return NULL;
1687 }
#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:1607
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:73
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:1399
+ 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:1783
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:1583
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_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 1783 of file mx.c.

1784 {
1785  if (!a || !m || !m->mx_ops || !m->mx_ops->ac_add)
1786  return -1;
1787 
1788  if (m->mx_ops->ac_add(a, m) < 0)
1789  return -1;
1790 
1791  account_mailbox_add(a, m);
1792  return 0;
1793 }
int(* ac_add)(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account.
Definition: mx.h:126
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 1799 of file mx.c.

1800 {
1801  if (!m || !m->account)
1802  return -1;
1803 
1804  struct Account *a = m->account;
1806  mailbox_free(&m);
1807  if (STAILQ_EMPTY(&a->mailboxes))
1808  {
1810  }
1811  return 0;
1812 }
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:60
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_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:2370
int imap_access(const char *path)
Check permissions on an IMAP mailbox with a new connection.
Definition: imap.c:451
&#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 1232 of file mx.c.

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

int mx_check_empty ( const char *  path)

Is the mailbox empty.

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

Definition at line 1267 of file mx.c.

1268 {
1269  switch (mx_path_probe(path))
1270  {
1271  case MUTT_MBOX:
1272  case MUTT_MMDF:
1273  return mutt_file_check_empty(path);
1274  case MUTT_MH:
1275  return mh_check_empty(path);
1276  case MUTT_MAILDIR:
1277  return maildir_check_empty(path);
1278 #ifdef USE_IMAP
1279  case MUTT_IMAP:
1280  {
1281  int rc = imap_path_status(path, false);
1282  if (rc < 0)
1283  return -1;
1284  if (rc == 0)
1285  return 1;
1286  return 0;
1287  }
1288 #endif
1289  default:
1290  errno = EINVAL;
1291  return -1;
1292  }
1293  /* not reached */
1294 }
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1199
&#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
int maildir_check_empty(const char *path)
Is the mailbox empty.
Definition: shared.c:1604
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1353
int mutt_file_check_empty(const char *path)
Is the mailbox empty.
Definition: file.c:1412
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
int mh_check_empty(const char *path)
Is mailbox empty.
Definition: shared.c:1644
+ 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
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:178
void mutt_mailbox_set_notified(struct Mailbox *m)
Note when the user was last notified of new mail.
Definition: mutt_mailbox.c:285
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
+ 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
Type of Mailboxes this Account contains.
Definition: account.h:38
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:

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

1344 {
1345  return m && m->mx_ops->tags_commit && m->mx_ops->tags_edit;
1346 }
int(* tags_edit)(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags.
Definition: mx.h:244
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:254
+ Here is the caller graph for this function:

Variable Documentation

◆ mx_ops

const struct MxOps* mx_ops[]

All the Mailbox backends.

Definition at line 107 of file mx.c.

◆ C_KeepFlagged

bool C_KeepFlagged

Config: Don't move flagged messages from C_Spoolfile to C_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 C_Spoolfile to C_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.

◆ MboxTypeDef

struct EnumDef MboxTypeDef

Definition at line 98 of file mx.c.