NeoMutt  2019-12-07-168-gc45f47
Teaching an old dog new tricks
DOXYGEN
imap_private.h File Reference

Shared constants/structs that are private to IMAP. More...

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

Go to the source code of this file.

Data Structures

struct  ImapList
 Items in an IMAP browser. More...
 
struct  ImapCommand
 IMAP command structure. More...
 
struct  ImapAccountData
 IMAP-specific Account data -. More...
 
struct  ImapMboxData
 IMAP-specific Mailbox data -. More...
 
struct  SeqsetIterator
 UID Sequence Set Iterator. More...
 

Macros

#define IMAP_PORT   143
 Default port for IMAP. More...
 
#define IMAP_SSL_PORT   993
 Port for IMAP over SSL/TLS. More...
 
#define IMAP_LOG_CMD   2
 
#define IMAP_LOG_LTRL   3
 
#define IMAP_LOG_PASS   5
 
#define IMAP_RES_NO   -2
 <tag> NO ... More...
 
#define IMAP_RES_BAD   -1
 <tag> BAD ... More...
 
#define IMAP_RES_OK   0
 <tag> OK ... More...
 
#define IMAP_RES_CONTINUE   1
 * ... More...
 
#define IMAP_RES_RESPOND   2
 + More...
 
#define IMAP_RES_NEW   3
 ImapCommand.state additions. More...
 
#define SEQ_LEN   16
 
#define IMAP_MAX_CMDLEN   1024
 Maximum length of command lines before they must be split (for lazy servers) More...
 
#define IMAP_OPEN_NO_FLAGS   0
 No flags are set. More...
 
#define IMAP_REOPEN_ALLOW   (1 << 0)
 Allow re-opening a folder upon expunge. More...
 
#define IMAP_EXPUNGE_EXPECTED   (1 << 1)
 Messages will be expunged from the server. More...
 
#define IMAP_EXPUNGE_PENDING   (1 << 2)
 Messages on the server have been expunged. More...
 
#define IMAP_NEWMAIL_PENDING   (1 << 3)
 New mail is waiting on the server. More...
 
#define IMAP_FLAGS_PENDING   (1 << 4)
 Flags have changed on the server. More...
 
#define IMAP_CMD_NO_FLAGS   0
 No flags are set. More...
 
#define IMAP_CMD_PASS   (1 << 0)
 Command contains a password. Suppress logging. More...
 
#define IMAP_CMD_QUEUE   (1 << 1)
 Queue a command, do not execute. More...
 
#define IMAP_CMD_POLL   (1 << 2)
 Poll the tcp connection before running the imap command. More...
 
#define IMAP_DATELEN   27
 
#define IMAP_CAP_NO_FLAGS   0
 No flags are set. More...
 
#define IMAP_CAP_IMAP4   (1 << 0)
 Server supports IMAP4. More...
 
#define IMAP_CAP_IMAP4REV1   (1 << 1)
 Server supports IMAP4rev1. More...
 
#define IMAP_CAP_STATUS   (1 << 2)
 Server supports STATUS command. More...
 
#define IMAP_CAP_ACL   (1 << 3)
 RFC2086: IMAP4 ACL extension. More...
 
#define IMAP_CAP_NAMESPACE   (1 << 4)
 RFC2342: IMAP4 Namespace. More...
 
#define IMAP_CAP_AUTH_CRAM_MD5   (1 << 5)
 RFC2195: CRAM-MD5 authentication. More...
 
#define IMAP_CAP_AUTH_GSSAPI   (1 << 6)
 RFC1731: GSSAPI authentication. More...
 
#define IMAP_CAP_AUTH_ANONYMOUS   (1 << 7)
 AUTH=ANONYMOUS. More...
 
#define IMAP_CAP_AUTH_OAUTHBEARER   (1 << 8)
 RFC7628: AUTH=OAUTHBEARER. More...
 
#define IMAP_CAP_STARTTLS   (1 << 9)
 RFC2595: STARTTLS. More...
 
#define IMAP_CAP_LOGINDISABLED   (1 << 10)
 RFC2595: LOGINDISABLED. More...
 
#define IMAP_CAP_IDLE   (1 << 11)
 RFC2177: IDLE. More...
 
#define IMAP_CAP_SASL_IR   (1 << 12)
 SASL initial response draft. More...
 
#define IMAP_CAP_ENABLE   (1 << 13)
 RFC5161. More...
 
#define IMAP_CAP_CONDSTORE   (1 << 14)
 RFC7162. More...
 
#define IMAP_CAP_QRESYNC   (1 << 15)
 RFC7162. More...
 
#define IMAP_CAP_LIST_EXTENDED   (1 << 16)
 RFC5258: IMAP4 LIST Command Extensions. More...
 
#define IMAP_CAP_COMPRESS   (1 << 17)
 RFC4978: COMPRESS=DEFLATE. More...
 
#define IMAP_CAP_X_GM_EXT_1   (1 << 18)
 https://developers.google.com/gmail/imap/imap-extensions More...
 
#define IMAP_CAP_ALL   ((1 << 19) - 1)
 

Typedefs

typedef uint8_t ImapOpenFlags
 Flags, e.g. MUTT_THREAD_COLLAPSE. More...
 
typedef uint8_t ImapCmdFlags
 Flags for imap_exec(), e.g. IMAP_CMD_PASS. More...
 
typedef uint32_t ImapCapFlags
 typedef ImapCapFlags - Capabilities we are interested in More...
 

Enumerations

enum  ImapExecResult { IMAP_EXEC_SUCCESS = 0, IMAP_EXEC_ERROR, IMAP_EXEC_FATAL }
 imap_exec return code More...
 
enum  ImapFlags { IMAP_FATAL = 1, IMAP_BYE }
 IMAP server responses. More...
 
enum  ImapState {
  IMAP_DISCONNECTED = 0, IMAP_CONNECTED, IMAP_AUTHENTICATED, IMAP_SELECTED,
  IMAP_IDLE
}
 IMAP connection state. More...
 

Functions

int imap_create_mailbox (struct ImapAccountData *adata, char *mailbox)
 Create a new mailbox. More...
 
int imap_rename_mailbox (struct ImapAccountData *adata, char *oldname, const char *newname)
 Rename a mailbox. More...
 
int imap_exec_msgset (struct Mailbox *m, const char *pre, const char *post, int flag, bool changed, bool invert)
 Prepare commands for all messages matching conditions. More...
 
int imap_open_connection (struct ImapAccountData *adata)
 Open an IMAP connection. More...
 
void imap_close_connection (struct ImapAccountData *adata)
 Close an IMAP connection. More...
 
int imap_read_literal (FILE *fp, struct ImapAccountData *adata, unsigned long bytes, struct Progress *pbar)
 Read bytes bytes from server into file. More...
 
void imap_expunge_mailbox (struct Mailbox *m)
 Purge messages from the server. More...
 
int imap_login (struct ImapAccountData *adata)
 Open an IMAP connection. More...
 
int imap_sync_message_for_copy (struct Mailbox *m, struct Email *e, struct Buffer *cmd, enum QuadOption *err_continue)
 Update server to reflect the flags of a single message. More...
 
bool imap_has_flag (struct ListHead *flag_list, const char *flag)
 Does the flag exist in the list. More...
 
int imap_adata_find (const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
 Find the Account data for this path. More...
 
int imap_authenticate (struct ImapAccountData *adata)
 Authenticate to an IMAP server. More...
 
int imap_cmd_start (struct ImapAccountData *adata, const char *cmdstr)
 Given an IMAP command, send it to the server. More...
 
int imap_cmd_step (struct ImapAccountData *adata)
 Reads server responses from an IMAP command. More...
 
void imap_cmd_finish (struct ImapAccountData *adata)
 Attempt to perform cleanup. More...
 
bool imap_code (const char *s)
 Was the command successful. More...
 
const char * imap_cmd_trailer (struct ImapAccountData *adata)
 Extra information after tagged command response if any. More...
 
int imap_exec (struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
 Execute a command and wait for the response from the server. More...
 
int imap_cmd_idle (struct ImapAccountData *adata)
 Enter the IDLE state. More...
 
void imap_edata_free (void **ptr)
 free ImapHeader structure More...
 
struct ImapEmailDataimap_edata_get (struct Email *e)
 Get the private data for this Email. More...
 
int imap_read_headers (struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool initial_download)
 Read headers from the server. More...
 
char * imap_set_flags (struct Mailbox *m, struct Email *e, char *s, bool *server_changes)
 fill the message header according to the server flags More...
 
int imap_cache_del (struct Mailbox *m, struct Email *e)
 Delete an email from the body cache. More...
 
int imap_cache_clean (struct Mailbox *m)
 Delete all the entries in the message cache. More...
 
int imap_append_message (struct Mailbox *m, struct Message *msg)
 Write an email back to the server. More...
 
int imap_msg_open (struct Mailbox *m, struct Message *msg, int msgno)
 Open an email message in a Mailbox - Implements MxOps::msg_open() More...
 
int imap_msg_close (struct Mailbox *m, struct Message *msg)
 Close an email - Implements MxOps::msg_close() More...
 
int imap_msg_commit (struct Mailbox *m, struct Message *msg)
 Save changes to an email - Implements MxOps::msg_commit() More...
 
int imap_msg_save_hcache (struct Mailbox *m, struct Email *e)
 Save message to the header cache - Implements MxOps::msg_save_hcache() More...
 
struct ImapAccountDataimap_adata_get (struct Mailbox *m)
 Get the Account data for this mailbox. More...
 
struct ImapMboxDataimap_mdata_get (struct Mailbox *m)
 Get the Mailbox data for this mailbox. More...
 
header_cache_timap_hcache_open (struct ImapAccountData *adata, struct ImapMboxData *mdata)
 Open a header cache. More...
 
void imap_hcache_close (struct ImapMboxData *mdata)
 Close the header cache. More...
 
struct Emailimap_hcache_get (struct ImapMboxData *mdata, unsigned int uid)
 Get a header cache entry by its UID. More...
 
int imap_hcache_put (struct ImapMboxData *mdata, struct Email *e)
 Add an entry to the header cache. More...
 
int imap_hcache_del (struct ImapMboxData *mdata, unsigned int uid)
 Delete an item from the header cache. More...
 
int imap_hcache_store_uid_seqset (struct ImapMboxData *mdata)
 Store a UID Sequence Set in the header cache. More...
 
int imap_hcache_clear_uid_seqset (struct ImapMboxData *mdata)
 Delete a UID Sequence Set from the header cache. More...
 
char * imap_hcache_get_uid_seqset (struct ImapMboxData *mdata)
 Get a UID Sequence Set from the header cache. More...
 
enum QuadOption imap_continue (const char *msg, const char *resp)
 display a message and ask the user if they want to go on More...
 
void imap_error (const char *where, const char *msg)
 show an error and abort More...
 
struct ImapAccountDataimap_adata_new (struct Account *a)
 Allocate and initialise a new ImapAccountData structure. More...
 
void imap_adata_free (void **ptr)
 Release and clear storage in an ImapAccountData structure. More...
 
struct ImapMboxDataimap_mdata_new (struct ImapAccountData *adata, const char *name)
 Allocate and initialise a new ImapMboxData structure. More...
 
void imap_mdata_free (void **ptr)
 Release and clear storage in an ImapMboxData structure. More...
 
void imap_mdata_cache_reset (struct ImapMboxData *mdata)
 Release and clear cache data of ImapMboxData structure. More...
 
char * imap_fix_path (char delim, const char *mailbox, char *path, size_t plen)
 Fix up the imap path. More...
 
void imap_cachepath (char delim, const char *mailbox, struct Buffer *dest)
 Generate a cache path for a mailbox. More...
 
int imap_get_literal_count (const char *buf, unsigned int *bytes)
 write number of bytes in an IMAP literal into bytes More...
 
char * imap_get_qualifier (char *buf)
 Get the qualifier from a tagged response. More...
 
char * imap_next_word (char *s)
 Find where the next IMAP word begins. More...
 
void imap_qualify_path (char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
 Make an absolute IMAP folder target. More...
 
void imap_quote_string (char *dest, size_t dlen, const char *src, bool quote_backtick)
 quote string according to IMAP rules More...
 
void imap_unquote_string (char *s)
 equally stupid unquoting routine More...
 
void imap_munge_mbox_name (bool unicode, char *dest, size_t dlen, const char *src)
 Quote awkward characters in a mailbox name. More...
 
void imap_unmunge_mbox_name (bool unicode, char *s)
 Remove quoting from a mailbox name. More...
 
struct SeqsetIteratormutt_seqset_iterator_new (const char *seqset)
 Create a new Sequence Set Iterator. More...
 
int mutt_seqset_iterator_next (struct SeqsetIterator *iter, unsigned int *next)
 Get the next UID from a Sequence Set. More...
 
void mutt_seqset_iterator_free (struct SeqsetIterator **ptr)
 Free a Sequence Set Iterator. More...
 
bool imap_account_match (const struct ConnAccount *a1, const struct ConnAccount *a2)
 Compare two Accounts. More...
 
void imap_get_parent (const char *mbox, char delim, char *buf, size_t buflen)
 Get an IMAP folder's parent. More...
 
bool mutt_account_match (const struct ConnAccount *a1, const struct ConnAccount *a2)
 
void imap_utf_encode (bool unicode, char **s)
 Encode email from local charset to UTF-8. More...
 
void imap_utf_decode (bool unicode, char **s)
 Decode email from UTF-8 to local charset. More...
 
void imap_allow_reopen (struct Mailbox *m)
 Allow re-opening a folder upon expunge. More...
 
void imap_disallow_reopen (struct Mailbox *m)
 Disallow re-opening a folder upon expunge. More...
 

Detailed Description

Shared constants/structs that are private to IMAP.

Authors
  • Brandon Long
  • Brendan Cully
  • 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 imap_private.h.

Macro Definition Documentation

◆ IMAP_PORT

#define IMAP_PORT   143

Default port for IMAP.

Definition at line 43 of file imap_private.h.

◆ IMAP_SSL_PORT

#define IMAP_SSL_PORT   993

Port for IMAP over SSL/TLS.

Definition at line 44 of file imap_private.h.

◆ IMAP_LOG_CMD

#define IMAP_LOG_CMD   2

Definition at line 47 of file imap_private.h.

◆ IMAP_LOG_LTRL

#define IMAP_LOG_LTRL   3

Definition at line 48 of file imap_private.h.

◆ IMAP_LOG_PASS

#define IMAP_LOG_PASS   5

Definition at line 49 of file imap_private.h.

◆ IMAP_RES_NO

#define IMAP_RES_NO   -2

<tag> NO ...

Definition at line 52 of file imap_private.h.

◆ IMAP_RES_BAD

#define IMAP_RES_BAD   -1

<tag> BAD ...

Definition at line 53 of file imap_private.h.

◆ IMAP_RES_OK

#define IMAP_RES_OK   0

<tag> OK ...

Definition at line 54 of file imap_private.h.

◆ IMAP_RES_CONTINUE

#define IMAP_RES_CONTINUE   1

* ...

Definition at line 55 of file imap_private.h.

◆ IMAP_RES_RESPOND

#define IMAP_RES_RESPOND   2

+

Definition at line 56 of file imap_private.h.

◆ IMAP_RES_NEW

#define IMAP_RES_NEW   3

ImapCommand.state additions.

Definition at line 57 of file imap_private.h.

◆ SEQ_LEN

#define SEQ_LEN   16

Definition at line 59 of file imap_private.h.

◆ IMAP_MAX_CMDLEN

#define IMAP_MAX_CMDLEN   1024

Maximum length of command lines before they must be split (for lazy servers)

Definition at line 60 of file imap_private.h.

◆ IMAP_OPEN_NO_FLAGS

#define IMAP_OPEN_NO_FLAGS   0

No flags are set.

Definition at line 63 of file imap_private.h.

◆ IMAP_REOPEN_ALLOW

#define IMAP_REOPEN_ALLOW   (1 << 0)

Allow re-opening a folder upon expunge.

Definition at line 64 of file imap_private.h.

◆ IMAP_EXPUNGE_EXPECTED

#define IMAP_EXPUNGE_EXPECTED   (1 << 1)

Messages will be expunged from the server.

Definition at line 65 of file imap_private.h.

◆ IMAP_EXPUNGE_PENDING

#define IMAP_EXPUNGE_PENDING   (1 << 2)

Messages on the server have been expunged.

Definition at line 66 of file imap_private.h.

◆ IMAP_NEWMAIL_PENDING

#define IMAP_NEWMAIL_PENDING   (1 << 3)

New mail is waiting on the server.

Definition at line 67 of file imap_private.h.

◆ IMAP_FLAGS_PENDING

#define IMAP_FLAGS_PENDING   (1 << 4)

Flags have changed on the server.

Definition at line 68 of file imap_private.h.

◆ IMAP_CMD_NO_FLAGS

#define IMAP_CMD_NO_FLAGS   0

No flags are set.

Definition at line 71 of file imap_private.h.

◆ IMAP_CMD_PASS

#define IMAP_CMD_PASS   (1 << 0)

Command contains a password. Suppress logging.

Definition at line 72 of file imap_private.h.

◆ IMAP_CMD_QUEUE

#define IMAP_CMD_QUEUE   (1 << 1)

Queue a command, do not execute.

Definition at line 73 of file imap_private.h.

◆ IMAP_CMD_POLL

#define IMAP_CMD_POLL   (1 << 2)

Poll the tcp connection before running the imap command.

Definition at line 74 of file imap_private.h.

◆ IMAP_DATELEN

#define IMAP_DATELEN   27

Definition at line 87 of file imap_private.h.

◆ IMAP_CAP_NO_FLAGS

#define IMAP_CAP_NO_FLAGS   0

No flags are set.

Definition at line 119 of file imap_private.h.

◆ IMAP_CAP_IMAP4

#define IMAP_CAP_IMAP4   (1 << 0)

Server supports IMAP4.

Definition at line 120 of file imap_private.h.

◆ IMAP_CAP_IMAP4REV1

#define IMAP_CAP_IMAP4REV1   (1 << 1)

Server supports IMAP4rev1.

Definition at line 121 of file imap_private.h.

◆ IMAP_CAP_STATUS

#define IMAP_CAP_STATUS   (1 << 2)

Server supports STATUS command.

Definition at line 122 of file imap_private.h.

◆ IMAP_CAP_ACL

#define IMAP_CAP_ACL   (1 << 3)

RFC2086: IMAP4 ACL extension.

Definition at line 123 of file imap_private.h.

◆ IMAP_CAP_NAMESPACE

#define IMAP_CAP_NAMESPACE   (1 << 4)

RFC2342: IMAP4 Namespace.

Definition at line 124 of file imap_private.h.

◆ IMAP_CAP_AUTH_CRAM_MD5

#define IMAP_CAP_AUTH_CRAM_MD5   (1 << 5)

RFC2195: CRAM-MD5 authentication.

Definition at line 125 of file imap_private.h.

◆ IMAP_CAP_AUTH_GSSAPI

#define IMAP_CAP_AUTH_GSSAPI   (1 << 6)

RFC1731: GSSAPI authentication.

Definition at line 126 of file imap_private.h.

◆ IMAP_CAP_AUTH_ANONYMOUS

#define IMAP_CAP_AUTH_ANONYMOUS   (1 << 7)

AUTH=ANONYMOUS.

Definition at line 127 of file imap_private.h.

◆ IMAP_CAP_AUTH_OAUTHBEARER

#define IMAP_CAP_AUTH_OAUTHBEARER   (1 << 8)

RFC7628: AUTH=OAUTHBEARER.

Definition at line 128 of file imap_private.h.

◆ IMAP_CAP_STARTTLS

#define IMAP_CAP_STARTTLS   (1 << 9)

RFC2595: STARTTLS.

Definition at line 129 of file imap_private.h.

◆ IMAP_CAP_LOGINDISABLED

#define IMAP_CAP_LOGINDISABLED   (1 << 10)

RFC2595: LOGINDISABLED.

Definition at line 130 of file imap_private.h.

◆ IMAP_CAP_IDLE

#define IMAP_CAP_IDLE   (1 << 11)

RFC2177: IDLE.

Definition at line 131 of file imap_private.h.

◆ IMAP_CAP_SASL_IR

#define IMAP_CAP_SASL_IR   (1 << 12)

SASL initial response draft.

Definition at line 132 of file imap_private.h.

◆ IMAP_CAP_ENABLE

#define IMAP_CAP_ENABLE   (1 << 13)

RFC5161.

Definition at line 133 of file imap_private.h.

◆ IMAP_CAP_CONDSTORE

#define IMAP_CAP_CONDSTORE   (1 << 14)

RFC7162.

Definition at line 134 of file imap_private.h.

◆ IMAP_CAP_QRESYNC

#define IMAP_CAP_QRESYNC   (1 << 15)

RFC7162.

Definition at line 135 of file imap_private.h.

◆ IMAP_CAP_LIST_EXTENDED

#define IMAP_CAP_LIST_EXTENDED   (1 << 16)

RFC5258: IMAP4 LIST Command Extensions.

Definition at line 136 of file imap_private.h.

◆ IMAP_CAP_COMPRESS

#define IMAP_CAP_COMPRESS   (1 << 17)

RFC4978: COMPRESS=DEFLATE.

Definition at line 137 of file imap_private.h.

◆ IMAP_CAP_X_GM_EXT_1

#define IMAP_CAP_X_GM_EXT_1   (1 << 18)

◆ IMAP_CAP_ALL

#define IMAP_CAP_ALL   ((1 << 19) - 1)

Definition at line 140 of file imap_private.h.

Typedef Documentation

◆ ImapOpenFlags

typedef uint8_t ImapOpenFlags

Flags, e.g. MUTT_THREAD_COLLAPSE.

Definition at line 62 of file imap_private.h.

◆ ImapCmdFlags

typedef uint8_t ImapCmdFlags

Flags for imap_exec(), e.g. IMAP_CMD_PASS.

Definition at line 70 of file imap_private.h.

◆ ImapCapFlags

typedef uint32_t ImapCapFlags

typedef ImapCapFlags - Capabilities we are interested in

Note
This must be kept in the same order as Capabilities.Flags, e.g. IMAP_CAP_IMAP4

Definition at line 118 of file imap_private.h.

Enumeration Type Documentation

◆ ImapExecResult

imap_exec return code

Enumerator
IMAP_EXEC_SUCCESS 

Imap command executed or queued successfully.

IMAP_EXEC_ERROR 

Imap command failure.

IMAP_EXEC_FATAL 

Imap connection failure.

Definition at line 79 of file imap_private.h.

80 {
81  IMAP_EXEC_SUCCESS = 0,
84 };
Imap command executed or queued successfully.
Definition: imap_private.h:81
Imap connection failure.
Definition: imap_private.h:83
Imap command failure.
Definition: imap_private.h:82

◆ ImapFlags

enum ImapFlags

IMAP server responses.

Enumerator
IMAP_FATAL 

Unrecoverable error occurred.

IMAP_BYE 

Logged out from server.

Definition at line 92 of file imap_private.h.

93 {
94  IMAP_FATAL = 1,
95  IMAP_BYE,
96 };
Unrecoverable error occurred.
Definition: imap_private.h:94
Logged out from server.
Definition: imap_private.h:95

◆ ImapState

enum ImapState

IMAP connection state.

Enumerator
IMAP_DISCONNECTED 

Disconnected from server.

IMAP_CONNECTED 

Connected to server.

IMAP_AUTHENTICATED 

Connection is authenticated.

IMAP_SELECTED 

Mailbox is selected.

IMAP_IDLE 

Connection is idle.

Definition at line 101 of file imap_private.h.

102 {
103  /* States */
104  IMAP_DISCONNECTED = 0,
107  IMAP_SELECTED,
108 
109  /* and pseudo-states */
110  IMAP_IDLE,
111 };
Mailbox is selected.
Definition: imap_private.h:107
Connection is idle.
Definition: imap_private.h:110
Connection is authenticated.
Definition: imap_private.h:106
Connected to server.
Definition: imap_private.h:105
Disconnected from server.
Definition: imap_private.h:104

Function Documentation

◆ imap_create_mailbox()

int imap_create_mailbox ( struct ImapAccountData adata,
char *  mailbox 
)

Create a new mailbox.

Parameters
adataImap Account data
mailboxMailbox to create
Return values
0Success
-1Failure

Definition at line 581 of file imap.c.

582 {
583  char buf[2048], mbox[1024];
584 
585  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), mailbox);
586  snprintf(buf, sizeof(buf), "CREATE %s", mbox);
587 
588  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
589  {
590  mutt_error(_("CREATE failed: %s"), imap_cmd_trailer(adata));
591  return -1;
592  }
593 
594  return 0;
595 }
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1059
#define _(a)
Definition: message.h:28
const char * imap_cmd_trailer(struct ImapAccountData *adata)
Extra information after tagged command response if any.
Definition: command.c:1232
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_rename_mailbox()

int imap_rename_mailbox ( struct ImapAccountData adata,
char *  oldname,
const char *  newname 
)

Rename a mailbox.

Parameters
adataImap Account data
oldnameExisting mailbox
newnameNew name for mailbox
Return values
0Success
-1Failure

Definition at line 622 of file imap.c.

623 {
624  char oldmbox[1024];
625  char newmbox[1024];
626  int rc = 0;
627 
628  imap_munge_mbox_name(adata->unicode, oldmbox, sizeof(oldmbox), oldname);
629  imap_munge_mbox_name(adata->unicode, newmbox, sizeof(newmbox), newname);
630 
631  struct Buffer *buf = mutt_buffer_pool_get();
632  mutt_buffer_printf(buf, "RENAME %s %s", oldmbox, newmbox);
633 
635  rc = -1;
636 
638 
639  return rc;
640 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1059
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
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define mutt_b2s(buf)
Definition: buffer.h:41
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_exec_msgset()

int imap_exec_msgset ( struct Mailbox m,
const char *  pre,
const char *  post,
int  flag,
bool  changed,
bool  invert 
)

Prepare commands for all messages matching conditions.

Parameters
mSelected Imap Mailbox
preprefix commands
postpostfix commands
flagflag type on which to filter, e.g. MUTT_REPLIED
changedinclude only changed messages in message set
invertinvert sense of flag, eg MUTT_READ matches unread messages
Return values
numMatched messages
-1Failure

pre/post: commands are of the form "%s %s %s %s", tag, pre, message set, post Prepares commands for all messages matching conditions (must be flushed with imap_exec)

Definition at line 1023 of file imap.c.

1025 {
1026  struct ImapAccountData *adata = imap_adata_get(m);
1027  if (!adata || (adata->mailbox != m))
1028  return -1;
1029 
1030  struct Email **emails = NULL;
1031  short oldsort;
1032  int pos;
1033  int rc;
1034  int count = 0;
1035 
1036  struct Buffer cmd = mutt_buffer_make(0);
1037 
1038  /* We make a copy of the headers just in case resorting doesn't give
1039  exactly the original order (duplicate messages?), because other parts of
1040  the ctx are tied to the header order. This may be overkill. */
1041  oldsort = C_Sort;
1042  if (C_Sort != SORT_ORDER)
1043  {
1044  emails = m->emails;
1045  // We overcommit here, just in case new mail arrives whilst we're sync-ing
1046  m->emails = mutt_mem_malloc(m->email_max * sizeof(struct Email *));
1047  memcpy(m->emails, emails, m->email_max * sizeof(struct Email *));
1048 
1049  C_Sort = SORT_ORDER;
1050  qsort(m->emails, m->msg_count, sizeof(struct Email *), compare_uid);
1051  }
1052 
1053  pos = 0;
1054 
1055  do
1056  {
1057  mutt_buffer_reset(&cmd);
1058  mutt_buffer_add_printf(&cmd, "%s ", pre);
1059  rc = make_msg_set(m, &cmd, flag, changed, invert, &pos);
1060  if (rc > 0)
1061  {
1062  mutt_buffer_add_printf(&cmd, " %s", post);
1063  if (imap_exec(adata, cmd.data, IMAP_CMD_QUEUE) != IMAP_EXEC_SUCCESS)
1064  {
1065  rc = -1;
1066  goto out;
1067  }
1068  count += rc;
1069  }
1070  } while (rc > 0);
1071 
1072  rc = count;
1073 
1074 out:
1075  mutt_buffer_dealloc(&cmd);
1076  if (oldsort != C_Sort)
1077  {
1078  C_Sort = oldsort;
1079  FREE(&m->emails);
1080  m->emails = emails;
1081  }
1082 
1083  return rc;
1084 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int msg_count
Total number of messages.
Definition: mailbox.h:90
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
The envelope/body of an email.
Definition: email.h:37
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
static int make_msg_set(struct Mailbox *m, struct Buffer *buf, int flag, bool changed, bool invert, int *pos)
Make a message set.
Definition: imap.c:185
struct Mailbox * mailbox
Definition: imap_private.h:205
Imap command executed or queued successfully.
Definition: imap_private.h:81
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
int email_max
Number of pointers in emails.
Definition: mailbox.h:99
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:167
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define FREE(x)
Definition: memory.h:40
static int compare_uid(const void *a, const void *b)
Compare two Emails by UID - Implements sort_t.
Definition: imap.c:1000
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_open_connection()

int imap_open_connection ( struct ImapAccountData adata)

Open an IMAP connection.

Parameters
adataImap Account data
Return values
0Success
-1Failure

Definition at line 859 of file imap.c.

860 {
861  if (mutt_socket_open(adata->conn) < 0)
862  return -1;
863 
864  adata->state = IMAP_CONNECTED;
865 
866  if (imap_cmd_step(adata) != IMAP_RES_OK)
867  {
868  imap_close_connection(adata);
869  return -1;
870  }
871 
872  if (mutt_str_startswith(adata->buf, "* OK", CASE_IGNORE))
873  {
874  if (!mutt_str_startswith(adata->buf, "* OK [CAPABILITY", CASE_IGNORE) &&
875  check_capabilities(adata))
876  {
877  goto bail;
878  }
879 #ifdef USE_SSL
880  /* Attempt STARTTLS if available and desired. */
881  if (!adata->conn->ssf && (C_SslForceTls || (adata->capabilities & IMAP_CAP_STARTTLS)))
882  {
883  enum QuadOption ans;
884 
885  if (C_SslForceTls)
886  ans = MUTT_YES;
887  else if ((ans = query_quadoption(C_SslStarttls,
888  _("Secure connection with TLS?"))) == MUTT_ABORT)
889  {
890  goto err_close_conn;
891  }
892  if (ans == MUTT_YES)
893  {
894  enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_NO_FLAGS);
895  if (rc == IMAP_EXEC_FATAL)
896  goto bail;
897  if (rc != IMAP_EXEC_ERROR)
898  {
899  if (mutt_ssl_starttls(adata->conn))
900  {
901  mutt_error(_("Could not negotiate TLS connection"));
902  goto err_close_conn;
903  }
904  else
905  {
906  /* RFC2595 demands we recheck CAPABILITY after TLS completes. */
907  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS))
908  goto bail;
909  }
910  }
911  }
912  }
913 
914  if (C_SslForceTls && !adata->conn->ssf)
915  {
916  mutt_error(_("Encrypted connection unavailable"));
917  goto err_close_conn;
918  }
919 #endif
920  }
921  else if (mutt_str_startswith(adata->buf, "* PREAUTH", CASE_IGNORE))
922  {
923  adata->state = IMAP_AUTHENTICATED;
924  if (check_capabilities(adata) != 0)
925  goto bail;
926  FREE(&adata->capstr);
927  }
928  else
929  {
930  imap_error("imap_open_connection()", adata->buf);
931  goto bail;
932  }
933 
934  return 0;
935 
936 #ifdef USE_SSL
937 err_close_conn:
938  imap_close_connection(adata);
939 #endif
940 bail:
941  FREE(&adata->capstr);
942  return -1;
943 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
unsigned int ssf
security strength factor, in bits
Definition: connection.h:37
ImapExecResult
imap_exec return code
Definition: imap_private.h:79
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1109
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
#define _(a)
Definition: message.h:28
void imap_close_connection(struct ImapAccountData *adata)
Close an IMAP connection.
Definition: imap.c:949
WHERE bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: globals.h:234
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:74
#define IMAP_CAP_STARTTLS
RFC2595: STARTTLS.
Definition: imap_private.h:129
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: ssl.c:1463
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:804
Connection is authenticated.
Definition: imap_private.h:106
Imap connection failure.
Definition: imap_private.h:83
Ignore case when comparing strings.
Definition: string2.h:68
ImapCapFlags capabilities
Definition: imap_private.h:183
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
static int check_capabilities(struct ImapAccountData *adata)
Make sure we can log in to this server.
Definition: imap.c:82
Connected to server.
Definition: imap_private.h:105
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
WHERE unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: globals.h:186
struct Connection * conn
Definition: imap_private.h:169
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
Imap command failure.
Definition: imap_private.h:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_close_connection()

void imap_close_connection ( struct ImapAccountData adata)

Close an IMAP connection.

Parameters
adataImap Account data

Definition at line 949 of file imap.c.

950 {
951  if (adata->state != IMAP_DISCONNECTED)
952  {
953  mutt_socket_close(adata->conn);
954  adata->state = IMAP_DISCONNECTED;
955  }
956  adata->seqno = 0;
957  adata->nextcmd = 0;
958  adata->lastcmd = 0;
959  adata->status = 0;
960  memset(adata->cmds, 0, sizeof(struct ImapCommand) * adata->cmdslots);
961 }
struct ImapCommand * cmds
Definition: imap_private.h:198
unsigned int seqno
tag sequence number, e.g. &#39;{seqid}0001&#39;
Definition: imap_private.h:185
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
IMAP command structure.
Definition: imap_private.h:156
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
Disconnected from server.
Definition: imap_private.h:104
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_read_literal()

int imap_read_literal ( FILE *  fp,
struct ImapAccountData adata,
unsigned long  bytes,
struct Progress pbar 
)

Read bytes bytes from server into file.

Parameters
fpFile handle for email file
adataImap Account data
bytesNumber of bytes to read
pbarProgress bar
Return values
0Success
-1Failure

Not explicitly buffered, relies on FILE buffering.

Note
Strips \r from \r\n. Apparently even literals use \r\n-terminated strings ?!

Definition at line 730 of file imap.c.

732 {
733  char c;
734  bool r = false;
735  struct Buffer buf = { 0 }; // Do not allocate, maybe it won't be used
736 
738  mutt_buffer_alloc(&buf, bytes + 10);
739 
740  mutt_debug(LL_DEBUG2, "reading %ld bytes\n", bytes);
741 
742  for (unsigned long pos = 0; pos < bytes; pos++)
743  {
744  if (mutt_socket_readchar(adata->conn, &c) != 1)
745  {
746  mutt_debug(LL_DEBUG1, "error during read, %ld bytes read\n", pos);
747  adata->status = IMAP_FATAL;
748 
749  mutt_buffer_dealloc(&buf);
750  return -1;
751  }
752 
753  if (r && (c != '\n'))
754  fputc('\r', fp);
755 
756  if (c == '\r')
757  {
758  r = true;
759  continue;
760  }
761  else
762  r = false;
763 
764  fputc(c, fp);
765 
766  if (pbar && !(pos % 1024))
767  mutt_progress_update(pbar, pos, -1);
769  mutt_buffer_addch(&buf, c);
770  }
771 
773  {
774  mutt_debug(IMAP_LOG_LTRL, "\n%s", buf.data);
775  mutt_buffer_dealloc(&buf);
776  }
777  return 0;
778 }
#define IMAP_LOG_LTRL
Definition: imap_private.h:48
String manipulation buffer.
Definition: buffer.h:33
int mutt_socket_readchar(struct Connection *conn, char *c)
simple read buffering to speed things up
Definition: socket.c:208
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
Log at debug level 2.
Definition: logging.h:41
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
short C_DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Unrecoverable error occurred.
Definition: imap_private.h:94
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_expunge_mailbox()

void imap_expunge_mailbox ( struct Mailbox m)

Purge messages from the server.

Parameters
mMailbox

Purge IMAP portion of expunged messages from the context. Must not be done while something has a handle on any headers (eg inside pager or editor). That is, check IMAP_REOPEN_ALLOW.

Definition at line 788 of file imap.c.

789 {
790  struct ImapAccountData *adata = imap_adata_get(m);
791  struct ImapMboxData *mdata = imap_mdata_get(m);
792  if (!adata || !mdata)
793  return;
794 
795  struct Email *e = NULL;
796 
797 #ifdef USE_HCACHE
798  mdata->hcache = imap_hcache_open(adata, mdata);
799 #endif
800 
801  for (int i = 0; i < m->msg_count; i++)
802  {
803  e = m->emails[i];
804  if (!e)
805  break;
806 
807  if (e->index == INT_MAX)
808  {
809  mutt_debug(LL_DEBUG2, "Expunging message UID %u\n", imap_edata_get(e)->uid);
810 
811  e->deleted = true;
812 
813  imap_cache_del(m, e);
814 #ifdef USE_HCACHE
815  imap_hcache_del(mdata, imap_edata_get(e)->uid);
816 #endif
817 
818  mutt_hash_int_delete(mdata->uid_hash, imap_edata_get(e)->uid, e);
819 
820  imap_edata_free((void **) &e->edata);
821  }
822  else
823  {
824  e->index = i;
825  /* NeoMutt has several places where it turns off e->active as a
826  * hack. For example to avoid FLAG updates, or to exclude from
827  * imap_exec_msgset.
828  *
829  * Unfortunately, when a reopen is allowed and the IMAP_EXPUNGE_PENDING
830  * flag becomes set (e.g. a flag update to a modified header),
831  * this function will be called by imap_cmd_finish().
832  *
833  * The ctx_update_tables() will free and remove these "inactive" headers,
834  * despite that an EXPUNGE was not received for them.
835  * This would result in memory leaks and segfaults due to dangling
836  * pointers in the msn_index and uid_hash.
837  *
838  * So this is another hack to work around the hacks. We don't want to
839  * remove the messages, so make sure active is on.
840  */
841  e->active = true;
842  }
843  }
844 
845 #ifdef USE_HCACHE
846  imap_hcache_close(mdata);
847 #endif
848 
851 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:443
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
Update internal tables.
Definition: mailbox.h:172
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
void imap_edata_free(void **ptr)
free ImapHeader structure
Definition: message.c:74
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:544
header_cache_t * hcache
Definition: imap_private.h:240
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
Log at debug level 2.
Definition: logging.h:41
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:480
void * mdata
Driver specific data.
Definition: mailbox.h:135
Email list needs resorting.
Definition: mailbox.h:171
bool active
Message is not to be removed.
Definition: email.h:59
struct Hash * uid_hash
Definition: imap_private.h:234
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:106
int index
The absolute (unsorted) message number.
Definition: email.h:85
void mutt_hash_int_delete(struct Hash *table, unsigned int intkey, const void *data)
Remove an element from a Hash table.
Definition: hash.c:458
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1759
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_login()

int imap_login ( struct ImapAccountData adata)

Open an IMAP connection.

Parameters
adataImap Account data
Return values
0Success
-1Failure

Ensure ImapAccountData is connected and logged into the imap server.

Definition at line 1962 of file imap.c.

1963 {
1964  if (!adata)
1965  return -1;
1966 
1967  if (adata->state == IMAP_DISCONNECTED)
1968  {
1969  mutt_buffer_reset(&adata->cmdbuf); // purge outstanding queued commands
1970  imap_open_connection(adata);
1971  }
1972  if (adata->state == IMAP_CONNECTED)
1973  {
1974  if (imap_authenticate(adata) == IMAP_AUTH_SUCCESS)
1975  {
1976  adata->state = IMAP_AUTHENTICATED;
1977  FREE(&adata->capstr);
1978  if (adata->conn->ssf)
1979  {
1980  mutt_debug(LL_DEBUG2, "Communication encrypted at %d bits\n",
1981  adata->conn->ssf);
1982  }
1983  }
1984  else
1986  }
1987  if (adata->state == IMAP_AUTHENTICATED)
1988  {
1989  /* capabilities may have changed */
1990  imap_exec(adata, "CAPABILITY", IMAP_CMD_PASS);
1991 
1992 #ifdef USE_ZLIB
1993  /* RFC4978 */
1994  if ((adata->capabilities & IMAP_CAP_COMPRESS) && C_ImapDeflate &&
1995  (imap_exec(adata, "COMPRESS DEFLATE", IMAP_CMD_PASS) == IMAP_EXEC_SUCCESS))
1996  {
1997  mutt_debug(LL_DEBUG2, "IMAP compression is enabled on connection to %s\n",
1998  adata->conn->account.host);
1999  mutt_zstrm_wrap_conn(adata->conn);
2000  }
2001 #endif
2002 
2003  /* enable RFC6855, if the server supports that */
2004  if (C_ImapRfc5161 && (adata->capabilities & IMAP_CAP_ENABLE))
2005  imap_exec(adata, "ENABLE UTF8=ACCEPT", IMAP_CMD_QUEUE);
2006 
2007  /* enable QRESYNC. Advertising QRESYNC also means CONDSTORE
2008  * is supported (even if not advertised), so flip that bit. */
2009  if (adata->capabilities & IMAP_CAP_QRESYNC)
2010  {
2011  adata->capabilities |= IMAP_CAP_CONDSTORE;
2013  imap_exec(adata, "ENABLE QRESYNC", IMAP_CMD_QUEUE);
2014  }
2015 
2016  /* get root delimiter, '/' as default */
2017  adata->delim = '/';
2018  imap_exec(adata, "LIST \"\" \"\"", IMAP_CMD_QUEUE);
2019 
2020  /* we may need the root delimiter before we open a mailbox */
2021  imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
2022 
2023  /* select the mailbox that used to be open before disconnect */
2024  if (adata->mailbox)
2025  {
2026  imap_mbox_select(adata->mailbox);
2027  }
2028  }
2029 
2030  if (adata->state < IMAP_AUTHENTICATED)
2031  return -1;
2032 
2033  return 0;
2034 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
bool C_ImapRfc5161
Config: (imap) Use the IMAP ENABLE extension to select capabilities.
Definition: imap.c:74
struct ConnAccount account
Definition: connection.h:36
unsigned int ssf
security strength factor, in bits
Definition: connection.h:37
int imap_open_connection(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:859
void mutt_zstrm_wrap_conn(struct Connection *conn)
Wrap a compression layer around a Connection.
Definition: mutt_zstrm.c:287
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
#define IMAP_CAP_ENABLE
RFC5161.
Definition: imap_private.h:133
struct Mailbox * mailbox
Definition: imap_private.h:205
Imap command executed or queued successfully.
Definition: imap_private.h:81
char host[128]
Definition: connaccount.h:63
Log at debug level 2.
Definition: logging.h:41
int imap_authenticate(struct ImapAccountData *adata)
Authenticate to an IMAP server.
Definition: auth.c:68
struct Buffer cmdbuf
Definition: imap_private.h:202
bool C_ImapDeflate
Config: (imap) Compress network traffic.
Definition: imap.c:67
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void mutt_account_unsetpass(struct ConnAccount *cac)
Unset ConnAccount&#39;s password.
Definition: connaccount.c:132
WHERE bool C_ImapQresync
Config: (imap) Enable the QRESYNC extension.
Definition: globals.h:227
Connection is authenticated.
Definition: imap_private.h:106
ImapCapFlags capabilities
Definition: imap_private.h:183
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
Definition: imap_private.h:72
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1933
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: imap_private.h:134
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
Connected to server.
Definition: imap_private.h:105
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Disconnected from server.
Definition: imap_private.h:104
#define IMAP_CAP_COMPRESS
RFC4978: COMPRESS=DEFLATE.
Definition: imap_private.h:137
Authentication successful.
Definition: auth.h:37
#define IMAP_CAP_QRESYNC
RFC7162.
Definition: imap_private.h:135
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_sync_message_for_copy()

int imap_sync_message_for_copy ( struct Mailbox m,
struct Email e,
struct Buffer cmd,
enum QuadOption err_continue 
)

Update server to reflect the flags of a single message.

Parameters
[in]mMailbox
[in]eEmail
[in]cmdBuffer for the command string
[out]err_continueDid the user force a continue?
Return values
0Success
-1Failure

Update the IMAP server to reflect the flags for a single message before performing a "UID COPY".

Note
This does not sync the "deleted" flag state, because it is not desirable to propagate that flag into the copy.

Definition at line 1101 of file imap.c.

1103 {
1104  struct ImapAccountData *adata = imap_adata_get(m);
1105  if (!adata || (adata->mailbox != m))
1106  return -1;
1107 
1108  char flags[1024];
1109  char *tags = NULL;
1110  char uid[11];
1111 
1112  if (!compare_flags_for_copy(e))
1113  {
1114  if (e->deleted == imap_edata_get(e)->deleted)
1115  e->changed = false;
1116  return 0;
1117  }
1118 
1119  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
1120  mutt_buffer_reset(cmd);
1121  mutt_buffer_addstr(cmd, "UID STORE ");
1122  mutt_buffer_addstr(cmd, uid);
1123 
1124  flags[0] = '\0';
1125 
1126  set_flag(m, MUTT_ACL_SEEN, e->read, "\\Seen ", flags, sizeof(flags));
1127  set_flag(m, MUTT_ACL_WRITE, e->old, "Old ", flags, sizeof(flags));
1128  set_flag(m, MUTT_ACL_WRITE, e->flagged, "\\Flagged ", flags, sizeof(flags));
1129  set_flag(m, MUTT_ACL_WRITE, e->replied, "\\Answered ", flags, sizeof(flags));
1130  set_flag(m, MUTT_ACL_DELETE, imap_edata_get(e)->deleted, "\\Deleted ", flags,
1131  sizeof(flags));
1132 
1133  if (m->rights & MUTT_ACL_WRITE)
1134  {
1135  /* restore system flags */
1136  if (imap_edata_get(e)->flags_system)
1137  mutt_str_strcat(flags, sizeof(flags), imap_edata_get(e)->flags_system);
1138  /* set custom flags */
1139  tags = driver_tags_get_with_hidden(&e->tags);
1140  if (tags)
1141  {
1142  mutt_str_strcat(flags, sizeof(flags), tags);
1143  FREE(&tags);
1144  }
1145  }
1146 
1148 
1149  /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
1150  * explicitly revoke all system flags (if we have permission) */
1151  if (!*flags)
1152  {
1153  set_flag(m, MUTT_ACL_SEEN, 1, "\\Seen ", flags, sizeof(flags));
1154  set_flag(m, MUTT_ACL_WRITE, 1, "Old ", flags, sizeof(flags));
1155  set_flag(m, MUTT_ACL_WRITE, 1, "\\Flagged ", flags, sizeof(flags));
1156  set_flag(m, MUTT_ACL_WRITE, 1, "\\Answered ", flags, sizeof(flags));
1157  set_flag(m, MUTT_ACL_DELETE, !imap_edata_get(e)->deleted, "\\Deleted ",
1158  flags, sizeof(flags));
1159 
1160  /* erase custom flags */
1161  if ((m->rights & MUTT_ACL_WRITE) && imap_edata_get(e)->flags_remote)
1162  mutt_str_strcat(flags, sizeof(flags), imap_edata_get(e)->flags_remote);
1163 
1165 
1166  mutt_buffer_addstr(cmd, " -FLAGS.SILENT (");
1167  }
1168  else
1169  mutt_buffer_addstr(cmd, " FLAGS.SILENT (");
1170 
1171  mutt_buffer_addstr(cmd, flags);
1172  mutt_buffer_addstr(cmd, ")");
1173 
1174  /* after all this it's still possible to have no flags, if you
1175  * have no ACL rights */
1176  if (*flags && (imap_exec(adata, cmd->data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS) &&
1177  err_continue && (*err_continue != MUTT_YES))
1178  {
1179  *err_continue = imap_continue("imap_sync_message: STORE failed", adata->buf);
1180  if (*err_continue != MUTT_YES)
1181  return -1;
1182  }
1183 
1184  /* server have now the updated flags */
1185  FREE(&imap_edata_get(e)->flags_remote);
1187 
1188  if (e->deleted == imap_edata_get(e)->deleted)
1189  e->changed = false;
1190 
1191  return 0;
1192 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Mailbox * mailbox
Definition: imap_private.h:205
bool changed
Email has been edited.
Definition: email.h:48
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:65
Imap command executed or queued successfully.
Definition: imap_private.h:81
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * flags_remote
Definition: message.h:48
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:757
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
IMAP-specific Account data -.
Definition: imap_private.h:167
char * driver_tags_get_with_hidden(struct TagList *list)
Get tags with hiddens.
Definition: tags.c:155
static bool compare_flags_for_copy(struct Email *e)
Compare local flags against the server.
Definition: imap.c:285
bool flagged
Marked important?
Definition: email.h:43
bool deleted
Email is deleted.
Definition: email.h:45
bool replied
Email has been replied to.
Definition: email.h:54
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:72
enum QuadOption imap_continue(const char *msg, const char *resp)
display a message and ask the user if they want to go on
Definition: util.c:793
static void set_flag(struct Mailbox *m, AclFlags aclflag, int flag, const char *str, char *flags, size_t flsize)
append str to flags if we currently have permission according to aclflag
Definition: imap.c:164
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_has_flag()

bool imap_has_flag ( struct ListHead *  flag_list,
const char *  flag 
)

Does the flag exist in the list.

Parameters
flag_listList of server flags
flagFlag to find
Return values
trueFlag exists

Do a caseless comparison of the flag against a flag list, return true if found or flag list has '*'. Note that "flag" might contain additional whitespace at the end, so we really need to compare up to the length of each element in "flag_list".

Definition at line 974 of file imap.c.

975 {
976  if (STAILQ_EMPTY(flag_list))
977  return false;
978 
979  const size_t flaglen = mutt_str_strlen(flag);
980  struct ListNode *np = NULL;
981  STAILQ_FOREACH(np, flag_list, entries)
982  {
983  const size_t nplen = strlen(np->data);
984  if ((flaglen >= nplen) && ((flag[nplen] == '\0') || (flag[nplen] == ' ')) &&
985  (mutt_str_strncasecmp(np->data, flag, nplen) == 0))
986  {
987  return true;
988  }
989 
990  if (mutt_str_strcmp(np->data, "\\*") == 0)
991  return true;
992  }
993 
994  return false;
995 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:679
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:35
#define STAILQ_EMPTY(head)
Definition: queue.h:345
A List node for strings.
Definition: list.h:33
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_adata_find()

int imap_adata_find ( const char *  path,
struct ImapAccountData **  adata,
struct ImapMboxData **  mdata 
)

Find the Account data for this path.

Parameters
pathPath to search for
adataImap Account data
mdataImap Mailbox data
Return values
0Success
-1Failure

Definition at line 135 of file util.c.

137 {
138  struct ConnAccount cac = { { 0 } };
139  struct ImapAccountData *tmp_adata = NULL;
140  char tmp[1024];
141 
142  if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
143  return -1;
144 
145  struct Account *np = NULL;
146  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
147  {
148  if (np->magic != MUTT_IMAP)
149  continue;
150 
151  tmp_adata = np->adata;
152  if (!tmp_adata)
153  continue;
154  if (imap_account_match(&tmp_adata->conn->account, &cac))
155  {
156  *mdata = imap_mdata_new(tmp_adata, tmp);
157  *adata = tmp_adata;
158  return 0;
159  }
160  }
161  mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
162  return -1;
163 }
struct ConnAccount account
Definition: connection.h:36
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:39
A group of associated Mailboxes.
Definition: account.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:35
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:623
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1192
enum MailboxType magic
Type of Mailboxes this Account contains.
Definition: account.h:38
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: util.c:171
Login details for a remote server.
Definition: connaccount.h:58
IMAP-specific Account data -.
Definition: imap_private.h:167
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
Log at debug level 3.
Definition: logging.h:42
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_authenticate()

int imap_authenticate ( struct ImapAccountData adata)

Authenticate to an IMAP server.

Parameters
adataImap Account data
Return values
numResult, e.g. IMAP_AUTH_SUCCESS

Attempt to authenticate using either user-specified authentication method if specified, or any.

Definition at line 68 of file auth.c.

69 {
70  int rc = IMAP_AUTH_FAILURE;
71 
73  {
74  mutt_debug(LL_DEBUG2, "Trying user-defined imap_authenticators\n");
75 
76  /* Try user-specified list of authentication methods */
77  struct ListNode *np = NULL;
79  {
80  mutt_debug(LL_DEBUG2, "Trying method %s\n", np->data);
81 
82  for (size_t i = 0; i < mutt_array_size(imap_authenticators); i++)
83  {
84  const struct ImapAuth *auth = &imap_authenticators[i];
85  if (!auth->method || (mutt_str_strcasecmp(auth->method, np->data) == 0))
86  {
87  rc = auth->authenticate(adata, np->data);
88  if (rc == IMAP_AUTH_SUCCESS)
89  {
90  return rc;
91  }
92  }
93  }
94  }
95  }
96  else
97  {
98  /* Fall back to default: any authenticator */
99  mutt_debug(LL_DEBUG2, "Trying pre-defined imap_authenticators\n");
100 
101  for (size_t i = 0; i < mutt_array_size(imap_authenticators); i++)
102  {
103  rc = imap_authenticators[i].authenticate(adata, NULL);
104  if (rc == IMAP_AUTH_SUCCESS)
105  return rc;
106  }
107  }
108 
109  mutt_error(_("No authenticators available or wrong credentials"));
110  return rc;
111 }
const char * method
Definition: auth.h:51
#define _(a)
Definition: message.h:28
static const struct ImapAuth imap_authenticators[]
Accepted authentication methods.
Definition: auth.c:43
#define mutt_array_size(x)
Definition: memory.h:33
Log at debug level 2.
Definition: logging.h:41
struct ListHead head
Definition: slist.h:45
Authentication failed.
Definition: auth.h:38
size_t count
Definition: slist.h:46
enum ImapAuthRes(* authenticate)(struct ImapAccountData *adata, const char *method)
Definition: auth.h:48
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
IMAP authentication multiplexor.
Definition: auth.h:45
char * data
String.
Definition: list.h:35
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
struct Slist * C_ImapAuthenticators
Config: (imap) List of allowed IMAP authentication methods.
Definition: auth.c:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
A List node for strings.
Definition: list.h:33
Authentication successful.
Definition: auth.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cmd_start()

int imap_cmd_start ( struct ImapAccountData adata,
const char *  cmdstr 
)

Given an IMAP command, send it to the server.

Parameters
adataImap Account data
cmdstrCommand string to send
Return values
0Success
<0Failure, e.g. IMAP_RES_BAD

If cmdstr is NULL, sends queued commands.

Definition at line 1086 of file command.c.

1087 {
1088  return cmd_start(adata, cmdstr, IMAP_CMD_NO_FLAGS);
1089 }
static int cmd_start(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Start a new IMAP command.
Definition: command.c:200
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cmd_step()

int imap_cmd_step ( struct ImapAccountData adata)

Reads server responses from an IMAP command.

Parameters
adataImap Account data
Return values
0Success
<0Failure, e.g. IMAP_RES_BAD

detects tagged completion response, handles untagged messages, can read arbitrarily large strings (using malloc, so don't make it too large!).

Definition at line 1100 of file command.c.

1101 {
1102  if (!adata)
1103  return -1;
1104 
1105  size_t len = 0;
1106  int c;
1107  int rc;
1108  int stillrunning = 0;
1109  struct ImapCommand *cmd = NULL;
1110 
1111  if (adata->status == IMAP_FATAL)
1112  {
1113  cmd_handle_fatal(adata);
1114  return IMAP_RES_BAD;
1115  }
1116 
1117  /* read into buffer, expanding buffer as necessary until we have a full
1118  * line */
1119  do
1120  {
1121  if (len == adata->blen)
1122  {
1123  mutt_mem_realloc(&adata->buf, adata->blen + IMAP_CMD_BUFSIZE);
1124  adata->blen = adata->blen + IMAP_CMD_BUFSIZE;
1125  mutt_debug(LL_DEBUG3, "grew buffer to %lu bytes\n", adata->blen);
1126  }
1127 
1128  /* back up over '\0' */
1129  if (len)
1130  len--;
1131  c = mutt_socket_readln_d(adata->buf + len, adata->blen - len, adata->conn, MUTT_SOCK_LOG_FULL);
1132  if (c <= 0)
1133  {
1134  mutt_debug(LL_DEBUG1, "Error reading server response\n");
1135  cmd_handle_fatal(adata);
1136  return IMAP_RES_BAD;
1137  }
1138 
1139  len += c;
1140  }
1141  /* if we've read all the way to the end of the buffer, we haven't read a
1142  * full line (mutt_socket_readln strips the \r, so we always have at least
1143  * one character free when we've read a full line) */
1144  while (len == adata->blen);
1145 
1146  /* don't let one large string make cmd->buf hog memory forever */
1147  if ((adata->blen > IMAP_CMD_BUFSIZE) && (len <= IMAP_CMD_BUFSIZE))
1148  {
1150  adata->blen = IMAP_CMD_BUFSIZE;
1151  mutt_debug(LL_DEBUG3, "shrank buffer to %lu bytes\n", adata->blen);
1152  }
1153 
1154  adata->lastread = mutt_date_epoch();
1155 
1156  /* handle untagged messages. The caller still gets its shot afterwards. */
1157  if ((mutt_str_startswith(adata->buf, "* ", CASE_MATCH) ||
1158  mutt_str_startswith(imap_next_word(adata->buf), "OK [", CASE_MATCH)) &&
1159  cmd_handle_untagged(adata))
1160  {
1161  return IMAP_RES_BAD;
1162  }
1163 
1164  /* server demands a continuation response from us */
1165  if (adata->buf[0] == '+')
1166  return IMAP_RES_RESPOND;
1167 
1168  /* Look for tagged command completions.
1169  *
1170  * Some response handlers can end up recursively calling
1171  * imap_cmd_step() and end up handling all tagged command
1172  * completions.
1173  * (e.g. FETCH->set_flag->set_header_color->~h pattern match.)
1174  *
1175  * Other callers don't even create an adata->cmds entry.
1176  *
1177  * For both these cases, we default to returning OK */
1178  rc = IMAP_RES_OK;
1179  c = adata->lastcmd;
1180  do
1181  {
1182  cmd = &adata->cmds[c];
1183  if (cmd->state == IMAP_RES_NEW)
1184  {
1185  if (mutt_str_startswith(adata->buf, cmd->seq, CASE_MATCH))
1186  {
1187  if (!stillrunning)
1188  {
1189  /* first command in queue has finished - move queue pointer up */
1190  adata->lastcmd = (adata->lastcmd + 1) % adata->cmdslots;
1191  }
1192  cmd->state = cmd_status(adata->buf);
1193  /* bogus - we don't know which command result to return here. Caller
1194  * should provide a tag. */
1195  rc = cmd->state;
1196  }
1197  else
1198  stillrunning++;
1199  }
1200 
1201  c = (c + 1) % adata->cmdslots;
1202  } while (c != adata->nextcmd);
1203 
1204  if (stillrunning)
1205  rc = IMAP_RES_CONTINUE;
1206  else
1207  {
1208  mutt_debug(LL_DEBUG3, "IMAP queue drained\n");
1209  imap_cmd_finish(adata);
1210  }
1211 
1212  return rc;
1213 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
struct ImapCommand * cmds
Definition: imap_private.h:198
#define IMAP_RES_NEW
ImapCommand.state additions.
Definition: imap_private.h:57
Match case when comparing strings.
Definition: string2.h:67
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
Definition: command.c:164
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:32
IMAP command structure.
Definition: imap_private.h:156
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:937
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1324
#define IMAP_CMD_BUFSIZE
Definition: command.c:57
char seq[SEQ_LEN+1]
Command tag, e.g. &#39;a0001&#39;.
Definition: imap_private.h:158
time_t lastread
last time we read a command for the server
Definition: imap_private.h:186
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
Log at debug level 1.
Definition: logging.h:40
int state
Command state, e.g. IMAP_RES_NEW.
Definition: imap_private.h:159
static int cmd_handle_untagged(struct ImapAccountData *adata)
fallback parser for otherwise unhandled messages
Definition: command.c:1011
#define IMAP_RES_BAD
<tag> BAD ...
Definition: imap_private.h:53
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:244
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Unrecoverable error occurred.
Definition: imap_private.h:94
Log at debug level 3.
Definition: logging.h:42
struct Connection * conn
Definition: imap_private.h:169
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
#define IMAP_RES_RESPOND
+
Definition: imap_private.h:56
static int cmd_status(const char *s)
parse response line for tagged OK/NO/BAD
Definition: command.c:236
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cmd_finish()

void imap_cmd_finish ( struct ImapAccountData adata)

Attempt to perform cleanup.

Parameters
adataImap Account data

If a reopen is allowed, it attempts to perform cleanup (eg fetch new mail if detected, do expunge). Called automatically by imap_cmd_step(), but may be called at any time.

mdata->check_status is set and will be used later by imap_check_mailbox().

Definition at line 1324 of file command.c.

1325 {
1326  if (!adata)
1327  return;
1328 
1329  if (adata->status == IMAP_FATAL)
1330  {
1331  adata->closing = false;
1332  cmd_handle_fatal(adata);
1333  return;
1334  }
1335 
1336  if (!(adata->state >= IMAP_SELECTED) || (adata->mailbox && adata->closing))
1337  {
1338  adata->closing = false;
1339  return;
1340  }
1341 
1342  adata->closing = false;
1343 
1344  struct ImapMboxData *mdata = imap_mdata_get(adata->mailbox);
1345 
1346  if (mdata && mdata->reopen & IMAP_REOPEN_ALLOW)
1347  {
1348  // First remove expunged emails from the msn_index
1349  if (mdata->reopen & IMAP_EXPUNGE_PENDING)
1350  {
1351  mutt_debug(LL_DEBUG2, "Expunging mailbox\n");
1352  imap_expunge_mailbox(adata->mailbox);
1353  /* Detect whether we've gotten unexpected EXPUNGE messages */
1354  if (!(mdata->reopen & IMAP_EXPUNGE_EXPECTED))
1357  }
1358 
1359  // Then add new emails to it
1360  if (mdata->reopen & IMAP_NEWMAIL_PENDING && (mdata->new_mail_count > mdata->max_msn))
1361  {
1362  if (!(mdata->reopen & IMAP_EXPUNGE_PENDING))
1364 
1365  mutt_debug(LL_DEBUG2, "Fetching new mails from %d to %d\n",
1366  mdata->max_msn + 1, mdata->new_mail_count);
1367  imap_read_headers(adata->mailbox, mdata->max_msn + 1, mdata->new_mail_count, false);
1368  }
1369 
1370  // And to finish inform about MUTT_REOPEN if needed
1371  if (mdata->reopen & IMAP_EXPUNGE_PENDING && !(mdata->reopen & IMAP_EXPUNGE_EXPECTED))
1373 
1374  if (mdata->reopen & IMAP_EXPUNGE_PENDING)
1376  }
1377 
1378  adata->status = 0;
1379 }
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: imap_private.h:66
Mailbox is selected.
Definition: imap_private.h:107
void imap_expunge_mailbox(struct Mailbox *m)
Purge messages from the server.
Definition: imap.c:788
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:220
struct Mailbox * mailbox
Definition: imap_private.h:205
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
Definition: command.c:164
unsigned int max_msn
the largest MSN fetched so far
Definition: imap_private.h:237
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: imap_private.h:222
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
Log at debug level 2.
Definition: logging.h:41
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: imap_private.h:221
void * mdata
Driver specific data.
Definition: mailbox.h:135
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: imap_private.h:65
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
int imap_read_headers(struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool initial_download)
Read headers from the server.
Definition: message.c:1274
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: imap_private.h:67
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Unrecoverable error occurred.
Definition: imap_private.h:94
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: imap_private.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_code()

bool imap_code ( const char *  s)

Was the command successful.

Parameters
sIMAP command status
Return values
1Command result was OK
0If NO or BAD

Definition at line 1221 of file command.c.

1222 {
1223  return cmd_status(s) == IMAP_RES_OK;
1224 }
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
static int cmd_status(const char *s)
parse response line for tagged OK/NO/BAD
Definition: command.c:236
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cmd_trailer()

const char* imap_cmd_trailer ( struct ImapAccountData adata)

Extra information after tagged command response if any.

Parameters
adataImap Account data
Return values
ptrExtra command information (pointer into adata->buf)
""Error (static string)

Definition at line 1232 of file command.c.

1233 {
1234  static const char *notrailer = "";
1235  const char *s = adata->buf;
1236 
1237  if (!s)
1238  {
1239  mutt_debug(LL_DEBUG2, "not a tagged response\n");
1240  return notrailer;
1241  }
1242 
1243  s = imap_next_word((char *) s);
1244  if (!s || (!mutt_str_startswith(s, "OK", CASE_IGNORE) &&
1245  !mutt_str_startswith(s, "NO", CASE_IGNORE) &&
1246  !mutt_str_startswith(s, "BAD", CASE_IGNORE)))
1247  {
1248  mutt_debug(LL_DEBUG2, "not a command completion: %s\n", adata->buf);
1249  return notrailer;
1250  }
1251 
1252  s = imap_next_word((char *) s);
1253  if (!s)
1254  return notrailer;
1255 
1256  return s;
1257 }
Log at debug level 2.
Definition: logging.h:41
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:937
Ignore case when comparing strings.
Definition: string2.h:68
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_exec()

int imap_exec ( struct ImapAccountData adata,
const char *  cmdstr,
ImapCmdFlags  flags 
)

Execute a command and wait for the response from the server.

Parameters
adataImap Account data
cmdstrCommand to execute
flagsFlags, see ImapCmdFlags
Return values
IMAP_EXEC_SUCCESSCommand successful or queued
IMAP_EXEC_ERRORCommand returned an error
IMAP_EXEC_FATALImap connection failure

Also, handle untagged responses.

Definition at line 1270 of file command.c.

1271 {
1272  int rc;
1273 
1274  rc = cmd_start(adata, cmdstr, flags);
1275  if (rc < 0)
1276  {
1277  cmd_handle_fatal(adata);
1278  return IMAP_EXEC_FATAL;
1279  }
1280 
1281  if (flags & IMAP_CMD_QUEUE)
1282  return IMAP_EXEC_SUCCESS;
1283 
1284  if ((flags & IMAP_CMD_POLL) && (C_ImapPollTimeout > 0) &&
1285  ((mutt_socket_poll(adata->conn, C_ImapPollTimeout)) == 0))
1286  {
1287  mutt_error(_("Connection to %s timed out"), adata->conn->account.host);
1288  cmd_handle_fatal(adata);
1289  return IMAP_EXEC_FATAL;
1290  }
1291 
1292  /* Allow interruptions, particularly useful if there are network problems. */
1294  do
1295  {
1296  rc = imap_cmd_step(adata);
1297  } while (rc == IMAP_RES_CONTINUE);
1298  mutt_sig_allow_interrupt(false);
1299 
1300  if (rc == IMAP_RES_NO)
1301  return IMAP_EXEC_ERROR;
1302  if (rc != IMAP_RES_OK)
1303  {
1304  if (adata->status != IMAP_FATAL)
1305  return IMAP_EXEC_ERROR;
1306 
1307  mutt_debug(LL_DEBUG1, "command failed: %s\n", adata->buf);
1308  return IMAP_EXEC_FATAL;
1309  }
1310 
1311  return IMAP_EXEC_SUCCESS;
1312 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
struct ConnAccount account
Definition: connection.h:36
WHERE short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: globals.h:156
#define _(a)
Definition: message.h:28
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
Definition: command.c:164
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:74
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
Imap command executed or queued successfully.
Definition: imap_private.h:81
char host[128]
Definition: connaccount.h:63
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:190
#define IMAP_RES_NO
<tag> NO ...
Definition: imap_private.h:52
struct ListHead flags
Definition: imap_private.h:225
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
Imap connection failure.
Definition: imap_private.h:83
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
Log at debug level 1.
Definition: logging.h:40
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define mutt_error(...)
Definition: logging.h:84
static int cmd_start(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Start a new IMAP command.
Definition: command.c:200
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Unrecoverable error occurred.
Definition: imap_private.h:94
struct Connection * conn
Definition: imap_private.h:169
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
Imap command failure.
Definition: imap_private.h:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cmd_idle()

int imap_cmd_idle ( struct ImapAccountData adata)

Enter the IDLE state.

Parameters
adataImap Account data
Return values
0Success
<0Failure, e.g. IMAP_RES_BAD

Definition at line 1387 of file command.c.

1388 {
1389  int rc;
1390 
1391  if (cmd_start(adata, "IDLE", IMAP_CMD_POLL) < 0)
1392  {
1393  cmd_handle_fatal(adata);
1394  return -1;
1395  }
1396 
1397  if ((C_ImapPollTimeout > 0) && ((mutt_socket_poll(adata->conn, C_ImapPollTimeout)) == 0))
1398  {
1399  mutt_error(_("Connection to %s timed out"), adata->conn->account.host);
1400  cmd_handle_fatal(adata);
1401  return -1;
1402  }
1403 
1404  do
1405  {
1406  rc = imap_cmd_step(adata);
1407  } while (rc == IMAP_RES_CONTINUE);
1408 
1409  if (rc == IMAP_RES_RESPOND)
1410  {
1411  /* successfully entered IDLE state */
1412  adata->state = IMAP_IDLE;
1413  /* queue automatic exit when next command is issued */
1414  mutt_buffer_addstr(&adata->cmdbuf, "DONE\r\n");
1415  rc = IMAP_RES_OK;
1416  }
1417  if (rc != IMAP_RES_OK)
1418  {
1419  mutt_debug(LL_DEBUG1, "error starting IDLE\n");
1420  return -1;
1421  }
1422 
1423  return 0;
1424 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
struct ConnAccount account
Definition: connection.h:36
WHERE short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: globals.h:156
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
#define _(a)
Definition: message.h:28
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
Definition: command.c:164
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:74
char host[128]
Definition: connaccount.h:63
Connection is idle.
Definition: imap_private.h:110
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:190
struct Buffer cmdbuf
Definition: imap_private.h:202
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
static int cmd_start(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Start a new IMAP command.
Definition: command.c:200
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Connection * conn
Definition: imap_private.h:169
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
#define IMAP_RES_RESPOND
+
Definition: imap_private.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_edata_free()

void imap_edata_free ( void **  ptr)

free ImapHeader structure

Parameters
[out]ptrPrivate Email data

Definition at line 74 of file message.c.

75 {
76  if (!ptr || !*ptr)
77  return;
78 
79  struct ImapEmailData *edata = *ptr;
80  /* this should be safe even if the list wasn't used */
81  FREE(&edata->flags_system);
82  FREE(&edata->flags_remote);
83  FREE(ptr);
84 }
char * flags_remote
Definition: message.h:48
char * flags_system
Definition: message.h:47
void * edata
Driver-specific data.
Definition: email.h:106
#define FREE(x)
Definition: memory.h:40
IMAP-specific Email data -.
Definition: message.h:33
+ Here is the caller graph for this function:

◆ imap_edata_get()

struct ImapEmailData* imap_edata_get ( struct Email e)

Get the private data for this Email.

Parameters
eEmail
Return values
ptrPrivate Email data

Definition at line 100 of file message.c.

101 {
102  if (!e)
103  return NULL;
104  return e->edata;
105 }
void * edata
Driver-specific data.
Definition: email.h:106
+ Here is the caller graph for this function:

◆ imap_read_headers()

int imap_read_headers ( struct Mailbox m,
unsigned int  msn_begin,
unsigned int  msn_end,
bool  initial_download 
)

Read headers from the server.

Parameters
mImap Selected Mailbox
msn_beginFirst Message Sequence Number
msn_endLast Message Sequence Number
initial_downloadtrue, if this is the first opening of the mailbox
Return values
numLast MSN
-1Failure

Changed to read many headers instead of just one. It will return the msn of the last message read. It will return a value other than msn_end if mail comes in while downloading headers (in theory).

Definition at line 1274 of file message.c.

1276 {
1277  int oldmsgcount;
1278  unsigned int maxuid = 0;
1279  int retval = -1;
1280  bool evalhc = false;
1281 
1282 #ifdef USE_HCACHE
1283  void *uid_validity = NULL;
1284  void *puid_next = NULL;
1285  unsigned int uid_next = 0;
1286  bool has_condstore = false;
1287  bool has_qresync = false;
1288  bool eval_condstore = false;
1289  bool eval_qresync = false;
1290  unsigned long long *pmodseq = NULL;
1291  unsigned long long hc_modseq = 0;
1292  char *uid_seqset = NULL;
1293 #endif /* USE_HCACHE */
1294 
1295  struct ImapAccountData *adata = imap_adata_get(m);
1296  struct ImapMboxData *mdata = imap_mdata_get(m);
1297  if (!adata || (adata->mailbox != m))
1298  return -1;
1299 
1300  /* make sure context has room to hold the mailbox */
1301  while (msn_end > m->email_max)
1302  mx_alloc_memory(m);
1303  alloc_msn_index(adata, msn_end);
1304  imap_alloc_uid_hash(adata, msn_end);
1305 
1306  oldmsgcount = m->msg_count;
1308  mdata->new_mail_count = 0;
1309 
1310 #ifdef USE_HCACHE
1311  mdata->hcache = imap_hcache_open(adata, mdata);
1312 
1313  if (mdata->hcache && initial_download)
1314  {
1315  uid_validity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12);
1316  puid_next = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8);
1317  if (puid_next)
1318  {
1319  uid_next = *(unsigned int *) puid_next;
1320  mutt_hcache_free(mdata->hcache, &puid_next);
1321  }
1322 
1323  if (mdata->modseq)
1324  {
1326  has_condstore = true;
1327 
1328  /* If IMAP_CAP_QRESYNC and ImapQResync then NeoMutt sends ENABLE QRESYNC.
1329  * If we receive an ENABLED response back, then adata->qresync is set. */
1330  if (adata->qresync)
1331  has_qresync = true;
1332  }
1333 
1334  if (uid_validity && uid_next && (*(unsigned int *) uid_validity == mdata->uid_validity))
1335  {
1336  evalhc = true;
1337  pmodseq = mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7);
1338  if (pmodseq)
1339  {
1340  hc_modseq = *pmodseq;
1341  mutt_hcache_free(mdata->hcache, (void **) &pmodseq);
1342  }
1343  if (hc_modseq)
1344  {
1345  if (has_qresync)
1346  {
1347  uid_seqset = imap_hcache_get_uid_seqset(mdata);
1348  if (uid_seqset)
1349  eval_qresync = true;
1350  }
1351 
1352  if (!eval_qresync && has_condstore)
1353  eval_condstore = true;
1354  }
1355  }
1356  mutt_hcache_free(mdata->hcache, &uid_validity);
1357  }
1358  if (evalhc)
1359  {
1360  if (eval_qresync)
1361  {
1362  if (read_headers_qresync_eval_cache(adata, uid_seqset) < 0)
1363  goto bail;
1364  }
1365  else
1366  {
1367  if (read_headers_normal_eval_cache(adata, msn_end, uid_next, has_condstore || has_qresync,
1368  eval_condstore) < 0)
1369  goto bail;
1370  }
1371 
1372  if ((eval_condstore || eval_qresync) && (hc_modseq != mdata->modseq))
1373  {
1374  if (read_headers_condstore_qresync_updates(adata, msn_end, uid_next,
1375  hc_modseq, eval_qresync) < 0)
1376  {
1377  goto bail;
1378  }
1379  }
1380 
1381  /* Look for the first empty MSN and start there */
1382  while (msn_begin <= msn_end)
1383  {
1384  if (!mdata->msn_index[msn_begin - 1])
1385  break;
1386  msn_begin++;
1387  }
1388  }
1389 #endif /* USE_HCACHE */
1390 
1391  if (read_headers_fetch_new(m, msn_begin, msn_end, evalhc, &maxuid, initial_download) < 0)
1392  goto bail;
1393 
1394  if (maxuid && (mdata->uid_next < maxuid + 1))
1395  mdata->uid_next = maxuid + 1;
1396 
1397 #ifdef USE_HCACHE
1398  mutt_hcache_store_raw(mdata->hcache, "/UIDVALIDITY", 12, &mdata->uid_validity,
1399  sizeof(mdata->uid_validity));
1400  if (maxuid && (mdata->uid_next < maxuid + 1))
1401  {
1402  mutt_debug(LL_DEBUG2, "Overriding UIDNEXT: %u -> %u\n", mdata->uid_next, maxuid + 1);
1403  mdata->uid_next = maxuid + 1;
1404  }
1405  if (mdata->uid_next > 1)
1406  {
1407  mutt_hcache_store_raw(mdata->hcache, "/UIDNEXT", 8, &mdata->uid_next,
1408  sizeof(mdata->uid_next));
1409  }
1410 
1411  /* We currently only sync CONDSTORE and QRESYNC on the initial download.
1412  * To do it more often, we'll need to deal with flag updates combined with
1413  * unsync'ed local flag changes. We'll also need to properly sync flags to
1414  * the header cache on close. I'm not sure it's worth the added complexity. */
1415  if (initial_download)
1416  {
1417  if (has_condstore || has_qresync)
1418  {
1419  mutt_hcache_store_raw(mdata->hcache, "/MODSEQ", 7, &mdata->modseq,
1420  sizeof(mdata->modseq));
1421  }
1422  else
1423  mutt_hcache_delete_header(mdata->hcache, "/MODSEQ", 7);
1424 
1425  if (has_qresync)
1427  else
1429  }
1430 #endif /* USE_HCACHE */
1431 
1432  if (m->msg_count > oldmsgcount)
1433  {
1434  /* TODO: it's not clear to me why we are calling mx_alloc_memory
1435  * yet again. */
1436  mx_alloc_memory(m);
1437  }
1438 
1439  mdata->reopen |= IMAP_REOPEN_ALLOW;
1440 
1441  retval = msn_end;
1442 
1443 bail:
1444 #ifdef USE_HCACHE
1445  imap_hcache_close(mdata);
1446  FREE(&uid_seqset);
1447 #endif /* USE_HCACHE */
1448 
1449  return retval;
1450 }
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:443
int msg_count
Total number of messages.
Definition: mailbox.h:90
static int read_headers_normal_eval_cache(struct ImapAccountData *adata, unsigned int msn_end, unsigned int uid_next, bool store_flag_updates, bool eval_condstore)
Retrieve data from the header cache.
Definition: message.c:729
struct Email ** msn_index
look up headers by (MSN-1)
Definition: imap_private.h:235
void * mutt_hcache_fetch_raw(header_cache_t *hc, const char *key, size_t keylen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:373
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:220
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1189
struct Mailbox * mailbox
Definition: imap_private.h:205
int mutt_hcache_store_raw(header_cache_t *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:431
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: imap_private.h:222
header_cache_t * hcache
Definition: imap_private.h:240
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
Log at debug level 2.
Definition: logging.h:41
static void imap_alloc_uid_hash(struct ImapAccountData *adata, unsigned int msn_count)
Create a Hash Table for the UIDs.
Definition: message.c:581
char * imap_hcache_get_uid_seqset(struct ImapMboxData *mdata)
Get a UID Sequence Set from the header cache.
Definition: util.c:597
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:480
void * mdata
Driver specific data.
Definition: mailbox.h:135
unsigned long long modseq
Definition: imap_private.h:228
int mutt_hcache_delete_header(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::delete_header.
Definition: hcache.c:451
int email_max
Number of pointers in emails.
Definition: mailbox.h:99
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
ImapCapFlags capabilities
Definition: imap_private.h:183
static int read_headers_fetch_new(struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool evalhc, unsigned int *maxuid, bool initial_download)
Retrieve new messages from the server.
Definition: message.c:1031
static int read_headers_qresync_eval_cache(struct ImapAccountData *adata, char *uid_seqset)
Retrieve data from the header cache.
Definition: message.c:868
WHERE bool C_ImapCondstore
Config: (imap) Enable the CONDSTORE extension.
Definition: globals.h:223
unsigned int uid_validity
Definition: imap_private.h:226
int imap_hcache_clear_uid_seqset(struct ImapMboxData *mdata)
Delete a UID Sequence Set from the header cache.
Definition: util.c:583
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: imap_private.h:134
IMAP-specific Account data -.
Definition: imap_private.h:167
unsigned int uid_next
Definition: imap_private.h:227
static int read_headers_condstore_qresync_updates(struct ImapAccountData *adata, unsigned int msn_end, unsigned int uid_next, unsigned long long hc_modseq, bool eval_qresync)
Retrieve updates from the server.
Definition: message.c:939
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
#define FREE(x)
Definition: memory.h:40
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: imap_private.h:67
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:392
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static void alloc_msn_index(struct ImapAccountData *adata, size_t msn_count)
Create lookup table of MSN to Header.
Definition: message.c:541
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: imap_private.h:64
int imap_hcache_store_uid_seqset(struct ImapMboxData *mdata)
Store a UID Sequence Set in the header cache.
Definition: util.c:561
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_set_flags()

char* imap_set_flags ( struct Mailbox m,
struct Email e,
char *  s,
bool *  server_changes 
)

fill the message header according to the server flags

Parameters
[in]mImap Selected Mailbox
[in]eEmail
[in]sCommand string
[out]server_changesSet to true if the flags have changed
Return values
ptrThe end of flags string
NULLFailure

Expects a flags line of the form "FLAGS (flag flag ...)"

imap_set_flags: fill out the message header according to the flags from the server. Expects a flags line of the form "FLAGS (flag flag ...)"

Sets server_changes to 1 if a change to a flag is made, or in the case of e->changed, if a change to a flag would have been made.

Definition at line 1810 of file message.c.

1811 {
1812  struct ImapAccountData *adata = imap_adata_get(m);
1813  if (!adata || (adata->mailbox != m))
1814  return NULL;
1815 
1816  struct ImapHeader newh = { 0 };
1817  struct ImapEmailData old_edata = { 0 };
1818  int local_changes = e->changed;
1819 
1820  struct ImapEmailData *edata = e->edata;
1821  newh.edata = edata;
1822 
1823  mutt_debug(LL_DEBUG2, "parsing FLAGS\n");
1824  s = msg_parse_flags(&newh, s);
1825  if (!s)
1826  return NULL;
1827 
1828  /* Update tags system */
1829  /* We take a copy of the tags so we can split the string */
1830  char *tags_copy = mutt_str_strdup(edata->flags_remote);
1831  driver_tags_replace(&e->tags, tags_copy);
1832  FREE(&tags_copy);
1833 
1834  /* YAUH (yet another ugly hack): temporarily set context to
1835  * read-write even if it's read-only, so *server* updates of
1836  * flags can be processed by mutt_set_flag. mailbox->changed must
1837  * be restored afterwards */
1838  bool readonly = m->readonly;
1839  m->readonly = false;
1840 
1841  /* This is redundant with the following two checks. Removing:
1842  * mutt_set_flag (m, e, MUTT_NEW, !(edata->read || edata->old)); */
1843  set_changed_flag(m, e, local_changes, server_changes, MUTT_OLD, old_edata.old,
1844  edata->old, e->old);
1845  set_changed_flag(m, e, local_changes, server_changes, MUTT_READ,
1846  old_edata.read, edata->read, e->read);
1847  set_changed_flag(m, e, local_changes, server_changes, MUTT_DELETE,
1848  old_edata.deleted, edata->deleted, e->deleted);
1849  set_changed_flag(m, e, local_changes, server_changes, MUTT_FLAG,
1850  old_edata.flagged, edata->flagged, e->flagged);
1851  set_changed_flag(m, e, local_changes, server_changes, MUTT_REPLIED,
1852  old_edata.replied, edata->replied, e->replied);
1853 
1854  /* this message is now definitively *not* changed (mutt_set_flag
1855  * marks things changed as a side-effect) */
1856  if (local_changes == 0)
1857  e->changed = false;
1858  m->changed &= !readonly;
1859  m->readonly = readonly;
1860 
1861  return s;
1862 }
static void set_changed_flag(struct Mailbox *m, struct Email *e, int local_changes, bool *server_changes, int flag_name, bool old_hd_flag, bool new_hd_flag, bool h_flag)
Have the flags of an email changed.
Definition: message.c:689
Flagged messages.
Definition: mutt.h:106
struct Mailbox * mailbox
Definition: imap_private.h:205
bool changed
Email has been edited.
Definition: email.h:48
Messages that have been replied to.
Definition: mutt.h:99
bool flagged
Definition: message.h:39
bool deleted
Definition: message.h:38
bool read
Email is read.
Definition: email.h:51
Log at debug level 2.
Definition: logging.h:41
bool old
Email is seen, but unread.
Definition: email.h:50
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:118
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
char * flags_remote
Definition: message.h:48
Old messages.
Definition: mutt.h:98
Messages to be deleted.
Definition: mutt.h:102
IMAP-specific header.
Definition: message.h:54
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Messages that have been read.
Definition: mutt.h:100
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:167
bool flagged
Marked important?
Definition: email.h:43
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:106
bool replied
Email has been replied to.
Definition: email.h:54
#define FREE(x)
Definition: memory.h:40
bool read
Definition: message.h:36
bool changed
Mailbox has been modified.
Definition: mailbox.h:113
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
IMAP-specific Email data -.
Definition: message.h:33
bool driver_tags_replace(struct TagList *head, char *tags)
Replace all tags.
Definition: tags.c:183
static char * msg_parse_flags(struct ImapHeader *h, char *s)
read a FLAGS token into an ImapHeader
Definition: message.c:224
struct ImapEmailData * edata
Definition: message.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cache_del()

int imap_cache_del ( struct Mailbox m,
struct Email e 
)

Delete an email from the body cache.

Parameters
mSelected Imap Mailbox
eEmail
Return values
0Success
-1Failure

Definition at line 1759 of file message.c.

1760 {
1761  struct ImapAccountData *adata = imap_adata_get(m);
1762  struct ImapMboxData *mdata = imap_mdata_get(m);
1763 
1764  if (!e || !adata || (adata->mailbox != m))
1765  return -1;
1766 
1767  mdata->bcache = msg_cache_open(m);
1768  char id[64];
1769  snprintf(id, sizeof(id), "%u-%u", mdata->uid_validity, imap_edata_get(e)->uid);
1770  return mutt_bcache_del(mdata->bcache, id);
1771 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
struct Mailbox * mailbox
Definition: imap_private.h:205
struct BodyCache * bcache
Definition: imap_private.h:238
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
static struct BodyCache * msg_cache_open(struct Mailbox *m)
Open a message cache.
Definition: message.c:114
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
int mutt_bcache_del(struct BodyCache *bcache, const char *id)
Delete a file from the Body Cache.
Definition: bcache.c:252
unsigned int uid_validity
Definition: imap_private.h:226
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_cache_clean()

int imap_cache_clean ( struct Mailbox m)

Delete all the entries in the message cache.

Parameters
mSelectedImap Mailbox
Return values
0Always

Definition at line 1778 of file message.c.

1779 {
1780  struct ImapAccountData *adata = imap_adata_get(m);
1781  struct ImapMboxData *mdata = imap_mdata_get(m);
1782 
1783  if (!adata || (adata->mailbox != m))
1784  return -1;
1785 
1786  mdata->bcache = msg_cache_open(m);
1787  mutt_bcache_list(mdata->bcache, msg_cache_clean_cb, mdata);
1788 
1789  return 0;
1790 }
static int msg_cache_clean_cb(const char *id, struct BodyCache *bcache, void *data)
Delete an entry from the message cache - Implements bcache_list_t.
Definition: message.c:202
struct Mailbox * mailbox
Definition: imap_private.h:205
int mutt_bcache_list(struct BodyCache *bcache, bcache_list_t want_id, void *data)
Find matching entries in the Body Cache.
Definition: bcache.c:317
struct BodyCache * bcache
Definition: imap_private.h:238
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
static struct BodyCache * msg_cache_open(struct Mailbox *m)
Open a message cache.
Definition: message.c:114
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_append_message()

int imap_append_message ( struct Mailbox m,
struct Message msg 
)

Write an email back to the server.

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

Definition at line 1459 of file message.c.

1460 {
1461  if (!m || !msg)
1462  return -1;
1463 
1464  FILE *fp = NULL;
1465  char buf[1024 * 2];
1466  char internaldate[IMAP_DATELEN];
1467  char imap_flags[128];
1468  size_t len;
1469  struct Progress progress;
1470  size_t sent;
1471  int c, last;
1472  int rc;
1473 
1474  struct ImapAccountData *adata = imap_adata_get(m);
1475  struct ImapMboxData *mdata = imap_mdata_get(m);
1476 
1477  fp = fopen(msg->path, "r");
1478  if (!fp)
1479  {
1480  mutt_perror(msg->path);
1481  goto fail;
1482  }
1483 
1484  /* currently we set the \Seen flag on all messages, but probably we
1485  * should scan the message Status header for flag info. Since we're
1486  * already rereading the whole file for length it isn't any more
1487  * expensive (it'd be nice if we had the file size passed in already
1488  * by the code that writes the file, but that's a lot of changes.
1489  * Ideally we'd have an Email structure with flag info here... */
1490  for (last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
1491  {
1492  if ((c == '\n') && (last != '\r'))
1493  len++;
1494 
1495  len++;
1496  }
1497  rewind(fp);
1498 
1499  mutt_progress_init(&progress, _("Uploading message..."), MUTT_PROGRESS_NET, len);
1500 
1501  mutt_date_make_imap(internaldate, sizeof(internaldate), msg->received);
1502 
1503  imap_flags[0] = '\0';
1504  imap_flags[1] = '\0';
1505 
1506  if (msg->flags.read)
1507  mutt_str_strcat(imap_flags, sizeof(imap_flags), " \\Seen");
1508  if (msg->flags.replied)
1509  mutt_str_strcat(imap_flags, sizeof(imap_flags), " \\Answered");
1510  if (msg->flags.flagged)
1511  mutt_str_strcat(imap_flags, sizeof(imap_flags), " \\Flagged");
1512  if (msg->flags.draft)
1513  mutt_str_strcat(imap_flags, sizeof(imap_flags), " \\Draft");
1514 
1515  snprintf(buf, sizeof(buf), "APPEND %s (%s) \"%s\" {%lu}", mdata->munge_name,
1516  imap_flags + 1, internaldate, (unsigned long) len);
1517 
1518  imap_cmd_start(adata, buf);
1519 
1520  do
1521  {
1522  rc = imap_cmd_step(adata);
1523  } while (rc == IMAP_RES_CONTINUE);
1524 
1525  if (rc != IMAP_RES_RESPOND)
1526  goto cmd_step_fail;
1527 
1528  for (last = EOF, sent = len = 0; (c = fgetc(fp)) != EOF; last = c)
1529  {
1530  if ((c == '\n') && (last != '\r'))
1531  buf[len++] = '\r';
1532 
1533  buf[len++] = c;
1534 
1535  if (len > sizeof(buf) - 3)
1536  {
1537  sent += len;
1538  if (flush_buffer(buf, &len, adata->conn) < 0)
1539  goto fail;
1540  mutt_progress_update(&progress, sent, -1);
1541  }
1542  }
1543 
1544  if (len)
1545  if (flush_buffer(buf, &len, adata->conn) < 0)
1546  goto fail;
1547 
1548  if (mutt_socket_send(adata->conn, "\r\n") < 0)
1549  goto fail;
1550  mutt_file_fclose(&fp);
1551 
1552  do
1553  {
1554  rc = imap_cmd_step(adata);
1555  } while (rc == IMAP_RES_CONTINUE);
1556 
1557  if (rc != IMAP_RES_OK)
1558  goto cmd_step_fail;
1559 
1560  return 0;
1561 
1562 cmd_step_fail:
1563  mutt_debug(LL_DEBUG1, "command failed: %s\n", adata->buf);
1564  if (rc != IMAP_RES_BAD)
1565  {
1566  char *pc = imap_next_word(adata->buf); /* skip sequence number or token */
1567  pc = imap_next_word(pc); /* skip response code */
1568  if (*pc != '\0')
1569  mutt_error("%s", pc);
1570  }
1571 
1572 fail:
1573  mutt_file_fclose(&fp);
1574  return -1;
1575 }
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:43
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
#define mutt_perror(...)
Definition: logging.h:85
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:38
bool replied
Definition: mx.h:93
#define _(a)
Definition: message.h:28
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1086
A progress bar.
Definition: progress.h:49
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
static int flush_buffer(char *buf, size_t *len, struct Connection *conn)
Write data to a connection.
Definition: message.c:502
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
void * mdata
Driver specific data.
Definition: mailbox.h:135
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:937
bool flagged
Definition: mx.h:92
struct Message::@0 flags
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
bool draft
Definition: mx.h:94
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
IMAP-specific Account data -.
Definition: imap_private.h:167
Log at debug level 1.
Definition: logging.h:40
#define IMAP_DATELEN
Definition: imap_private.h:87
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_RES_BAD
<tag> BAD ...
Definition: imap_private.h:53
int mutt_date_make_imap(char *buf, size_t buflen, time_t timestamp)
Format date in IMAP style: DD-MMM-YYYY HH:MM:SS +ZZzz.
Definition: date.c:618
time_t received
the time at which this message was received
Definition: mx.h:96
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool read
Definition: mx.h:91
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:217
char * path
path to temp file
Definition: mx.h:86
struct Connection * conn
Definition: imap_private.h:169
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
#define IMAP_RES_RESPOND
+
Definition: imap_private.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_msg_open()

int imap_msg_open ( struct Mailbox m,
struct Message msg,
int  msgno 
)

Open an email message in a Mailbox - Implements MxOps::msg_open()

Definition at line 1867 of file message.c.

1868 {
1869  if (!m || !msg)
1870  return -1;
1871 
1872  struct Envelope *newenv = NULL;
1873  char buf[1024];
1874  char *pc = NULL;
1875  unsigned int bytes;
1876  struct Progress progress;
1877  unsigned int uid;
1878  bool retried = false;
1879  bool read;
1880  int rc;
1881 
1882  /* Sam's weird courier server returns an OK response even when FETCH
1883  * fails. Thanks Sam. */
1884  bool fetched = false;
1885  int output_progress;
1886 
1887  struct ImapAccountData *adata = imap_adata_get(m);
1888 
1889  if (!adata || (adata->mailbox != m))
1890  return -1;
1891 
1892  struct Email *e = m->emails[msgno];
1893  if (!e)
1894  return -1;
1895 
1896  msg->fp = msg_cache_get(m, e);
1897  if (msg->fp)
1898  {
1899  if (imap_edata_get(e)->parsed)
1900  return 0;
1901  goto parsemsg;
1902  }
1903 
1904  /* This function is called in a few places after endwin()
1905  * e.g. mutt_pipe_message(). */
1906  output_progress = !isendwin();
1907  if (output_progress)
1908  mutt_message(_("Fetching message..."));
1909 
1910  msg->fp = msg_cache_put(m, e);
1911  if (!msg->fp)
1912  {
1913  struct Buffer *path = mutt_buffer_pool_get();
1914  mutt_buffer_mktemp(path);
1915  msg->fp = mutt_file_fopen(mutt_b2s(path), "w+");
1916  unlink(mutt_b2s(path));
1917  mutt_buffer_pool_release(&path);
1918 
1919  if (!msg->fp)
1920  return -1;
1921  }
1922 
1923  /* mark this header as currently inactive so the command handler won't
1924  * also try to update it. HACK until all this code can be moved into the
1925  * command handler */
1926  e->active = false;
1927 
1928  snprintf(buf, sizeof(buf), "UID FETCH %u %s", imap_edata_get(e)->uid,
1929  ((adata->capabilities & IMAP_CAP_IMAP4REV1) ?
1930  (C_ImapPeek ? "BODY.PEEK[]" : "BODY[]") :
1931  "RFC822"));
1932 
1933  imap_cmd_start(adata, buf);
1934  do
1935  {
1936  rc = imap_cmd_step(adata);
1937  if (rc != IMAP_RES_CONTINUE)
1938  break;
1939 
1940  pc = adata->buf;
1941  pc = imap_next_word(pc);
1942  pc = imap_next_word(pc);
1943 
1944  if (mutt_str_startswith(pc, "FETCH", CASE_IGNORE))
1945  {
1946  while (*pc)
1947  {
1948  pc = imap_next_word(pc);
1949  if (pc[0] == '(')
1950  pc++;
1951  if (mutt_str_startswith(pc, "UID", CASE_IGNORE))
1952  {
1953  pc = imap_next_word(pc);
1954  if (mutt_str_atoui(pc, &uid) < 0)
1955  goto bail;
1956  if (uid != imap_edata_get(e)->uid)
1957  {
1958  mutt_error(_(
1959  "The message index is incorrect. Try reopening the mailbox."));
1960  }
1961  }
1962  else if (mutt_str_startswith(pc, "RFC822", CASE_IGNORE) ||
1963  mutt_str_startswith(pc, "BODY[]", CASE_IGNORE))
1964  {
1965  pc = imap_next_word(pc);
1966  if (imap_get_literal_count(pc, &bytes) < 0)
1967  {
1968  imap_error("imap_msg_open()", buf);
1969  goto bail;
1970  }
1971  if (output_progress)
1972  {
1973  mutt_progress_init(&progress, _("Fetching message..."), MUTT_PROGRESS_NET, bytes);
1974  }
1975  if (imap_read_literal(msg->fp, adata, bytes, output_progress ? &progress : NULL) < 0)
1976  {
1977  goto bail;
1978  }
1979  /* pick up trailing line */
1980  rc = imap_cmd_step(adata);
1981  if (rc != IMAP_RES_CONTINUE)
1982  goto bail;
1983  pc = adata->buf;
1984 
1985  fetched = true;
1986  }
1987  /* UW-IMAP will provide a FLAGS update here if the FETCH causes a
1988  * change (eg from \Unseen to \Seen).
1989  * Uncommitted changes in neomutt take precedence. If we decide to
1990  * incrementally update flags later, this won't stop us syncing */
1991  else if (mutt_str_startswith(pc, "FLAGS", CASE_IGNORE) && !e->changed)
1992  {
1993  pc = imap_set_flags(m, e, pc, NULL);
1994  if (!pc)
1995  goto bail;
1996  }
1997  }
1998  }
1999  } while (rc == IMAP_RES_CONTINUE);
2000 
2001  /* see comment before command start. */
2002  e->active = true;
2003 
2004  fflush(msg->fp);
2005  if (ferror(msg->fp))
2006  goto bail;
2007 
2008  if (rc != IMAP_RES_OK)
2009  goto bail;
2010 
2011  if (!fetched || !imap_code(adata->buf))
2012  goto bail;
2013 
2014  msg_cache_commit(m, e);
2015 
2016 parsemsg:
2017  /* Update the header information. Previously, we only downloaded a
2018  * portion of the headers, those required for the main display. */
2019  rewind(msg->fp);
2020  /* It may be that the Status header indicates a message is read, but the
2021  * IMAP server doesn't know the message has been \Seen. So we capture
2022  * the server's notion of 'read' and if it differs from the message info
2023  * picked up in mutt_rfc822_read_header, we mark the message (and context
2024  * changed). Another possibility: ignore Status on IMAP? */
2025  read = e->read;
2026  newenv = mutt_rfc822_read_header(msg->fp, e, false, false);
2027  mutt_env_merge(e->env, &newenv);
2028 
2029  /* see above. We want the new status in e->read, so we unset it manually
2030  * and let mutt_set_flag set it correctly, updating context. */
2031  if (read != e->read)
2032  {
2033  e->read = read;
2034  mutt_set_flag(m, e, MUTT_NEW, read);
2035  }
2036 
2037  e->lines = 0;
2038  fgets(buf, sizeof(buf), msg->fp);
2039  while (!feof(msg->fp))
2040  {
2041  e->lines++;
2042  fgets(buf, sizeof(buf), msg->fp);
2043  }
2044 
2045  e->content->length = ftell(msg->fp) - e->content->offset;
2046 
2047  mutt_clear_error();
2048  rewind(msg->fp);
2049  imap_edata_get(e)->parsed = true;
2050 
2051  /* retry message parse if cached message is empty */
2052  if (!retried && ((e->lines == 0) || (e->content->length == 0)))
2053  {
2054  imap_cache_del(m, e);
2055  retried = true;
2056  goto parsemsg;
2057  }
2058 
2059  return 0;
2060 
2061 bail:
2062  e->active = true;
2063  mutt_file_fclose(&msg->fp);
2064  imap_cache_del(m, e);
2065  return -1;
2066 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:43
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
int lines
How many lines in the body of this message?
Definition: email.h:84
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
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
void mutt_env_merge(struct Envelope *base, struct Envelope **extra)
Merge the headers of two Envelopes.
Definition: envelope.c:151
#define mutt_message(...)
Definition: logging.h:83
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
static FILE * msg_cache_put(struct Mailbox *m, struct Email *e)
Put an email into the message cache.
Definition: message.c:162
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1759
String manipulation buffer.
Definition: buffer.h:33
static FILE * msg_cache_get(struct Mailbox *m, struct Email *e)
Get the message cache entry for an email.
Definition: message.c:141
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
WHERE bool C_ImapPeek
Config: (imap) Don&#39;t mark messages as read when fetching them from the server.
Definition: globals.h:226
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Definition: imap_private.h:205
bool changed
Email has been edited.
Definition: email.h:48
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1086
int imap_read_literal(FILE *fp, struct ImapAccountData *adata, unsigned long bytes, struct Progress *pbar)
Read bytes bytes from server into file.
Definition: imap.c:730
A progress bar.
Definition: progress.h:49
bool read
Email is read.
Definition: email.h:51
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: imap_private.h:121
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
struct Envelope * env
Envelope information.
Definition: email.h:89
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:937
#define mutt_b2s(buf)
Definition: buffer.h:41
bool active
Message is not to be removed.
Definition: email.h:59
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:804
New messages.
Definition: mutt.h:97
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:292
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
Ignore case when comparing strings.
Definition: string2.h:68
ImapCapFlags capabilities
Definition: imap_private.h:183
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
IMAP-specific Account data -.
Definition: imap_private.h:167
int imap_get_literal_count(const char *buf, unsigned int *bytes)
write number of bytes in an IMAP literal into bytes
Definition: util.c:893
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mx.h:85
char * imap_set_flags(struct Mailbox *m, struct Email *e, char *s, bool *server_changes)
fill the message header according to the server flags
Definition: message.c:1810
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1136
bool parsed
Definition: message.h:42
bool imap_code(const char *s)
Was the command successful.
Definition: command.c:1221
The header of an Email.
Definition: envelope.h:54
int msgno
Number displayed to the user.
Definition: email.h:86
static int msg_cache_commit(struct Mailbox *m, struct Email *e)
Add to the message cache.
Definition: message.c:183
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
+ Here is the call graph for this function:

◆ imap_msg_close()

int imap_msg_close ( struct Mailbox m,
struct Message msg 
)

Close an email - Implements MxOps::msg_close()

Note
May also return EOF Failure, see errno

Definition at line 2087 of file message.c.

2088 {
2089  return mutt_file_fclose(&msg->fp);
2090 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
FILE * fp
pointer to the message data
Definition: mx.h:85
+ Here is the call graph for this function:

◆ imap_msg_commit()

int imap_msg_commit ( struct Mailbox m,
struct Message msg 
)

Save changes to an email - Implements MxOps::msg_commit()

Note
May also return EOF Failure, see errno

Definition at line 2073 of file message.c.

2074 {
2075  int rc = mutt_file_fclose(&msg->fp);
2076  if (rc != 0)
2077  return rc;
2078 
2079  return imap_append_message(m, msg);
2080 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
int imap_append_message(struct Mailbox *m, struct Message *msg)
Write an email back to the server.
Definition: message.c:1459
FILE * fp
pointer to the message data
Definition: mx.h:85
+ Here is the call graph for this function:

◆ imap_msg_save_hcache()

int imap_msg_save_hcache ( struct Mailbox m,
struct Email e 
)

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

Definition at line 2095 of file message.c.

2096 {
2097  int rc = 0;
2098 #ifdef USE_HCACHE
2099  bool close_hc = true;
2100  struct ImapAccountData *adata = imap_adata_get(m);
2101  struct ImapMboxData *mdata = imap_mdata_get(m);
2102  if (!mdata || !adata)
2103  return -1;
2104  if (mdata->hcache)
2105  close_hc = false;
2106  else
2107  mdata->hcache = imap_hcache_open(adata, mdata);
2108  rc = imap_hcache_put(mdata, e);
2109  if (close_hc)
2110  imap_hcache_close(mdata);
2111 #endif
2112  return rc;
2113 }
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:443
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:526
header_cache_t * hcache
Definition: imap_private.h:240
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:480
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
+ Here is the call graph for this function:

◆ imap_adata_get()

struct ImapAccountData* imap_adata_get ( struct Mailbox m)

Get the Account data for this mailbox.

Parameters
mMailbox
Return values
ptrPrivate data

Definition at line 120 of file util.c.

121 {
122  if (!m || (m->magic != MUTT_IMAP) || !m->account)
123  return NULL;
124  return m->account->adata;
125 }
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:130
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
+ Here is the caller graph for this function:

◆ imap_mdata_get()

struct ImapMboxData* imap_mdata_get ( struct Mailbox m)

Get the Mailbox data for this mailbox.

Parameters
mMailbox

Definition at line 251 of file util.c.

252 {
253  if (!m || (m->magic != MUTT_IMAP) || !m->mdata)
254  return NULL;
255  return m->mdata;
256 }
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void * mdata
Driver specific data.
Definition: mailbox.h:135
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
+ Here is the caller graph for this function:

◆ imap_hcache_open()

header_cache_t* imap_hcache_open ( struct ImapAccountData adata,
struct ImapMboxData mdata 
)

Open a header cache.

Parameters
adataImap Account data
mdataImap Mailbox data
Return values
ptrHeaderCache
NULLFailure

Definition at line 443 of file util.c.

444 {
445  if (!adata || !mdata)
446  return NULL;
447 
448  header_cache_t *hc = NULL;
449  struct Buffer *mbox = mutt_buffer_pool_get();
450  struct Buffer *cachepath = mutt_buffer_pool_get();
451 
452  imap_cachepath(adata->delim, mdata->name, mbox);
453 
454  if (strstr(mutt_b2s(mbox), "/../") || (strcmp(mutt_b2s(mbox), "..") == 0) ||
455  (strncmp(mutt_b2s(mbox), "../", 3) == 0))
456  {
457  goto cleanup;
458  }
459  size_t len = mutt_buffer_len(mbox);
460  if ((len > 3) && (strcmp(mutt_b2s(mbox) + len - 3, "/..") == 0))
461  goto cleanup;
462 
463  struct Url url = { 0 };
464  mutt_account_tourl(&adata->conn->account, &url);
465  url.path = mbox->data;
466  url_tobuffer(&url, cachepath, U_PATH);
467 
469 
470 cleanup:
472  mutt_buffer_pool_release(&cachepath);
473  return hc;
474 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static void imap_hcache_namer(const char *path, struct Buffer *dest)
Generate a filename for the header cache - Implements hcache_namer_t.
Definition: util.c:431
struct ConnAccount account
Definition: connection.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
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
WHERE char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: globals.h:121
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:85
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:864
header_cache_t * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for HcacheOps::open.
Definition: hcache.c:250
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
char * data
Pointer to data.
Definition: buffer.h:35
char * name
Mailbox name.
Definition: imap_private.h:216
char * path
Path.
Definition: url.h:73
header cache structure
Definition: lib.h:67
int url_tobuffer(struct Url *url, struct Buffer *buf, int flags)
Output the URL string for a given Url object.
Definition: url.c:358
#define U_PATH
Definition: url.h:48
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_close()

void imap_hcache_close ( struct ImapMboxData mdata)

Close the header cache.

Parameters
mdataImap Mailbox data

Definition at line 480 of file util.c.

481 {
482  if (!mdata->hcache)
483  return;
484 
485  mutt_hcache_close(mdata->hcache);
486  mdata->hcache = NULL;
487 }
void mutt_hcache_close(header_cache_t *hc)
Multiplexor for HcacheOps::close.
Definition: hcache.c:329
header_cache_t * hcache
Definition: imap_private.h:240
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_get()

struct Email* imap_hcache_get ( struct ImapMboxData mdata,
unsigned int  uid 
)

Get a header cache entry by its UID.

Parameters
mdataImap Mailbox data
uidUID to find
Return values
ptrEmail
NULLFailure

Definition at line 496 of file util.c.

497 {
498  if (!mdata->hcache)
499  return NULL;
500 
501  char key[16];
502  struct Email *e = NULL;
503 
504  sprintf(key, "/%u", uid);
505  void *uv = mutt_hcache_fetch(mdata->hcache, key, mutt_str_strlen(key));
506  if (uv)
507  {
508  const size_t *const uid_validity = uv;
509  if (*uid_validity == mdata->uid_validity)
510  e = mutt_hcache_restore(uv);
511  else
512  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %zu\n", *uid_validity);
513  mutt_hcache_free(mdata->hcache, &uv);
514  }
515 
516  return e;
517 }
void * mutt_hcache_fetch(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::fetch.
Definition: hcache.c:343
The envelope/body of an email.
Definition: email.h:37
struct Email * mutt_hcache_restore(const unsigned char *d)
restore an Email from data retrieved from the cache
Definition: serialize.c:634
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
header_cache_t * hcache
Definition: imap_private.h:240
unsigned int uid_validity
Definition: imap_private.h:226
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:392
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_put()

int imap_hcache_put ( struct ImapMboxData mdata,
struct Email e 
)

Add an entry to the header cache.

Parameters
mdataImap Mailbox data
eEmail
Return values
0Success
-1Failure

Definition at line 526 of file util.c.

527 {
528  if (!mdata->hcache)
529  return -1;
530 
531  char key[16];
532 
533  sprintf(key, "/%u", imap_edata_get(e)->uid);
534  return mutt_hcache_store(mdata->hcache, key, mutt_str_strlen(key), e, mdata->uid_validity);
535 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
header_cache_t * hcache
Definition: imap_private.h:240
int mutt_hcache_store(header_cache_t *hc, const char *key, size_t keylen, struct Email *e, unsigned int uidvalidity)
Multiplexor for HcacheOps::store.
Definition: hcache.c:405
unsigned int uid_validity
Definition: imap_private.h:226
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_del()

int imap_hcache_del ( struct ImapMboxData mdata,
unsigned int  uid 
)

Delete an item from the header cache.

Parameters
mdataImap Mailbox data
uidUID of entry to delete
Return values
0Success
-1Failure

Definition at line 544 of file util.c.

545 {
546  if (!mdata->hcache)
547  return -1;
548 
549  char key[16];
550 
551  sprintf(key, "/%u", uid);
552  return mutt_hcache_delete_header(mdata->hcache, key, mutt_str_strlen(key));
553 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
header_cache_t * hcache
Definition: imap_private.h:240
int mutt_hcache_delete_header(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::delete_header.
Definition: hcache.c:451
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_store_uid_seqset()

int imap_hcache_store_uid_seqset ( struct ImapMboxData mdata)

Store a UID Sequence Set in the header cache.

Parameters
mdataImap Mailbox data
Return values
0Success
-1Error

Definition at line 561 of file util.c.

562 {
563  if (!mdata->hcache)
564  return -1;
565 
566  /* The seqset is likely large. Preallocate to reduce reallocs */
567  struct Buffer buf = mutt_buffer_make(8192);
568  imap_msn_index_to_uid_seqset(&buf, mdata);
569 
570  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
571  mutt_buffer_len(&buf) + 1);
572  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
573  mutt_buffer_dealloc(&buf);
574  return rc;
575 }
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
int mutt_hcache_store_raw(header_cache_t *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:431
header_cache_t * hcache
Definition: imap_private.h:240
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
char * data
Pointer to data.
Definition: buffer.h:35
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:376
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_clear_uid_seqset()

int imap_hcache_clear_uid_seqset ( struct ImapMboxData mdata)

Delete a UID Sequence Set from the header cache.

Parameters
mdataImap Mailbox data
Return values
0Success
-1Error

Definition at line 583 of file util.c.

584 {
585  if (!mdata->hcache)
586  return -1;
587 
588  return mutt_hcache_delete_header(mdata->hcache, "/UIDSEQSET", 10);
589 }
header_cache_t * hcache
Definition: imap_private.h:240
int mutt_hcache_delete_header(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::delete_header.
Definition: hcache.c:451
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_get_uid_seqset()

char* imap_hcache_get_uid_seqset ( struct ImapMboxData mdata)

Get a UID Sequence Set from the header cache.

Parameters
mdataImap Mailbox data
Return values
ptrUID Sequence Set
NULLError

Definition at line 597 of file util.c.

598 {
599  if (!mdata->hcache)
600  return NULL;
601 
602  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10);
603  char *seqset = mutt_str_strdup(hc_seqset);
604  mutt_hcache_free(mdata->hcache, (void **) &hc_seqset);
605  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
606 
607  return seqset;
608 }
#define NONULL(x)
Definition: string2.h:37
void * mutt_hcache_fetch_raw(header_cache_t *hc, const char *key, size_t keylen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:373
header_cache_t * hcache
Definition: imap_private.h:240
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:392
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_continue()

enum QuadOption imap_continue ( const char *  msg,
const char *  resp 
)

display a message and ask the user if they want to go on

Parameters
msgLocation of the error
respMessage for user
Return values
QuadOptionResult, e.g. MUTT_NO

Definition at line 793 of file util.c.

794 {
795  imap_error(msg, resp);
796  return mutt_yesorno(_("Continue?"), MUTT_NO);
797 }
#define _(a)
Definition: message.h:28
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:804
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_error()

void imap_error ( const char *  where,
const char *  msg 
)

show an error and abort

Parameters
whereLocation of the error
msgMessage for user

Definition at line 804 of file util.c.

805 {
806  mutt_error("%s [%s]", where, msg);
807 }
#define mutt_error(...)
Definition: logging.h:84
+ Here is the caller graph for this function:

◆ imap_adata_new()

struct ImapAccountData* imap_adata_new ( struct Account a)

Allocate and initialise a new ImapAccountData structure.

Return values
ptrNew ImapAccountData

Definition at line 98 of file util.c.

99 {
100  struct ImapAccountData *adata = mutt_mem_calloc(1, sizeof(struct ImapAccountData));
101  adata->account = a;
102 
103  static unsigned char new_seqid = 'a';
104 
105  adata->seqid = new_seqid;
106  adata->cmdslots = C_ImapPipelineDepth + 2;
107  adata->cmds = mutt_mem_calloc(adata->cmdslots, sizeof(*adata->cmds));
108 
109  if (++new_seqid > 'z')
110  new_seqid = 'a';
111 
112  return adata;
113 }
struct ImapCommand * cmds
Definition: imap_private.h:198
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
unsigned char seqid
Definition: imap_private.h:184
short C_ImapPipelineDepth
Config: (imap) Number of IMAP commands that may be queued up.
Definition: util.c:66
struct Account * account
Parent Account.
Definition: imap_private.h:206
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: imap_private.h:167
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_adata_free()

void imap_adata_free ( void **  ptr)

Release and clear storage in an ImapAccountData structure.

Parameters
[out]ptrImap Account data

Definition at line 72 of file util.c.

73 {
74  if (!ptr || !*ptr)
75  return;
76 
77  struct ImapAccountData *adata = *ptr;
78 
79  FREE(&adata->capstr);
80  mutt_buffer_dealloc(&adata->cmdbuf);
81  FREE(&adata->buf);
82  FREE(&adata->cmds);
83 
84  if (adata->conn)
85  {
86  if (adata->conn->conn_close)
87  adata->conn->conn_close(adata->conn);
88  FREE(&adata->conn);
89  }
90 
91  FREE(ptr);
92 }
struct ImapCommand * cmds
Definition: imap_private.h:198
struct Buffer cmdbuf
Definition: imap_private.h:202
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
int(* conn_close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:87
IMAP-specific Account data -.
Definition: imap_private.h:167
#define FREE(x)
Definition: memory.h:40
struct Connection * conn
Definition: imap_private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_new()

struct ImapMboxData* imap_mdata_new ( struct ImapAccountData adata,
const char *  name 
)

Allocate and initialise a new ImapMboxData structure.

Parameters
adataImap Account data
nameName for Mailbox
Return values
ptrNew ImapMboxData

Definition at line 171 of file util.c.

172 {
173  char buf[1024];
174  struct ImapMboxData *mdata = mutt_mem_calloc(1, sizeof(struct ImapMboxData));
175 
176  mdata->real_name = mutt_str_strdup(name);
177 
178  imap_fix_path(adata->delim, name, buf, sizeof(buf));
179  if (buf[0] == '\0')
180  mutt_str_strfcpy(buf, "INBOX", sizeof(buf));
181  mdata->name = mutt_str_strdup(buf);
182 
183  imap_munge_mbox_name(adata->unicode, buf, sizeof(buf), mdata->name);
184  mdata->munge_name = mutt_str_strdup(buf);
185 
186  mdata->reopen &= IMAP_REOPEN_ALLOW;
187 
188  STAILQ_INIT(&mdata->flags);
189 
190 #ifdef USE_HCACHE
191  header_cache_t *hc = imap_hcache_open(adata, mdata);
192  if (hc)
193  {
194  void *uidvalidity = mutt_hcache_fetch_raw(hc, "/UIDVALIDITY", 12);
195  void *uidnext = mutt_hcache_fetch_raw(hc, "/UIDNEXT", 8);
196  unsigned long long *modseq = mutt_hcache_fetch_raw(hc, "/MODSEQ", 7);
197  if (uidvalidity)
198  {
199  mdata->uid_validity = *(unsigned int *) uidvalidity;
200  mdata->uid_next = uidnext ? *(unsigned int *) uidnext : 0;
201  mdata->modseq = modseq ? *modseq : 0;
202  mutt_debug(LL_DEBUG3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
203  mdata->uid_validity, mdata->uid_next, mdata->modseq);
204  }
205  mutt_hcache_free(hc, &uidvalidity);
206  mutt_hcache_free(hc, &uidnext);
207  mutt_hcache_free(hc, (void **) &modseq);
208  mutt_hcache_close(hc);
209  }
210 #endif
211 
212  return mdata;
213 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void * mutt_hcache_fetch_raw(header_cache_t *hc, const char *key, size_t keylen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:373
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:220
void mutt_hcache_close(header_cache_t *hc)
Multiplexor for HcacheOps::close.
Definition: hcache.c:329
#define STAILQ_INIT(head)
Definition: queue.h:369
const char * name
Definition: pgpmicalg.c:46
void * mdata
Driver specific data.
Definition: mailbox.h:135
unsigned long long modseq
Definition: imap_private.h:228
struct ListHead flags
Definition: imap_private.h:225
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
char * name
Mailbox name.
Definition: imap_private.h:216
char * imap_fix_path(char server_delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:823
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: imap_private.h:218
unsigned int uid_validity
Definition: imap_private.h:226
unsigned int uid_next
Definition: imap_private.h:227
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:443
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:392
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1059
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
header cache structure
Definition: lib.h:67
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:217
Log at debug level 3.
Definition: logging.h:42
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: imap_private.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_free()

void imap_mdata_free ( void **  ptr)

Release and clear storage in an ImapMboxData structure.

Parameters
[out]ptrImap Mailbox data

Definition at line 232 of file util.c.

233 {
234  if (!ptr || !*ptr)
235  return;
236 
237  struct ImapMboxData *mdata = *ptr;
238 
239  imap_mdata_cache_reset(mdata);
240  mutt_list_free(&mdata->flags);
241  FREE(&mdata->name);
242  FREE(&mdata->real_name);
243  FREE(&mdata->munge_name);
244  FREE(ptr);
245 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct ListHead flags
Definition: imap_private.h:225
char * name
Mailbox name.
Definition: imap_private.h:216
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:219
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: imap_private.h:218
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
#define FREE(x)
Definition: memory.h:40
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_cache_reset()

void imap_mdata_cache_reset ( struct ImapMboxData mdata)

Release and clear cache data of ImapMboxData structure.

Parameters
mdataImap Mailbox data

Definition at line 219 of file util.c.

220 {
221  mutt_hash_free(&mdata->uid_hash);
222  FREE(&mdata->msn_index);
223  mdata->msn_index_size = 0;
224  mdata->max_msn = 0;
225  mutt_bcache_close(&mdata->bcache);
226 }
struct Email ** msn_index
look up headers by (MSN-1)
Definition: imap_private.h:235
size_t msn_index_size
allocation size
Definition: imap_private.h:236
unsigned int max_msn
the largest MSN fetched so far
Definition: imap_private.h:237
struct BodyCache * bcache
Definition: imap_private.h:238
struct Hash * uid_hash
Definition: imap_private.h:234
#define FREE(x)
Definition: memory.h:40
void mutt_hash_free(struct Hash **ptr)
Free a hash table.
Definition: hash.c:471
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:153
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_fix_path()

char* imap_fix_path ( char  server_delim,
const char *  mailbox,
char *  path,
size_t  plen 
)

Fix up the imap path.

Parameters
server_delimImap Server Delim
mailboxMailbox path
pathBuffer for the result
plenLength of buffer
Return values
ptrFixed-up path

This is necessary because the rest of neomutt assumes a hierarchy delimiter of '/', which is not necessarily true in IMAP. Additionally, the filesystem converts multiple hierarchy delimiters into a single one, ie "///" is equal to "/". IMAP servers are not required to do this. Moreover, IMAP servers may dislike the path ending with the delimiter.

Definition at line 823 of file util.c.

824 {
825  int i = 0;
826  char delim = server_delim;
827 
828  while (mailbox && *mailbox && (i < plen - 1))
829  {
830  if ((C_ImapDelimChars && strchr(C_ImapDelimChars, *mailbox)) ||
831  (delim && (*mailbox == delim)))
832  {
833  /* use connection delimiter if known. Otherwise use user delimiter */
834  if (server_delim == '\0')
835  delim = *mailbox;
836 
837  while (*mailbox && ((C_ImapDelimChars && strchr(C_ImapDelimChars, *mailbox)) ||
838  (delim && (*mailbox == delim))))
839  {
840  mailbox++;
841  }
842  path[i] = delim;
843  }
844  else
845  {
846  path[i] = *mailbox;
847  mailbox++;
848  }
849  i++;
850  }
851  if (i && (path[--i] != delim))
852  i++;
853  path[i] = '\0';
854 
855  return path;
856 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: util.c:62
+ Here is the caller graph for this function:

◆ imap_cachepath()

void imap_cachepath ( char  delim,
const char *  mailbox,
struct Buffer dest 
)

Generate a cache path for a mailbox.

Parameters
delimImap server delimiter
mailboxMailbox name
destBuffer to store cache path

Definition at line 864 of file util.c.

865 {
866  const char *p = mailbox;
867  mutt_buffer_reset(dest);
868  if (!p)
869  return;
870 
871  while (*p)
872  {
873  if (p[0] == delim)
874  {
875  mutt_buffer_addch(dest, '/');
876  /* simple way to avoid collisions with UIDs */
877  if ((p[1] >= '0') && (p[1] <= '9'))
878  mutt_buffer_addch(dest, '_');
879  }
880  else
881  mutt_buffer_addch(dest, *p);
882  p++;
883  }
884 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_literal_count()

int imap_get_literal_count ( const char *  buf,
unsigned int *  bytes 
)

write number of bytes in an IMAP literal into bytes

Parameters
[in]bufNumber as a string
[out]bytesResulting number
Return values
0Success
-1Failure

Definition at line 893 of file util.c.

894 {
895  char *pc = NULL;
896  char *pn = NULL;
897 
898  if (!buf || !(pc = strchr(buf, '{')))
899  return -1;
900 
901  pc++;
902  pn = pc;
903  while (isdigit((unsigned char) *pc))
904  pc++;
905  *pc = '\0';
906  if (mutt_str_atoui(pn, bytes) < 0)
907  return -1;
908 
909  return 0;
910 }
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:292
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_qualifier()

char* imap_get_qualifier ( char *  buf)

Get the qualifier from a tagged response.

Parameters
bufCommand string to process
Return values
ptrStart of the qualifier

In a tagged response, skip tag and status for the qualifier message. Used by imap_copy_message for TRYCREATE

Definition at line 920 of file util.c.

921 {
922  char *s = buf;
923 
924  /* skip tag */
925  s = imap_next_word(s);
926  /* skip OK/NO/BAD response */
927  s = imap_next_word(s);
928 
929  return s;
930 }
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:937
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_next_word()

char* imap_next_word ( char *  s)

Find where the next IMAP word begins.

Parameters
sCommand string to process
Return values
ptrNext IMAP word

Definition at line 937 of file util.c.

938 {
939  bool quoted = false;
940 
941  while (*s)
942  {
943  if (*s == '\\')
944  {
945  s++;
946  if (*s)
947  s++;
948  continue;
949  }
950  if (*s == '\"')
951  quoted = !quoted;
952  if (!quoted && IS_SPACE(*s))
953  break;
954  s++;
955  }
956 
957  SKIPWS(s);
958  return s;
959 }
#define SKIPWS(ch)
Definition: string2.h:47
#define IS_SPACE(ch)
Definition: string2.h:38
+ Here is the caller graph for this function:

◆ imap_qualify_path()

void imap_qualify_path ( char *  buf,
size_t  buflen,
struct ConnAccount cac,
char *  path 
)

Make an absolute IMAP folder target.

Parameters
bufBuffer for the result
buflenLength of buffer
cacConnAccount of the account
pathPath relative to the mailbox

Definition at line 968 of file util.c.

969 {
970  struct Url url = { 0 };
971  mutt_account_tourl(cac, &url);
972  url.path = path;
973  url_tostring(&url, buf, buflen, 0);
974 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:85
char * path
Path.
Definition: url.h:73
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:423
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_quote_string()

void imap_quote_string ( char *  dest,
size_t  dlen,
const char *  src,
bool  quote_backtick 
)

quote string according to IMAP rules

Parameters
destBuffer for the result
dlenLength of the buffer
srcString to be quoted
quote_backtickIf true, quote backticks too

Surround string with quotes, escape " and \ with backslash

Definition at line 985 of file util.c.

986 {
987  const char *quote = "`\"\\";
988  if (!quote_backtick)
989  quote++;
990 
991  char *pt = dest;
992  const char *s = src;
993 
994  *pt++ = '"';
995  /* save room for quote-chars */
996  dlen -= 3;
997 
998  for (; *s && dlen; s++)
999  {
1000  if (strchr(quote, *s))
1001  {
1002  if (dlen < 2)
1003  break;
1004  dlen -= 2;
1005  *pt++ = '\\';
1006  *pt++ = *s;
1007  }
1008  else
1009  {
1010  *pt++ = *s;
1011  dlen--;
1012  }
1013  }
1014  *pt++ = '"';
1015  *pt = '\0';
1016 }
char * src
Raw URL string.
Definition: url.h:75
+ Here is the caller graph for this function:

◆ imap_unquote_string()

void imap_unquote_string ( char *  s)

equally stupid unquoting routine

Parameters
sString to be unquoted

Definition at line 1022 of file util.c.

1023 {
1024  char *d = s;
1025 
1026  if (*s == '\"')
1027  s++;
1028  else
1029  return;
1030 
1031  while (*s)
1032  {
1033  if (*s == '\"')
1034  {
1035  *d = '\0';
1036  return;
1037  }
1038  if (*s == '\\')
1039  {
1040  s++;
1041  }
1042  if (*s)
1043  {
1044  *d = *s;
1045  d++;
1046  s++;
1047  }
1048  }
1049  *d = '\0';
1050 }
+ Here is the caller graph for this function:

◆ imap_munge_mbox_name()

void imap_munge_mbox_name ( bool  unicode,
char *  dest,
size_t  dlen,
const char *  src 
)

Quote awkward characters in a mailbox name.

Parameters
unicodetrue if Unicode is allowed
destBuffer to store safe mailbox name
dlenLength of buffer
srcMailbox name

Definition at line 1059 of file util.c.

1060 {
1061  char *buf = mutt_str_strdup(src);
1062  imap_utf_encode(unicode, &buf);
1063 
1064  imap_quote_string(dest, dlen, buf, false);
1065 
1066  FREE(&buf);
1067 }
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition: utf7.c:316
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:985
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
char * src
Raw URL string.
Definition: url.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_unmunge_mbox_name()

void imap_unmunge_mbox_name ( bool  unicode,
char *  s 
)

Remove quoting from a mailbox name.

Parameters
unicodetrue if Unicode is allowed
sMailbox name

The string will be altered in-place.

Definition at line 1076 of file util.c.

1077 {
1079 
1080  char *buf = mutt_str_strdup(s);
1081  if (buf)
1082  {
1083  imap_utf_decode(unicode, &buf);
1084  strncpy(s, buf, strlen(s));
1085  }
1086 
1087  FREE(&buf);
1088 }
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:345
void imap_unquote_string(char *s)
equally stupid unquoting routine
Definition: util.c:1022
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_new()

struct SeqsetIterator* mutt_seqset_iterator_new ( const char *  seqset)

Create a new Sequence Set Iterator.

Parameters
seqsetSource Sequence Set
Return values
ptrNewly allocated Sequence Set Iterator

Definition at line 1223 of file util.c.

1224 {
1225  if (!seqset || !*seqset)
1226  return NULL;
1227 
1228  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1229  iter->full_seqset = mutt_str_strdup(seqset);
1230  iter->eostr = strchr(iter->full_seqset, '\0');
1231  iter->substr_cur = iter->substr_end = iter->full_seqset;
1232 
1233  return iter;
1234 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * full_seqset
Definition: imap_private.h:248
UID Sequence Set Iterator.
Definition: imap_private.h:246
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_next()

int mutt_seqset_iterator_next ( struct SeqsetIterator iter,
unsigned int *  next 
)

Get the next UID from a Sequence Set.

Parameters
[in]iterSequence Set Iterator
[out]nextNext UID in set
Return values
0Next sequence is generated
1Iterator is finished
-1error

Definition at line 1244 of file util.c.

1245 {
1246  if (!iter || !next)
1247  return -1;
1248 
1249  if (iter->in_range)
1250  {
1251  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1252  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1253  {
1254  iter->in_range = 0;
1255  }
1256  }
1257 
1258  if (!iter->in_range)
1259  {
1260  iter->substr_cur = iter->substr_end;
1261  if (iter->substr_cur == iter->eostr)
1262  return 1;
1263 
1264  while (!*(iter->substr_cur))
1265  iter->substr_cur++;
1266  iter->substr_end = strchr(iter->substr_cur, ',');
1267  if (!iter->substr_end)
1268  iter->substr_end = iter->eostr;
1269  else
1270  *(iter->substr_end) = '\0';
1271 
1272  char *range_sep = strchr(iter->substr_cur, ':');
1273  if (range_sep)
1274  *range_sep++ = '\0';
1275 
1276  if (mutt_str_atoui(iter->substr_cur, &iter->range_cur) != 0)
1277  return -1;
1278  if (range_sep)
1279  {
1280  if (mutt_str_atoui(range_sep, &iter->range_end) != 0)
1281  return -1;
1282  }
1283  else
1284  iter->range_end = iter->range_cur;
1285 
1286  iter->down = (iter->range_end < iter->range_cur);
1287  iter->in_range = 1;
1288  }
1289 
1290  *next = iter->range_cur;
1291  if (iter->down)
1292  iter->range_cur--;
1293  else
1294  iter->range_cur++;
1295 
1296  return 0;
1297 }
unsigned int range_end
Definition: imap_private.h:253
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:292
unsigned int range_cur
Definition: imap_private.h:252
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_free()

void mutt_seqset_iterator_free ( struct SeqsetIterator **  ptr)

Free a Sequence Set Iterator.

Parameters
[out]ptrIterator to free

Definition at line 1303 of file util.c.

1304 {
1305  if (!ptr || !*ptr)
1306  return;
1307 
1308  struct SeqsetIterator *iter = *ptr;
1309  FREE(&iter->full_seqset);
1310  FREE(ptr);
1311 }
#define FREE(x)
Definition: memory.h:40
char * full_seqset
Definition: imap_private.h:248
UID Sequence Set Iterator.
Definition: imap_private.h:246
+ Here is the caller graph for this function:

◆ imap_account_match()

bool imap_account_match ( const struct ConnAccount a1,
const struct ConnAccount a2 
)

Compare two Accounts.

Parameters
a1First ConnAccount
a2Second ConnAccount
Return values
trueAccounts match

Definition at line 1192 of file util.c.

1193 {
1194  if (!a1 || !a2)
1195  return false;
1196  if (a1->type != a2->type)
1197  return false;
1198  if (mutt_str_strcasecmp(a1->host, a2->host) != 0)
1199  return false;
1200  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1201  return false;
1202  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1203  return strcmp(a1->user, a2->user) == 0;
1204 
1205  const char *user = NONULL(Username);
1206 
1207  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && C_ImapUser)
1208  user = C_ImapUser;
1209 
1210  if (a1->flags & MUTT_ACCT_USER)
1211  return strcmp(a1->user, user) == 0;
1212  if (a2->flags & MUTT_ACCT_USER)
1213  return strcmp(a2->user, user) == 0;
1214 
1215  return true;
1216 }
WHERE char * Username
User&#39;s login name.
Definition: globals.h:52
#define NONULL(x)
Definition: string2.h:37
char user[128]
Definition: connaccount.h:60
WHERE char * C_ImapUser
Config: (imap) Username for the IMAP server.
Definition: globals.h:115
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:50
char host[128]
Definition: connaccount.h:63
unsigned short port
Definition: connaccount.h:64
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:65
Imap Account.
Definition: mutt_account.h:40
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_parent()

void imap_get_parent ( const char *  mbox,
char  delim,
char *  buf,
size_t  buflen 
)

Get an IMAP folder's parent.

Parameters
mboxMailbox whose parent is to be determined
delimPath delimiter
bufBuffer for the result
buflenLength of the buffer

Definition at line 265 of file util.c.

266 {
267  /* Make a copy of the mailbox name, but only if the pointers are different */
268  if (mbox != buf)
269  mutt_str_strfcpy(buf, mbox, buflen);
270 
271  int n = mutt_str_strlen(buf);
272 
273  /* Let's go backwards until the next delimiter
274  *
275  * If buf[n] is a '/', the first n-- will allow us
276  * to ignore it. If it isn't, then buf looks like
277  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
278  * the "/" after the 'a's.
279  *
280  * If buf == '/', then n-- => n == 0, so the loop ends
281  * immediately */
282  for (n--; (n >= 0) && (buf[n] != delim); n--)
283  ;
284 
285  /* We stopped before the beginning. There is a trailing slash. */
286  if (n > 0)
287  {
288  /* Strip the trailing delimiter. */
289  buf[n] = '\0';
290  }
291  else
292  {
293  buf[0] = (n == 0) ? delim : '\0';
294  }
295 }
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_account_match()

bool mutt_account_match ( const struct ConnAccount a1,
const struct ConnAccount a2 
)

◆ imap_utf_encode()

void imap_utf_encode ( bool  unicode,
char **  s 
)

Encode email from local charset to UTF-8.

Parameters
[in]unicodetrue if Unicode is allowed
[out]sEmail to convert

Definition at line 316 of file utf7.c.

317 {
318  if (!C_Charset || !s || !*s)
319  return;
320 
321  if (unicode && mutt_ch_is_utf8(C_Charset))
322  {
323  return;
324  }
325 
326  if (mutt_ch_convert_string(s, C_Charset, "utf-8", 0) != 0)
327  {
328  FREE(s);
329  return;
330  }
331 
332  if (!unicode)
333  {
334  char *utf7 = utf8_to_utf7(*s, strlen(*s), NULL, 0);
335  FREE(s);
336  *s = utf7;
337  }
338 }
#define mutt_ch_is_utf8(str)
Definition: charset.h:106
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:748
static char * utf8_to_utf7(const char *u8, size_t u8len, char **u7, size_t *u7len)
Convert data from UTF-8 to RFC2060&#39;s UTF-7.
Definition: utf7.c:193
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_utf_decode()

void imap_utf_decode ( bool  unicode,
char **  s 
)

Decode email from UTF-8 to local charset.

Parameters
[in]unicodetrue if Unicode is allowed
[out]sEmail to convert

Definition at line 345 of file utf7.c.

346 {
347  if (!C_Charset || !s || !*s)
348  return;
349 
350  if (unicode && mutt_ch_is_utf8(C_Charset))
351  {
352  return;
353  }
354 
355  if (!unicode)
356  {
357  char *utf8 = utf7_to_utf8(*s, strlen(*s), 0, 0);
358  FREE(s);
359  *s = utf8;
360  }
361 
362  if (mutt_ch_convert_string(s, "utf-8", C_Charset, 0) != 0)
363  {
364  FREE(s);
365  }
366 }
#define mutt_ch_is_utf8(str)
Definition: charset.h:106
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:748
static char * utf7_to_utf8(const char *u7, size_t u7len, char **u8, size_t *u8len)
Convert data from RFC2060&#39;s UTF-7 to UTF-8.
Definition: utf7.c:83
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_allow_reopen()

void imap_allow_reopen ( struct Mailbox m)

Allow re-opening a folder upon expunge.

Parameters
mMailbox

Definition at line 1164 of file util.c.

1165 {
1166  struct ImapAccountData *adata = imap_adata_get(m);
1167  struct ImapMboxData *mdata = imap_mdata_get(m);
1168  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1169  return;
1170  mdata->reopen |= IMAP_REOPEN_ALLOW;
1171 }
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:220
struct Mailbox * mailbox
Definition: imap_private.h:205
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: imap_private.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_disallow_reopen()

void imap_disallow_reopen ( struct Mailbox m)

Disallow re-opening a folder upon expunge.

Parameters
mMailbox

Definition at line 1177 of file util.c.

1178 {
1179  struct ImapAccountData *adata = imap_adata_get(m);
1180  struct ImapMboxData *mdata = imap_mdata_get(m);
1181  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1182  return;
1183  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1184 }
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:220
struct Mailbox * mailbox
Definition: imap_private.h:205
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:251
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: imap_private.h:167
IMAP-specific Mailbox data -.
Definition: imap_private.h:214
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: imap_private.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function: