NeoMutt  2020-08-21-74-g346364
Teaching an old dog new tricks
DOXYGEN
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 "hcache/lib.h"
+ Include dependency graph for 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_CMD_SINGLE   (1 << 3)
 Run a single 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
 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 the private Email data - Implements Email::edata_free() 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...
 
void imap_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)
 Free the private Account data - Implements Account::adata_free() 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)
 Free the private Mailbox data - Implements Mailbox::mdata_free() 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...
 
void cmd_parse_search (struct ImapAccountData *adata, const char *s)
 store SEARCH response for later use More...
 

Variables

struct SlistC_ImapAuthenticators
 Config: (imap) List of allowed IMAP authentication methods. More...
 
bool C_ImapCheckSubscribed
 Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders. More...
 
bool C_ImapCondstore
 Config: (imap) Enable the CONDSTORE extension. More...
 
bool C_ImapDeflate
 Config: (imap) Compress network traffic. More...
 
char * C_ImapDelimChars
 Config: (imap) Characters that denote separators in IMAP folders. More...
 
long C_ImapFetchChunkSize
 Config: (imap) Download headers in blocks of this size. More...
 
char * C_ImapHeaders
 Config: (imap) Additional email headers to download when getting index. More...
 
bool C_ImapIdle
 Config: (imap) Use the IMAP IDLE extension to check for new mail. More...
 
char * C_ImapLogin
 Config: (imap) Login name for the IMAP server (defaults to C_ImapUser) More...
 
char * C_ImapOauthRefreshCommand
 Config: (imap) External command to generate OAUTH refresh token. More...
 
char * C_ImapPass
 Config: (imap) Password for the IMAP server. More...
 
short C_ImapPipelineDepth
 Config: (imap) Number of IMAP commands that may be queued up. More...
 
short C_ImapPollTimeout
 Config: (imap) Maximum time to wait for a server response. More...
 
bool C_ImapQresync
 Config: (imap) Enable the QRESYNC extension. More...
 
bool C_ImapRfc5161
 Config: (imap) Use the IMAP ENABLE extension to select capabilities. More...
 
bool C_ImapServernoise
 Config: (imap) Display server warnings as error messages. More...
 
char * C_ImapUser
 Config: (imap) Username for the IMAP server. 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 private.h.

Macro Definition Documentation

◆ IMAP_PORT

#define IMAP_PORT   143

Default port for IMAP.

Definition at line 45 of file private.h.

◆ IMAP_SSL_PORT

#define IMAP_SSL_PORT   993

Port for IMAP over SSL/TLS.

Definition at line 46 of file private.h.

◆ IMAP_LOG_CMD

#define IMAP_LOG_CMD   2

Definition at line 49 of file private.h.

◆ IMAP_LOG_LTRL

#define IMAP_LOG_LTRL   3

Definition at line 50 of file private.h.

◆ IMAP_LOG_PASS

#define IMAP_LOG_PASS   5

Definition at line 51 of file private.h.

◆ IMAP_RES_NO

#define IMAP_RES_NO   -2

<tag> NO ...

Definition at line 54 of file private.h.

◆ IMAP_RES_BAD

#define IMAP_RES_BAD   -1

<tag> BAD ...

Definition at line 55 of file private.h.

◆ IMAP_RES_OK

#define IMAP_RES_OK   0

<tag> OK ...

Definition at line 56 of file private.h.

◆ IMAP_RES_CONTINUE

#define IMAP_RES_CONTINUE   1

* ...

Definition at line 57 of file private.h.

◆ IMAP_RES_RESPOND

#define IMAP_RES_RESPOND   2

+

Definition at line 58 of file private.h.

◆ IMAP_RES_NEW

#define IMAP_RES_NEW   3

ImapCommand.state additions.

Definition at line 59 of file private.h.

◆ SEQ_LEN

#define SEQ_LEN   16

Definition at line 61 of file 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 62 of file private.h.

◆ IMAP_OPEN_NO_FLAGS

#define IMAP_OPEN_NO_FLAGS   0

No flags are set.

Definition at line 65 of file private.h.

◆ IMAP_REOPEN_ALLOW

#define IMAP_REOPEN_ALLOW   (1 << 0)

Allow re-opening a folder upon expunge.

Definition at line 66 of file private.h.

◆ IMAP_EXPUNGE_EXPECTED

#define IMAP_EXPUNGE_EXPECTED   (1 << 1)

Messages will be expunged from the server.

Definition at line 67 of file private.h.

◆ IMAP_EXPUNGE_PENDING

#define IMAP_EXPUNGE_PENDING   (1 << 2)

Messages on the server have been expunged.

Definition at line 68 of file private.h.

◆ IMAP_NEWMAIL_PENDING

#define IMAP_NEWMAIL_PENDING   (1 << 3)

New mail is waiting on the server.

Definition at line 69 of file private.h.

◆ IMAP_FLAGS_PENDING

#define IMAP_FLAGS_PENDING   (1 << 4)

Flags have changed on the server.

Definition at line 70 of file private.h.

◆ IMAP_CMD_NO_FLAGS

#define IMAP_CMD_NO_FLAGS   0

No flags are set.

Definition at line 73 of file private.h.

◆ IMAP_CMD_PASS

#define IMAP_CMD_PASS   (1 << 0)

Command contains a password. Suppress logging.

Definition at line 74 of file private.h.

◆ IMAP_CMD_QUEUE

#define IMAP_CMD_QUEUE   (1 << 1)

Queue a command, do not execute.

Definition at line 75 of file private.h.

◆ IMAP_CMD_POLL

#define IMAP_CMD_POLL   (1 << 2)

Poll the tcp connection before running the imap command.

Definition at line 76 of file private.h.

◆ IMAP_CMD_SINGLE

#define IMAP_CMD_SINGLE   (1 << 3)

Run a single command.

Definition at line 77 of file private.h.

◆ IMAP_DATELEN

#define IMAP_DATELEN   27

Definition at line 90 of file private.h.

◆ IMAP_CAP_NO_FLAGS

#define IMAP_CAP_NO_FLAGS   0

No flags are set.

Definition at line 122 of file private.h.

◆ IMAP_CAP_IMAP4

#define IMAP_CAP_IMAP4   (1 << 0)

Server supports IMAP4.

Definition at line 123 of file private.h.

◆ IMAP_CAP_IMAP4REV1

#define IMAP_CAP_IMAP4REV1   (1 << 1)

Server supports IMAP4rev1.

Definition at line 124 of file private.h.

◆ IMAP_CAP_STATUS

#define IMAP_CAP_STATUS   (1 << 2)

Server supports STATUS command.

Definition at line 125 of file private.h.

◆ IMAP_CAP_ACL

#define IMAP_CAP_ACL   (1 << 3)

RFC2086: IMAP4 ACL extension.

Definition at line 126 of file private.h.

◆ IMAP_CAP_NAMESPACE

#define IMAP_CAP_NAMESPACE   (1 << 4)

RFC2342: IMAP4 Namespace.

Definition at line 127 of file private.h.

◆ IMAP_CAP_AUTH_CRAM_MD5

#define IMAP_CAP_AUTH_CRAM_MD5   (1 << 5)

RFC2195: CRAM-MD5 authentication.

Definition at line 128 of file private.h.

◆ IMAP_CAP_AUTH_GSSAPI

#define IMAP_CAP_AUTH_GSSAPI   (1 << 6)

RFC1731: GSSAPI authentication.

Definition at line 129 of file private.h.

◆ IMAP_CAP_AUTH_ANONYMOUS

#define IMAP_CAP_AUTH_ANONYMOUS   (1 << 7)

AUTH=ANONYMOUS.

Definition at line 130 of file private.h.

◆ IMAP_CAP_AUTH_OAUTHBEARER

#define IMAP_CAP_AUTH_OAUTHBEARER   (1 << 8)

RFC7628: AUTH=OAUTHBEARER.

Definition at line 131 of file private.h.

◆ IMAP_CAP_STARTTLS

#define IMAP_CAP_STARTTLS   (1 << 9)

RFC2595: STARTTLS.

Definition at line 132 of file private.h.

◆ IMAP_CAP_LOGINDISABLED

#define IMAP_CAP_LOGINDISABLED   (1 << 10)

RFC2595: LOGINDISABLED.

Definition at line 133 of file private.h.

◆ IMAP_CAP_IDLE

#define IMAP_CAP_IDLE   (1 << 11)

RFC2177: IDLE.

Definition at line 134 of file private.h.

◆ IMAP_CAP_SASL_IR

#define IMAP_CAP_SASL_IR   (1 << 12)

SASL initial response draft.

Definition at line 135 of file private.h.

◆ IMAP_CAP_ENABLE

#define IMAP_CAP_ENABLE   (1 << 13)

RFC5161.

Definition at line 136 of file private.h.

◆ IMAP_CAP_CONDSTORE

#define IMAP_CAP_CONDSTORE   (1 << 14)

RFC7162.

Definition at line 137 of file private.h.

◆ IMAP_CAP_QRESYNC

#define IMAP_CAP_QRESYNC   (1 << 15)

RFC7162.

Definition at line 138 of file private.h.

◆ IMAP_CAP_LIST_EXTENDED

#define IMAP_CAP_LIST_EXTENDED   (1 << 16)

RFC5258: IMAP4 LIST Command Extensions.

Definition at line 139 of file private.h.

◆ IMAP_CAP_COMPRESS

#define IMAP_CAP_COMPRESS   (1 << 17)

RFC4978: COMPRESS=DEFLATE.

Definition at line 140 of file 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 143 of file private.h.

Typedef Documentation

◆ ImapOpenFlags

typedef uint8_t ImapOpenFlags

Flags, e.g. MUTT_THREAD_COLLAPSE.

Definition at line 64 of file private.h.

◆ ImapCmdFlags

typedef uint8_t ImapCmdFlags

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

Definition at line 72 of file private.h.

◆ ImapCapFlags

typedef uint32_t 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 121 of file 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 82 of file private.h.

83 {
84  IMAP_EXEC_SUCCESS = 0,
87 };
Imap connection failure.
Definition: private.h:86
Imap command executed or queued successfully.
Definition: private.h:84
Imap command failure.
Definition: private.h:85

◆ ImapFlags

enum ImapFlags

IMAP server responses.

Enumerator
IMAP_FATAL 

Unrecoverable error occurred.

IMAP_BYE 

Logged out from server.

Definition at line 95 of file private.h.

96 {
97  IMAP_FATAL = 1,
98  IMAP_BYE,
99 };
Logged out from server.
Definition: private.h:98
Unrecoverable error occurred.
Definition: private.h:97

◆ 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 104 of file private.h.

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

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 425 of file imap.c.

426 {
427  char buf[2048], mbox[1024];
428 
429  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), mailbox);
430  snprintf(buf, sizeof(buf), "CREATE %s", mbox);
431 
432  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
433  {
434  mutt_error(_("CREATE failed: %s"), imap_cmd_trailer(adata));
435  return -1;
436  }
437 
438  return 0;
439 }
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:1045
#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:1205
Imap command executed or queued successfully.
Definition: private.h:84
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:1242
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
#define mutt_error(...)
Definition: logging.h:84
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
+ 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 466 of file imap.c.

467 {
468  char oldmbox[1024];
469  char newmbox[1024];
470  int rc = 0;
471 
472  imap_munge_mbox_name(adata->unicode, oldmbox, sizeof(oldmbox), oldname);
473  imap_munge_mbox_name(adata->unicode, newmbox, sizeof(newmbox), newname);
474 
475  struct Buffer *buf = mutt_buffer_pool_get();
476  mutt_buffer_printf(buf, "RENAME %s %s", oldmbox, newmbox);
477 
479  rc = -1;
480 
482 
483  return rc;
484 }
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:1045
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: private.h:84
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:1242
#define mutt_b2s(buf)
Definition: buffer.h:41
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
+ 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 899 of file imap.c.

901 {
902  struct ImapAccountData *adata = imap_adata_get(m);
903  if (!adata || (adata->mailbox != m))
904  return -1;
905 
906  struct Email **emails = NULL;
907  short oldsort;
908  int pos;
909  int rc;
910  int count = 0;
911 
912  struct Buffer cmd = mutt_buffer_make(0);
913 
914  /* We make a copy of the headers just in case resorting doesn't give
915  exactly the original order (duplicate messages?), because other parts of
916  the ctx are tied to the header order. This may be overkill. */
917  oldsort = C_Sort;
918  if (C_Sort != SORT_ORDER)
919  {
920  emails = m->emails;
921  // We overcommit here, just in case new mail arrives whilst we're sync-ing
922  m->emails = mutt_mem_malloc(m->email_max * sizeof(struct Email *));
923  memcpy(m->emails, emails, m->email_max * sizeof(struct Email *));
924 
925  C_Sort = SORT_ORDER;
926  qsort(m->emails, m->msg_count, sizeof(struct Email *), compare_uid);
927  }
928 
929  pos = 0;
930 
931  do
932  {
933  mutt_buffer_reset(&cmd);
934  mutt_buffer_add_printf(&cmd, "%s ", pre);
935  rc = make_msg_set(m, &cmd, flag, changed, invert, &pos);
936  if (rc > 0)
937  {
938  mutt_buffer_add_printf(&cmd, " %s", post);
939  if (imap_exec(adata, cmd.data, IMAP_CMD_QUEUE) != IMAP_EXEC_SUCCESS)
940  {
941  rc = -1;
942  goto out;
943  }
944  count += rc;
945  }
946  } while (rc > 0);
947 
948  rc = count;
949 
950 out:
951  mutt_buffer_dealloc(&cmd);
952  if (oldsort != C_Sort)
953  {
954  C_Sort = oldsort;
955  FREE(&m->emails);
956  m->emails = emails;
957  }
958 
959  return rc;
960 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
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:177
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
Imap command executed or queued successfully.
Definition: private.h:84
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:51
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:60
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:1242
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
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
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
#define FREE(x)
Definition: memory.h:40
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
static int compare_uid(const void *a, const void *b)
Compare two Emails by UID - Implements sort_t.
Definition: imap.c:876
+ 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 719 of file imap.c.

720 {
721  if (mutt_socket_open(adata->conn) < 0)
722  return -1;
723 
724  adata->state = IMAP_CONNECTED;
725 
726  if (imap_cmd_step(adata) != IMAP_RES_OK)
727  {
728  imap_close_connection(adata);
729  return -1;
730  }
731 
732  if (mutt_istr_startswith(adata->buf, "* OK"))
733  {
734  if (!mutt_istr_startswith(adata->buf, "* OK [CAPABILITY") && check_capabilities(adata))
735  {
736  goto bail;
737  }
738 #ifdef USE_SSL
739  /* Attempt STARTTLS if available and desired. */
740  if ((adata->conn->ssf == 0) && (C_SslForceTls || (adata->capabilities & IMAP_CAP_STARTTLS)))
741  {
742  enum QuadOption ans;
743 
744  if (C_SslForceTls)
745  ans = MUTT_YES;
746  else if ((ans = query_quadoption(C_SslStarttls,
747  _("Secure connection with TLS?"))) == MUTT_ABORT)
748  {
749  goto err_close_conn;
750  }
751  if (ans == MUTT_YES)
752  {
753  enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_SINGLE);
754  // Clear any data after the STARTTLS acknowledgement
755  mutt_socket_empty(adata->conn);
756 
757  if (rc == IMAP_EXEC_FATAL)
758  goto bail;
759  if (rc != IMAP_EXEC_ERROR)
760  {
761  if (mutt_ssl_starttls(adata->conn))
762  {
763  mutt_error(_("Could not negotiate TLS connection"));
764  goto err_close_conn;
765  }
766  else
767  {
768  /* RFC2595 demands we recheck CAPABILITY after TLS completes. */
769  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS))
770  goto bail;
771  }
772  }
773  }
774  }
775 
776  if (C_SslForceTls && (adata->conn->ssf == 0))
777  {
778  mutt_error(_("Encrypted connection unavailable"));
779  goto err_close_conn;
780  }
781 #endif
782  }
783  else if (mutt_istr_startswith(adata->buf, "* PREAUTH"))
784  {
785 #ifdef USE_SSL
786  /* Unless using a secure $tunnel, an unencrypted PREAUTH response may be a
787  * MITM attack. The only way to stop "STARTTLS" MITM attacks is via
788  * $ssl_force_tls: an attacker can easily spoof "* OK" and strip the
789  * STARTTLS capability. So consult $ssl_force_tls, not $ssl_starttls, to
790  * decide whether to abort. Note that if using $tunnel and
791  * $tunnel_is_secure, adata->conn->ssf will be set to 1. */
792  if ((adata->conn->ssf == 0) && C_SslForceTls)
793  {
794  mutt_error(_("Encrypted connection unavailable"));
795  goto err_close_conn;
796  }
797 #endif
798 
799  adata->state = IMAP_AUTHENTICATED;
800  if (check_capabilities(adata) != 0)
801  goto bail;
802  FREE(&adata->capstr);
803  }
804  else
805  {
806  imap_error("imap_open_connection()", adata->buf);
807  goto bail;
808  }
809 
810  return 0;
811 
812 #ifdef USE_SSL
813 err_close_conn:
814  imap_close_connection(adata);
815 #endif
816 bail:
817  FREE(&adata->capstr);
818  return -1;
819 }
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
Imap connection failure.
Definition: private.h:86
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:37
Connection is authenticated.
Definition: private.h:109
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
#define _(a)
Definition: message.h:28
void imap_close_connection(struct ImapAccountData *adata)
Close an IMAP connection.
Definition: imap.c:825
char * capstr
Definition: private.h:185
ImapExecResult
imap_exec return code
Definition: private.h:82
#define IMAP_CAP_STARTTLS
RFC2595: STARTTLS.
Definition: private.h:132
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:75
Connected to server.
Definition: private.h:108
User aborted the question (with Ctrl-G)
Definition: quad.h:38
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:1242
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: config.c:47
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
ImapCapFlags capabilities
Definition: private.h:186
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: config.c:46
Imap command failure.
Definition: private.h:85
void mutt_socket_empty(struct Connection *conn)
Clear out any queued data.
Definition: socket.c:312
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:517
char * buf
Definition: private.h:190
#define mutt_error(...)
Definition: logging.h:84
#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:74
#define IMAP_CMD_SINGLE
Run a single command.
Definition: private.h:77
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1136
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Connection * conn
Definition: private.h:172
+ 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 825 of file imap.c.

826 {
827  if (adata->state != IMAP_DISCONNECTED)
828  {
829  mutt_socket_close(adata->conn);
830  adata->state = IMAP_DISCONNECTED;
831  }
832  adata->seqno = 0;
833  adata->nextcmd = 0;
834  adata->lastcmd = 0;
835  adata->status = 0;
836  memset(adata->cmds, 0, sizeof(struct ImapCommand) * adata->cmdslots);
837 }
struct ImapCommand * cmds
Definition: private.h:200
unsigned int seqno
tag sequence number, e.g. &#39;{seqid}0001&#39;
Definition: private.h:188
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
Disconnected from server.
Definition: private.h:107
IMAP command structure.
Definition: private.h:159
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: private.h:176
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:96
struct Connection * conn
Definition: private.h:172
+ 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 574 of file imap.c.

576 {
577  char c;
578  bool r = false;
579  struct Buffer buf = { 0 }; // Do not allocate, maybe it won't be used
580 
582  mutt_buffer_alloc(&buf, bytes + 10);
583 
584  mutt_debug(LL_DEBUG2, "reading %ld bytes\n", bytes);
585 
586  for (unsigned long pos = 0; pos < bytes; pos++)
587  {
588  if (mutt_socket_readchar(adata->conn, &c) != 1)
589  {
590  mutt_debug(LL_DEBUG1, "error during read, %ld bytes read\n", pos);
591  adata->status = IMAP_FATAL;
592 
593  mutt_buffer_dealloc(&buf);
594  return -1;
595  }
596 
597  if (r && (c != '\n'))
598  fputc('\r', fp);
599 
600  if (c == '\r')
601  {
602  r = true;
603  continue;
604  }
605  else
606  r = false;
607 
608  fputc(c, fp);
609 
610  if (pbar && !(pos % 1024))
611  mutt_progress_update(pbar, pos, -1);
613  mutt_buffer_addch(&buf, c);
614  }
615 
617  {
618  mutt_debug(IMAP_LOG_LTRL, "\n%s", buf.data);
619  mutt_buffer_dealloc(&buf);
620  }
621  return 0;
622 }
Unrecoverable error occurred.
Definition: private.h:97
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:209
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: private.h:176
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
#define IMAP_LOG_LTRL
Definition: private.h:50
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: private.h:172
+ 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 649 of file imap.c.

650 {
651  struct ImapAccountData *adata = imap_adata_get(m);
652  struct ImapMboxData *mdata = imap_mdata_get(m);
653  if (!adata || !mdata)
654  return;
655 
656  struct Email *e = NULL;
657 
658 #ifdef USE_HCACHE
659  imap_hcache_open(adata, mdata);
660 #endif
661 
662  for (int i = 0; i < m->msg_count; i++)
663  {
664  e = m->emails[i];
665  if (!e)
666  break;
667 
668  if (e->index == INT_MAX)
669  {
670  mutt_debug(LL_DEBUG2, "Expunging message UID %u\n", imap_edata_get(e)->uid);
671 
672  e->deleted = true;
673 
674  imap_cache_del(m, e);
675 #ifdef USE_HCACHE
676  imap_hcache_del(mdata, imap_edata_get(e)->uid);
677 #endif
678 
679  mutt_hash_int_delete(mdata->uid_hash, imap_edata_get(e)->uid, e);
680 
681  imap_edata_free((void **) &e->edata);
682  }
683  else
684  {
685  e->index = i;
686  /* NeoMutt has several places where it turns off e->active as a
687  * hack. For example to avoid FLAG updates, or to exclude from
688  * imap_exec_msgset.
689  *
690  * Unfortunately, when a reopen is allowed and the IMAP_EXPUNGE_PENDING
691  * flag becomes set (e.g. a flag update to a modified header),
692  * this function will be called by imap_cmd_finish().
693  *
694  * The ctx_update_tables() will free and remove these "inactive" headers,
695  * despite that an EXPUNGE was not received for them.
696  * This would result in memory leaks and segfaults due to dangling
697  * pointers in the msn_index and uid_hash.
698  *
699  * So this is another hack to work around the hacks. We don't want to
700  * remove the messages, so make sure active is on. */
701  e->active = true;
702  }
703  }
704 
705 #ifdef USE_HCACHE
706  imap_hcache_close(mdata);
707 #endif
708 
711 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
Update internal tables.
Definition: mailbox.h:174
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:534
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1732
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
Log at debug level 2.
Definition: logging.h:41
void imap_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free()
Definition: message.c:72
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct HashTable * uid_hash
Definition: private.h:237
Email list needs resorting.
Definition: mailbox.h:172
bool active
Message is not to be removed.
Definition: email.h:59
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void mutt_hash_int_delete(struct HashTable *table, unsigned int intkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:434
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
int index
The absolute (unsorted) message number.
Definition: email.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:174
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 1817 of file imap.c.

1818 {
1819  if (!adata)
1820  return -1;
1821 
1822  if (adata->state == IMAP_DISCONNECTED)
1823  {
1824  mutt_buffer_reset(&adata->cmdbuf); // purge outstanding queued commands
1825  imap_open_connection(adata);
1826  }
1827  if (adata->state == IMAP_CONNECTED)
1828  {
1829  if (imap_authenticate(adata) == IMAP_AUTH_SUCCESS)
1830  {
1831  adata->state = IMAP_AUTHENTICATED;
1832  FREE(&adata->capstr);
1833  if (adata->conn->ssf != 0)
1834  {
1835  mutt_debug(LL_DEBUG2, "Communication encrypted at %d bits\n",
1836  adata->conn->ssf);
1837  }
1838  }
1839  else
1841  }
1842  if (adata->state == IMAP_AUTHENTICATED)
1843  {
1844  /* capabilities may have changed */
1845  imap_exec(adata, "CAPABILITY", IMAP_CMD_PASS);
1846 
1847 #ifdef USE_ZLIB
1848  /* RFC4978 */
1849  if ((adata->capabilities & IMAP_CAP_COMPRESS) && C_ImapDeflate &&
1850  (imap_exec(adata, "COMPRESS DEFLATE", IMAP_CMD_PASS) == IMAP_EXEC_SUCCESS))
1851  {
1852  mutt_debug(LL_DEBUG2, "IMAP compression is enabled on connection to %s\n",
1853  adata->conn->account.host);
1854  mutt_zstrm_wrap_conn(adata->conn);
1855  }
1856 #endif
1857 
1858  /* enable RFC6855, if the server supports that */
1859  if (C_ImapRfc5161 && (adata->capabilities & IMAP_CAP_ENABLE))
1860  imap_exec(adata, "ENABLE UTF8=ACCEPT", IMAP_CMD_QUEUE);
1861 
1862  /* enable QRESYNC. Advertising QRESYNC also means CONDSTORE
1863  * is supported (even if not advertised), so flip that bit. */
1864  if (adata->capabilities & IMAP_CAP_QRESYNC)
1865  {
1866  adata->capabilities |= IMAP_CAP_CONDSTORE;
1868  imap_exec(adata, "ENABLE QRESYNC", IMAP_CMD_QUEUE);
1869  }
1870 
1871  /* get root delimiter, '/' as default */
1872  adata->delim = '/';
1873  imap_exec(adata, "LIST \"\" \"\"", IMAP_CMD_QUEUE);
1874 
1875  /* we may need the root delimiter before we open a mailbox */
1876  imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1877 
1878  /* select the mailbox that used to be open before disconnect */
1879  if (adata->mailbox)
1880  {
1881  imap_mbox_select(adata->mailbox);
1882  }
1883  }
1884 
1885  if (adata->state < IMAP_AUTHENTICATED)
1886  return -1;
1887 
1888  return 0;
1889 }
#define IMAP_CAP_COMPRESS
RFC4978: COMPRESS=DEFLATE.
Definition: private.h:140
void mutt_zstrm_wrap_conn(struct Connection *conn)
Wrap a compression layer around a Connection.
Definition: zstrm.c:288
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:37
int imap_open_connection(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:719
Connection is authenticated.
Definition: private.h:109
#define IMAP_CAP_ENABLE
RFC5161.
Definition: private.h:136
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
bool C_ImapRfc5161
Config: (imap) Use the IMAP ENABLE extension to select capabilities.
Definition: config.c:57
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
char * capstr
Definition: private.h:185
Imap command executed or queued successfully.
Definition: private.h:84
char host[128]
Server to login to.
Definition: connaccount.h:53
Disconnected from server.
Definition: private.h:107
Log at debug level 2.
Definition: logging.h:41
struct Buffer cmdbuf
Definition: private.h:204
bool C_ImapQresync
Config: (imap) Enable the QRESYNC extension.
Definition: config.c:56
Connected to server.
Definition: private.h:108
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:1242
void mutt_account_unsetpass(struct ConnAccount *cac)
Unset ConnAccount&#39;s password.
Definition: connaccount.c:141
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
Definition: private.h:74
ImapCapFlags capabilities
Definition: private.h:186
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1785
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: private.h:137
bool C_ImapDeflate
Config: (imap) Compress network traffic.
Definition: config.c:41
#define IMAP_CAP_QRESYNC
RFC7162.
Definition: private.h:138
#define FREE(x)
Definition: memory.h:40
int imap_authenticate(struct ImapAccountData *adata)
Authenticate to an IMAP server.
Definition: auth.c:82
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
Authentication successful.
Definition: auth.h:38
struct Connection * conn
Definition: private.h:172
+ 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 977 of file imap.c.

979 {
980  struct ImapAccountData *adata = imap_adata_get(m);
981  if (!adata || (adata->mailbox != m))
982  return -1;
983 
984  char flags[1024];
985  char *tags = NULL;
986  char uid[11];
987 
988  if (!compare_flags_for_copy(e))
989  {
990  if (e->deleted == imap_edata_get(e)->deleted)
991  e->changed = false;
992  return 0;
993  }
994 
995  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
996  mutt_buffer_reset(cmd);
997  mutt_buffer_addstr(cmd, "UID STORE ");
998  mutt_buffer_addstr(cmd, uid);
999 
1000  flags[0] = '\0';
1001 
1002  set_flag(m, MUTT_ACL_SEEN, e->read, "\\Seen ", flags, sizeof(flags));
1003  set_flag(m, MUTT_ACL_WRITE, e->old, "Old ", flags, sizeof(flags));
1004  set_flag(m, MUTT_ACL_WRITE, e->flagged, "\\Flagged ", flags, sizeof(flags));
1005  set_flag(m, MUTT_ACL_WRITE, e->replied, "\\Answered ", flags, sizeof(flags));
1006  set_flag(m, MUTT_ACL_DELETE, imap_edata_get(e)->deleted, "\\Deleted ", flags,
1007  sizeof(flags));
1008 
1009  if (m->rights & MUTT_ACL_WRITE)
1010  {
1011  /* restore system flags */
1012  if (imap_edata_get(e)->flags_system)
1013  mutt_str_cat(flags, sizeof(flags), imap_edata_get(e)->flags_system);
1014  /* set custom flags */
1015  tags = driver_tags_get_with_hidden(&e->tags);
1016  if (tags)
1017  {
1018  mutt_str_cat(flags, sizeof(flags), tags);
1019  FREE(&tags);
1020  }
1021  }
1022 
1024 
1025  /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
1026  * explicitly revoke all system flags (if we have permission) */
1027  if (*flags == '\0')
1028  {
1029  set_flag(m, MUTT_ACL_SEEN, 1, "\\Seen ", flags, sizeof(flags));
1030  set_flag(m, MUTT_ACL_WRITE, 1, "Old ", flags, sizeof(flags));
1031  set_flag(m, MUTT_ACL_WRITE, 1, "\\Flagged ", flags, sizeof(flags));
1032  set_flag(m, MUTT_ACL_WRITE, 1, "\\Answered ", flags, sizeof(flags));
1033  set_flag(m, MUTT_ACL_DELETE, !imap_edata_get(e)->deleted, "\\Deleted ",
1034  flags, sizeof(flags));
1035 
1036  /* erase custom flags */
1037  if ((m->rights & MUTT_ACL_WRITE) && imap_edata_get(e)->flags_remote)
1038  mutt_str_cat(flags, sizeof(flags), imap_edata_get(e)->flags_remote);
1039 
1041 
1042  mutt_buffer_addstr(cmd, " -FLAGS.SILENT (");
1043  }
1044  else
1045  mutt_buffer_addstr(cmd, " FLAGS.SILENT (");
1046 
1047  mutt_buffer_addstr(cmd, flags);
1048  mutt_buffer_addstr(cmd, ")");
1049 
1050  /* after all this it's still possible to have no flags, if you
1051  * have no ACL rights */
1052  if (*flags && (imap_exec(adata, cmd->data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS) &&
1053  err_continue && (*err_continue != MUTT_YES))
1054  {
1055  *err_continue = imap_continue("imap_sync_message: STORE failed", adata->buf);
1056  if (*err_continue != MUTT_YES)
1057  return -1;
1058  }
1059 
1060  /* server have now the updated flags */
1061  FREE(&imap_edata_get(e)->flags_remote);
1063 
1064  if (e->deleted == imap_edata_get(e)->deleted)
1065  e->changed = false;
1066 
1067  return 0;
1068 }
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:787
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
bool changed
Email has been edited.
Definition: email.h:48
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
Imap command executed or queued successfully.
Definition: private.h:84
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:74
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
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:1242
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:700
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
IMAP-specific Account data -.
Definition: private.h:170
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:277
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
bool flagged
Marked important?
Definition: email.h:43
char * buf
Definition: private.h:190
bool deleted
Email is deleted.
Definition: email.h:45
bool replied
Email has been replied to.
Definition: email.h:54
#define FREE(x)
Definition: memory.h:40
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:73
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
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:156
+ 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 850 of file imap.c.

851 {
852  if (STAILQ_EMPTY(flag_list))
853  return false;
854 
855  const size_t flaglen = mutt_str_len(flag);
856  struct ListNode *np = NULL;
857  STAILQ_FOREACH(np, flag_list, entries)
858  {
859  const size_t nplen = strlen(np->data);
860  if ((flaglen >= nplen) && ((flag[nplen] == '\0') || (flag[nplen] == ' ')) &&
861  mutt_istrn_equal(np->data, flag, nplen))
862  {
863  return true;
864  }
865 
866  if (mutt_str_equal(np->data, "\\*"))
867  return true;
868  }
869 
870  return false;
871 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
bool mutt_istrn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:621
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
char * data
String.
Definition: list.h:36
#define STAILQ_EMPTY(head)
Definition: queue.h:345
A List node for strings.
Definition: list.h:34
+ 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 129 of file util.c.

131 {
132  struct ConnAccount cac = { { 0 } };
133  struct ImapAccountData *tmp_adata = NULL;
134  char tmp[1024];
135 
136  if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
137  return -1;
138 
139  struct Account *np = NULL;
140  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
141  {
142  if (np->type != MUTT_IMAP)
143  continue;
144 
145  tmp_adata = np->adata;
146  if (!tmp_adata)
147  continue;
148  if (imap_account_match(&tmp_adata->conn->account, &cac))
149  {
150  *mdata = imap_mdata_new(tmp_adata, tmp);
151  *adata = tmp_adata;
152  return 0;
153  }
154  }
155  mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
156  return -1;
157 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
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:618
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
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:165
Login details for a remote server.
Definition: connaccount.h:51
IMAP-specific Account data -.
Definition: private.h:170
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
Log at debug level 3.
Definition: logging.h:42
struct Connection * conn
Definition: private.h:172
+ 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 82 of file auth.c.

83 {
84  int rc = IMAP_AUTH_FAILURE;
85 
87  {
88  mutt_debug(LL_DEBUG2, "Trying user-defined imap_authenticators\n");
89 
90  /* Try user-specified list of authentication methods */
91  struct ListNode *np = NULL;
93  {
94  mutt_debug(LL_DEBUG2, "Trying method %s\n", np->data);
95 
96  for (size_t i = 0; i < mutt_array_size(imap_authenticators); i++)
97  {
98  const struct ImapAuth *auth = &imap_authenticators[i];
99  if (!auth->method || mutt_istr_equal(auth->method, np->data))
100  {
101  rc = auth->authenticate(adata, np->data);
102  if (rc == IMAP_AUTH_SUCCESS)
103  {
104  return rc;
105  }
106  }
107  }
108  }
109  }
110  else
111  {
112  /* Fall back to default: any authenticator */
113  mutt_debug(LL_DEBUG2, "Trying pre-defined imap_authenticators\n");
114 
115  for (size_t i = 0; i < mutt_array_size(imap_authenticators); i++)
116  {
117  rc = imap_authenticators[i].authenticate(adata, NULL);
118  if (rc == IMAP_AUTH_SUCCESS)
119  return rc;
120  }
121  }
122 
123  mutt_error(_("No authenticators available or wrong credentials"));
124  return rc;
125 }
const char * method
Name of authentication method supported, NULL means variable.
Definition: auth.c:50
struct Slist * C_ImapAuthenticators
Config: (imap) List of allowed IMAP authentication methods.
Definition: config.c:37
#define _(a)
Definition: message.h:28
#define mutt_array_size(x)
Definition: memory.h:33
Log at debug level 2.
Definition: logging.h:41
struct ListHead head
Definition: slist.h:47
Authentication failed.
Definition: auth.h:39
static const struct ImapAuth imap_authenticators[]
Accepted authentication methods.
Definition: auth.c:57
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
size_t count
Definition: slist.h:48
enum ImapAuthRes(* authenticate)(struct ImapAccountData *adata, const char *method)
Authenticate an IMAP connection.
Definition: auth.c:48
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
IMAP authentication multiplexor.
Definition: auth.c:40
char * data
String.
Definition: list.h:36
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
A List node for strings.
Definition: list.h:34
Authentication successful.
Definition: auth.h:38
+ 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 1057 of file command.c.

1058 {
1059  return cmd_start(adata, cmdstr, IMAP_CMD_NO_FLAGS);
1060 }
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
static int cmd_start(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Start a new IMAP command.
Definition: command.c:199
+ 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 1071 of file command.c.

1072 {
1073  if (!adata)
1074  return -1;
1075 
1076  size_t len = 0;
1077  int c;
1078  int rc;
1079  int stillrunning = 0;
1080  struct ImapCommand *cmd = NULL;
1081 
1082  if (adata->status == IMAP_FATAL)
1083  {
1084  cmd_handle_fatal(adata);
1085  return IMAP_RES_BAD;
1086  }
1087 
1088  /* read into buffer, expanding buffer as necessary until we have a full
1089  * line */
1090  do
1091  {
1092  if (len == adata->blen)
1093  {
1094  mutt_mem_realloc(&adata->buf, adata->blen + IMAP_CMD_BUFSIZE);
1095  adata->blen = adata->blen + IMAP_CMD_BUFSIZE;
1096  mutt_debug(LL_DEBUG3, "grew buffer to %lu bytes\n", adata->blen);
1097  }
1098 
1099  /* back up over '\0' */
1100  if (len)
1101  len--;
1102  c = mutt_socket_readln_d(adata->buf + len, adata->blen - len, adata->conn, MUTT_SOCK_LOG_FULL);
1103  if (c <= 0)
1104  {
1105  mutt_debug(LL_DEBUG1, "Error reading server response\n");
1106  cmd_handle_fatal(adata);
1107  return IMAP_RES_BAD;
1108  }
1109 
1110  len += c;
1111  }
1112  /* if we've read all the way to the end of the buffer, we haven't read a
1113  * full line (mutt_socket_readln strips the \r, so we always have at least
1114  * one character free when we've read a full line) */
1115  while (len == adata->blen);
1116 
1117  /* don't let one large string make cmd->buf hog memory forever */
1118  if ((adata->blen > IMAP_CMD_BUFSIZE) && (len <= IMAP_CMD_BUFSIZE))
1119  {
1121  adata->blen = IMAP_CMD_BUFSIZE;
1122  mutt_debug(LL_DEBUG3, "shrank buffer to %lu bytes\n", adata->blen);
1123  }
1124 
1125  adata->lastread = mutt_date_epoch();
1126 
1127  /* handle untagged messages. The caller still gets its shot afterwards. */
1128  if ((mutt_str_startswith(adata->buf, "* ") ||
1129  mutt_str_startswith(imap_next_word(adata->buf), "OK [")) &&
1130  cmd_handle_untagged(adata))
1131  {
1132  return IMAP_RES_BAD;
1133  }
1134 
1135  /* server demands a continuation response from us */
1136  if (adata->buf[0] == '+')
1137  return IMAP_RES_RESPOND;
1138 
1139  /* Look for tagged command completions.
1140  *
1141  * Some response handlers can end up recursively calling
1142  * imap_cmd_step() and end up handling all tagged command
1143  * completions.
1144  * (e.g. FETCH->set_flag->set_header_color->~h pattern match.)
1145  *
1146  * Other callers don't even create an adata->cmds entry.
1147  *
1148  * For both these cases, we default to returning OK */
1149  rc = IMAP_RES_OK;
1150  c = adata->lastcmd;
1151  do
1152  {
1153  cmd = &adata->cmds[c];
1154  if (cmd->state == IMAP_RES_NEW)
1155  {
1156  if (mutt_str_startswith(adata->buf, cmd->seq))
1157  {
1158  if (!stillrunning)
1159  {
1160  /* first command in queue has finished - move queue pointer up */
1161  adata->lastcmd = (adata->lastcmd + 1) % adata->cmdslots;
1162  }
1163  cmd->state = cmd_status(adata->buf);
1164  rc = cmd->state;
1165  if (cmd->state == IMAP_RES_NO || cmd->state == IMAP_RES_BAD)
1166  {
1167  mutt_message(_("IMAP command failed: %s"), adata->buf);
1168  }
1169  }
1170  else
1171  stillrunning++;
1172  }
1173 
1174  c = (c + 1) % adata->cmdslots;
1175  } while (c != adata->nextcmd);
1176 
1177  if (stillrunning)
1178  rc = IMAP_RES_CONTINUE;
1179  else
1180  {
1181  mutt_debug(LL_DEBUG3, "IMAP queue drained\n");
1182  imap_cmd_finish(adata);
1183  }
1184 
1185  return rc;
1186 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
struct ImapCommand * cmds
Definition: private.h:200
#define IMAP_RES_RESPOND
+
Definition: private.h:58
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
#define mutt_message(...)
Definition: logging.h:83
#define IMAP_RES_NEW
ImapCommand.state additions.
Definition: private.h:59
Unrecoverable error occurred.
Definition: private.h:97
#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:163
size_t blen
Definition: private.h:191
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
IMAP command structure.
Definition: private.h:159
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: private.h:176
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1306
#define IMAP_CMD_BUFSIZE
Definition: command.c:56
char seq[SEQ_LEN+1]
Command tag, e.g. &#39;a0001&#39;.
Definition: private.h:161
#define IMAP_RES_NO
<tag> NO ...
Definition: private.h:54
time_t lastread
last time we read a command for the server
Definition: private.h:189
Log at debug level 1.
Definition: logging.h:40
int state
Command state, e.g. IMAP_RES_NEW.
Definition: private.h:162
char * buf
Definition: private.h:190
static int cmd_handle_untagged(struct ImapAccountData *adata)
fallback parser for otherwise unhandled messages
Definition: command.c:981
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:245
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
Log at debug level 3.
Definition: logging.h:42
struct Connection * conn
Definition: private.h:172
#define IMAP_RES_BAD
<tag> BAD ...
Definition: private.h:55
static int cmd_status(const char *s)
parse response line for tagged OK/NO/BAD
Definition: command.c:235
+ 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 1306 of file command.c.

1307 {
1308  if (!adata)
1309  return;
1310 
1311  if (adata->status == IMAP_FATAL)
1312  {
1313  adata->closing = false;
1314  cmd_handle_fatal(adata);
1315  return;
1316  }
1317 
1318  if (!(adata->state >= IMAP_SELECTED) || (adata->mailbox && adata->closing))
1319  {
1320  adata->closing = false;
1321  return;
1322  }
1323 
1324  adata->closing = false;
1325 
1326  struct ImapMboxData *mdata = imap_mdata_get(adata->mailbox);
1327 
1328  if (mdata && mdata->reopen & IMAP_REOPEN_ALLOW)
1329  {
1330  // First remove expunged emails from the msn_index
1331  if (mdata->reopen & IMAP_EXPUNGE_PENDING)
1332  {
1333  mutt_debug(LL_DEBUG2, "Expunging mailbox\n");
1334  imap_expunge_mailbox(adata->mailbox);
1335  /* Detect whether we've gotten unexpected EXPUNGE messages */
1336  if (!(mdata->reopen & IMAP_EXPUNGE_EXPECTED))
1339  }
1340 
1341  // Then add new emails to it
1342  if (mdata->reopen & IMAP_NEWMAIL_PENDING)
1343  {
1344  const size_t max_msn = imap_msn_highest(&mdata->msn);
1345  if (mdata->new_mail_count > max_msn)
1346  {
1347  if (!(mdata->reopen & IMAP_EXPUNGE_PENDING))
1349 
1350  mutt_debug(LL_DEBUG2, "Fetching new mails from %d to %d\n", max_msn + 1,
1351  mdata->new_mail_count);
1352  imap_read_headers(adata->mailbox, max_msn + 1, mdata->new_mail_count, false);
1353  }
1354  }
1355 
1356  // And to finish inform about MUTT_REOPEN if needed
1357  if (mdata->reopen & IMAP_EXPUNGE_PENDING && !(mdata->reopen & IMAP_EXPUNGE_EXPECTED))
1359 
1360  if (mdata->reopen & IMAP_EXPUNGE_PENDING)
1362  }
1363 
1364  adata->status = 0;
1365 }
Unrecoverable error occurred.
Definition: private.h:97
void imap_expunge_mailbox(struct Mailbox *m)
Purge messages from the server.
Definition: imap.c:649
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
Definition: command.c:163
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: private.h:225
Log at debug level 2.
Definition: logging.h:41
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:1243
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: private.h:224
Mailbox is selected.
Definition: private.h:110
void * mdata
Driver specific data.
Definition: mailbox.h:136
bool closing
If true, we are waiting for CLOSE completion.
Definition: private.h:174
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: private.h:176
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: private.h:67
size_t imap_msn_highest(const struct MSN *msn)
Return the highest MSN in use.
Definition: msn.c:69
IMAP-specific Mailbox data -.
Definition: private.h:217
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:69
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: private.h:68
+ 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 1194 of file command.c.

1195 {
1196  return cmd_status(s) == IMAP_RES_OK;
1197 }
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
static int cmd_status(const char *s)
parse response line for tagged OK/NO/BAD
Definition: command.c:235
+ 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 1205 of file command.c.

1206 {
1207  static const char *notrailer = "";
1208  const char *s = adata->buf;
1209 
1210  if (!s)
1211  {
1212  mutt_debug(LL_DEBUG2, "not a tagged response\n");
1213  return notrailer;
1214  }
1215 
1216  s = imap_next_word((char *) s);
1217  if (!s || (!mutt_istr_startswith(s, "OK") && !mutt_istr_startswith(s, "NO") &&
1218  !mutt_istr_startswith(s, "BAD")))
1219  {
1220  mutt_debug(LL_DEBUG2, "not a command completion: %s\n", adata->buf);
1221  return notrailer;
1222  }
1223 
1224  s = imap_next_word((char *) s);
1225  if (!s)
1226  return notrailer;
1227 
1228  return s;
1229 }
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
Log at debug level 2.
Definition: logging.h:41
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
char * buf
Definition: private.h:190
#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 1242 of file command.c.

1243 {
1244  int rc;
1245 
1246  if (flags & IMAP_CMD_SINGLE)
1247  {
1248  // Process any existing commands
1249  if (adata->nextcmd != adata->lastcmd)
1250  imap_exec(adata, NULL, IMAP_CMD_POLL);
1251  }
1252 
1253  rc = cmd_start(adata, cmdstr, flags);
1254  if (rc < 0)
1255  {
1256  cmd_handle_fatal(adata);
1257  return IMAP_EXEC_FATAL;
1258  }
1259 
1260  if (flags & IMAP_CMD_QUEUE)
1261  return IMAP_EXEC_SUCCESS;
1262 
1263  if ((flags & IMAP_CMD_POLL) && (C_ImapPollTimeout > 0) &&
1264  ((mutt_socket_poll(adata->conn, C_ImapPollTimeout)) == 0))
1265  {
1266  mutt_error(_("Connection to %s timed out"), adata->conn->account.host);
1267  cmd_handle_fatal(adata);
1268  return IMAP_EXEC_FATAL;
1269  }
1270 
1271  /* Allow interruptions, particularly useful if there are network problems. */
1273  do
1274  {
1275  rc = imap_cmd_step(adata);
1276  // The queue is empty, so the single command has been processed
1277  if ((flags & IMAP_CMD_SINGLE) && (adata->nextcmd == adata->lastcmd))
1278  break;
1279  } while (rc == IMAP_RES_CONTINUE);
1280  mutt_sig_allow_interrupt(false);
1281 
1282  if (rc == IMAP_RES_NO)
1283  return IMAP_EXEC_ERROR;
1284  if (rc != IMAP_RES_OK)
1285  {
1286  if (adata->status != IMAP_FATAL)
1287  return IMAP_EXEC_ERROR;
1288 
1289  mutt_debug(LL_DEBUG1, "command failed: %s\n", adata->buf);
1290  return IMAP_EXEC_FATAL;
1291  }
1292 
1293  return IMAP_EXEC_SUCCESS;
1294 }
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
Imap connection failure.
Definition: private.h:86
Unrecoverable error occurred.
Definition: private.h:97
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:76
#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:163
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
Imap command executed or queued successfully.
Definition: private.h:84
char host[128]
Server to login to.
Definition: connaccount.h:53
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: config.c:55
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:1242
struct ListHead flags
Definition: private.h:228
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: private.h:176
#define IMAP_RES_NO
<tag> NO ...
Definition: private.h:54
Imap command failure.
Definition: private.h:85
Log at debug level 1.
Definition: logging.h:40
char * buf
Definition: private.h:190
#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:199
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
#define IMAP_CMD_SINGLE
Run a single command.
Definition: private.h:77
struct Connection * conn
Definition: private.h:172
+ 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 1373 of file command.c.

1374 {
1375  int rc;
1376 
1377  if (cmd_start(adata, "IDLE", IMAP_CMD_POLL) < 0)
1378  {
1379  cmd_handle_fatal(adata);
1380  return -1;
1381  }
1382 
1383  if ((C_ImapPollTimeout > 0) && ((mutt_socket_poll(adata->conn, C_ImapPollTimeout)) == 0))
1384  {
1385  mutt_error(_("Connection to %s timed out"), adata->conn->account.host);
1386  cmd_handle_fatal(adata);
1387  return -1;
1388  }
1389 
1390  do
1391  {
1392  rc = imap_cmd_step(adata);
1393  } while (rc == IMAP_RES_CONTINUE);
1394 
1395  if (rc == IMAP_RES_RESPOND)
1396  {
1397  /* successfully entered IDLE state */
1398  adata->state = IMAP_IDLE;
1399  /* queue automatic exit when next command is issued */
1400  mutt_buffer_addstr(&adata->cmdbuf, "DONE\r\n");
1401  rc = IMAP_RES_OK;
1402  }
1403  if (rc != IMAP_RES_OK)
1404  {
1405  mutt_debug(LL_DEBUG1, "error starting IDLE\n");
1406  return -1;
1407  }
1408 
1409  return 0;
1410 }
#define IMAP_RES_RESPOND
+
Definition: private.h:58
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:76
#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:163
char host[128]
Server to login to.
Definition: connaccount.h:53
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
struct Buffer cmdbuf
Definition: private.h:204
short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: config.c:55
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
Connection is idle.
Definition: private.h:113
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:199
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
struct Connection * conn
Definition: private.h:172
+ 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 the private Email data - Implements Email::edata_free()

Definition at line 72 of file message.c.

73 {
74  if (!ptr || !*ptr)
75  return;
76 
77  struct ImapEmailData *edata = *ptr;
78  /* this should be safe even if the list wasn't used */
79  FREE(&edata->flags_system);
80  FREE(&edata->flags_remote);
81  FREE(ptr);
82 }
char * flags_remote
Definition: message.h:48
char * flags_system
Definition: message.h:47
void * edata
Driver-specific data.
Definition: email.h:111
#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 98 of file message.c.

99 {
100  if (!e)
101  return NULL;
102  return e->edata;
103 }
void * edata
Driver-specific data.
Definition: email.h:111
+ 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 1243 of file message.c.

1245 {
1246  int oldmsgcount;
1247  unsigned int maxuid = 0;
1248  int retval = -1;
1249  bool evalhc = false;
1250 
1251 #ifdef USE_HCACHE
1252  void *uidvalidity = NULL;
1253  void *puid_next = NULL;
1254  unsigned int uid_next = 0;
1255  bool has_condstore = false;
1256  bool has_qresync = false;
1257  bool eval_condstore = false;
1258  bool eval_qresync = false;
1259  unsigned long long *pmodseq = NULL;
1260  unsigned long long hc_modseq = 0;
1261  char *uid_seqset = NULL;
1262 #endif /* USE_HCACHE */
1263 
1264  struct ImapAccountData *adata = imap_adata_get(m);
1265  struct ImapMboxData *mdata = imap_mdata_get(m);
1266  if (!adata || (adata->mailbox != m))
1267  return -1;
1268 
1269  /* make sure context has room to hold the mailbox */
1270  while (msn_end > m->email_max)
1271  mx_alloc_memory(m);
1272  imap_msn_reserve(&mdata->msn, msn_end);
1273  imap_alloc_uid_hash(adata, msn_end);
1274 
1275  oldmsgcount = m->msg_count;
1277  mdata->new_mail_count = 0;
1278 
1279 #ifdef USE_HCACHE
1280  imap_hcache_open(adata, mdata);
1281 
1282  if (mdata->hcache && initial_download)
1283  {
1284  size_t dlen = 0;
1285  uidvalidity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12, &dlen);
1286  puid_next = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8, &dlen);
1287  if (puid_next)
1288  {
1289  uid_next = *(unsigned int *) puid_next;
1290  mutt_hcache_free_raw(mdata->hcache, &puid_next);
1291  }
1292 
1293  if (mdata->modseq)
1294  {
1296  has_condstore = true;
1297 
1298  /* If IMAP_CAP_QRESYNC and ImapQResync then NeoMutt sends ENABLE QRESYNC.
1299  * If we receive an ENABLED response back, then adata->qresync is set. */
1300  if (adata->qresync)
1301  has_qresync = true;
1302  }
1303 
1304  if (uidvalidity && uid_next && (*(uint32_t *) uidvalidity == mdata->uidvalidity))
1305  {
1306  size_t dlen2 = 0;
1307  evalhc = true;
1308  pmodseq = mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7, &dlen2);
1309  if (pmodseq)
1310  {
1311  hc_modseq = *pmodseq;
1312  mutt_hcache_free_raw(mdata->hcache, (void **) &pmodseq);
1313  }
1314  if (hc_modseq)
1315  {
1316  if (has_qresync)
1317  {
1318  uid_seqset = imap_hcache_get_uid_seqset(mdata);
1319  if (uid_seqset)
1320  eval_qresync = true;
1321  }
1322 
1323  if (!eval_qresync && has_condstore)
1324  eval_condstore = true;
1325  }
1326  }
1327  mutt_hcache_free_raw(mdata->hcache, &uidvalidity);
1328  }
1329  if (evalhc)
1330  {
1331  if (eval_qresync)
1332  {
1333  if (read_headers_qresync_eval_cache(adata, uid_seqset) < 0)
1334  goto bail;
1335  }
1336  else
1337  {
1338  if (read_headers_normal_eval_cache(adata, msn_end, uid_next, has_condstore || has_qresync,
1339  eval_condstore) < 0)
1340  goto bail;
1341  }
1342 
1343  if ((eval_condstore || eval_qresync) && (hc_modseq != mdata->modseq))
1344  {
1345  if (read_headers_condstore_qresync_updates(adata, msn_end, uid_next,
1346  hc_modseq, eval_qresync) < 0)
1347  {
1348  goto bail;
1349  }
1350  }
1351 
1352  /* Look for the first empty MSN and start there */
1353  while (msn_begin <= msn_end)
1354  {
1355  if (!imap_msn_get(&mdata->msn, msn_begin - 1))
1356  break;
1357  msn_begin++;
1358  }
1359  }
1360 #endif /* USE_HCACHE */
1361 
1362  if (read_headers_fetch_new(m, msn_begin, msn_end, evalhc, &maxuid, initial_download) < 0)
1363  goto bail;
1364 
1365  if (maxuid && (mdata->uid_next < maxuid + 1))
1366  mdata->uid_next = maxuid + 1;
1367 
1368 #ifdef USE_HCACHE
1369  mutt_hcache_store_raw(mdata->hcache, "/UIDVALIDITY", 12, &mdata->uidvalidity,
1370  sizeof(mdata->uidvalidity));
1371  if (maxuid && (mdata->uid_next < maxuid + 1))
1372  {
1373  mutt_debug(LL_DEBUG2, "Overriding UIDNEXT: %u -> %u\n", mdata->uid_next, maxuid + 1);
1374  mdata->uid_next = maxuid + 1;
1375  }
1376  if (mdata->uid_next > 1)
1377  {
1378  mutt_hcache_store_raw(mdata->hcache, "/UIDNEXT", 8, &mdata->uid_next,
1379  sizeof(mdata->uid_next));
1380  }
1381 
1382  /* We currently only sync CONDSTORE and QRESYNC on the initial download.
1383  * To do it more often, we'll need to deal with flag updates combined with
1384  * unsync'ed local flag changes. We'll also need to properly sync flags to
1385  * the header cache on close. I'm not sure it's worth the added complexity. */
1386  if (initial_download)
1387  {
1388  if (has_condstore || has_qresync)
1389  {
1390  mutt_hcache_store_raw(mdata->hcache, "/MODSEQ", 7, &mdata->modseq,
1391  sizeof(mdata->modseq));
1392  }
1393  else
1394  mutt_hcache_delete_record(mdata->hcache, "/MODSEQ", 7);
1395 
1396  if (has_qresync)
1398  else
1400  }
1401 #endif /* USE_HCACHE */
1402 
1403  if (m->msg_count > oldmsgcount)
1404  {
1405  /* TODO: it's not clear to me why we are calling mx_alloc_memory
1406  * yet again. */
1407  mx_alloc_memory(m);
1408  }
1409 
1410  mdata->reopen |= IMAP_REOPEN_ALLOW;
1411 
1412  retval = msn_end;
1413 
1414 bail:
1415 #ifdef USE_HCACHE
1416  imap_hcache_close(mdata);
1417  FREE(&uid_seqset);
1418 #endif /* USE_HCACHE */
1419 
1420  return retval;
1421 }
int msg_count
Total number of messages.
Definition: mailbox.h:91
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:689
uint32_t uidvalidity
Definition: private.h:229
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
int imap_hcache_store_uid_seqset(struct ImapMboxData *mdata)
Store a UID Sequence Set in the header cache.
Definition: util.c:551
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1232
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
struct HeaderCache * hcache
Definition: private.h:241
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:512
char * imap_hcache_get_uid_seqset(struct ImapMboxData *mdata)
Get a UID Sequence Set from the header cache.
Definition: util.c:587
bool C_ImapCondstore
Config: (imap) Enable the CONDSTORE extension.
Definition: config.c:39
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: private.h:225
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
Log at debug level 2.
Definition: logging.h:41
struct Email * imap_msn_get(const struct MSN *msn, size_t idx)
Return the Email associated with an msn.
Definition: msn.c:80
static void imap_alloc_uid_hash(struct ImapAccountData *adata, unsigned int msn_count)
Create a Hash Table for the UIDs.
Definition: message.c:540
void * mdata
Driver specific data.
Definition: mailbox.h:136
unsigned long long modseq
Definition: private.h:231
void imap_msn_reserve(struct MSN *msn, size_t num)
Create / reallocate the cache.
Definition: msn.c:41
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:602
bool qresync
true, if QRESYNC is successfully ENABLE&#39;d
Definition: private.h:194
ImapCapFlags capabilities
Definition: private.h:186
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:997
static int read_headers_qresync_eval_cache(struct ImapAccountData *adata, char *uid_seqset)
Retrieve data from the header cache.
Definition: message.c:831
IMAP-specific Account data -.
Definition: private.h:170
unsigned int uid_next
Definition: private.h:230
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:900
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: private.h:137
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:69
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:582
int imap_hcache_clear_uid_seqset(struct ImapMboxData *mdata)
Delete a UID Sequence Set from the header cache.
Definition: util.c:573
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:494
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
+ 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 1783 of file message.c.

1784 {
1785  struct ImapAccountData *adata = imap_adata_get(m);
1786  if (!adata || (adata->mailbox != m))
1787  return NULL;
1788 
1789  struct ImapHeader newh = { 0 };
1790  struct ImapEmailData old_edata = { 0 };
1791  int local_changes = e->changed;
1792 
1793  struct ImapEmailData *edata = e->edata;
1794  newh.edata = edata;
1795 
1796  mutt_debug(LL_DEBUG2, "parsing FLAGS\n");
1797  s = msg_parse_flags(&newh, s);
1798  if (!s)
1799  return NULL;
1800 
1801  /* Update tags system */
1802  /* We take a copy of the tags so we can split the string */
1803  char *tags_copy = mutt_str_dup(edata->flags_remote);
1804  driver_tags_replace(&e->tags, tags_copy);
1805  FREE(&tags_copy);
1806 
1807  /* YAUH (yet another ugly hack): temporarily set context to
1808  * read-write even if it's read-only, so *server* updates of
1809  * flags can be processed by mutt_set_flag. mailbox->changed must
1810  * be restored afterwards */
1811  bool readonly = m->readonly;
1812  m->readonly = false;
1813 
1814  /* This is redundant with the following two checks. Removing:
1815  * mutt_set_flag (m, e, MUTT_NEW, !(edata->read || edata->old)); */
1816  set_changed_flag(m, e, local_changes, server_changes, MUTT_OLD, old_edata.old,
1817  edata->old, e->old);
1818  set_changed_flag(m, e, local_changes, server_changes, MUTT_READ,
1819  old_edata.read, edata->read, e->read);
1820  set_changed_flag(m, e, local_changes, server_changes, MUTT_DELETE,
1821  old_edata.deleted, edata->deleted, e->deleted);
1822  set_changed_flag(m, e, local_changes, server_changes, MUTT_FLAG,
1823  old_edata.flagged, edata->flagged, e->flagged);
1824  set_changed_flag(m, e, local_changes, server_changes, MUTT_REPLIED,
1825  old_edata.replied, edata->replied, e->replied);
1826 
1827  /* this message is now definitively *not* changed (mutt_set_flag
1828  * marks things changed as a side-effect) */
1829  if (local_changes == 0)
1830  e->changed = false;
1831  m->changed &= !readonly;
1832  m->readonly = readonly;
1833 
1834  return s;
1835 }
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:649
Flagged messages.
Definition: mutt.h:102
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
bool changed
Email has been edited.
Definition: email.h:48
Messages that have been replied to.
Definition: mutt.h:95
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:119
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
char * flags_remote
Definition: message.h:48
Old messages.
Definition: mutt.h:94
Messages to be deleted.
Definition: mutt.h:98
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:96
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
bool flagged
Marked important?
Definition: email.h:43
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
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:114
#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:222
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 1732 of file message.c.

1733 {
1734  struct ImapAccountData *adata = imap_adata_get(m);
1735  struct ImapMboxData *mdata = imap_mdata_get(m);
1736 
1737  if (!e || !adata || (adata->mailbox != m))
1738  return -1;
1739 
1740  mdata->bcache = msg_cache_open(m);
1741  char id[64];
1742  snprintf(id, sizeof(id), "%u-%u", mdata->uidvalidity, imap_edata_get(e)->uid);
1743  return mutt_bcache_del(mdata->bcache, id);
1744 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
uint32_t uidvalidity
Definition: private.h:229
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
struct BodyCache * bcache
Definition: private.h:239
void * mdata
Driver specific data.
Definition: mailbox.h:136
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:111
int mutt_bcache_del(struct BodyCache *bcache, const char *id)
Delete a file from the Body Cache.
Definition: bcache.c:256
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
+ 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 1751 of file message.c.

1752 {
1753  struct ImapAccountData *adata = imap_adata_get(m);
1754  struct ImapMboxData *mdata = imap_mdata_get(m);
1755 
1756  if (!adata || (adata->mailbox != m))
1757  return -1;
1758 
1759  mdata->bcache = msg_cache_open(m);
1760  mutt_bcache_list(mdata->bcache, msg_cache_clean_cb, mdata);
1761 
1762  return 0;
1763 }
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:199
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
int mutt_bcache_list(struct BodyCache *bcache, bcache_list_t want_id, void *data)
Find matching entries in the Body Cache.
Definition: bcache.c:321
struct BodyCache * bcache
Definition: private.h:239
void * mdata
Driver specific data.
Definition: mailbox.h:136
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:111
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
+ 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 1430 of file message.c.

1431 {
1432  if (!m || !msg)
1433  return -1;
1434 
1435  FILE *fp = NULL;
1436  char buf[1024 * 2];
1437  char internaldate[IMAP_DATELEN];
1438  char imap_flags[128];
1439  size_t len;
1440  struct Progress progress;
1441  size_t sent;
1442  int c, last;
1443  int rc;
1444 
1445  struct ImapAccountData *adata = imap_adata_get(m);
1446  struct ImapMboxData *mdata = imap_mdata_get(m);
1447 
1448  fp = fopen(msg->path, "r");
1449  if (!fp)
1450  {
1451  mutt_perror(msg->path);
1452  goto fail;
1453  }
1454 
1455  /* currently we set the \Seen flag on all messages, but probably we
1456  * should scan the message Status header for flag info. Since we're
1457  * already rereading the whole file for length it isn't any more
1458  * expensive (it'd be nice if we had the file size passed in already
1459  * by the code that writes the file, but that's a lot of changes.
1460  * Ideally we'd have an Email structure with flag info here... */
1461  for (last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
1462  {
1463  if ((c == '\n') && (last != '\r'))
1464  len++;
1465 
1466  len++;
1467  }
1468  rewind(fp);
1469 
1470  if (m->verbose)
1471  mutt_progress_init(&progress, _("Uploading message..."), MUTT_PROGRESS_NET, len);
1472 
1473  mutt_date_make_imap(internaldate, sizeof(internaldate), msg->received);
1474 
1475  imap_flags[0] = '\0';
1476  imap_flags[1] = '\0';
1477 
1478  if (msg->flags.read)
1479  mutt_str_cat(imap_flags, sizeof(imap_flags), " \\Seen");
1480  if (msg->flags.replied)
1481  mutt_str_cat(imap_flags, sizeof(imap_flags), " \\Answered");
1482  if (msg->flags.flagged)
1483  mutt_str_cat(imap_flags, sizeof(imap_flags), " \\Flagged");
1484  if (msg->flags.draft)
1485  mutt_str_cat(imap_flags, sizeof(imap_flags), " \\Draft");
1486 
1487  snprintf(buf, sizeof(buf), "APPEND %s (%s) \"%s\" {%lu}", mdata->munge_name,
1488  imap_flags + 1, internaldate, (unsigned long) len);
1489 
1490  imap_cmd_start(adata, buf);
1491 
1492  do
1493  {
1494  rc = imap_cmd_step(adata);
1495  } while (rc == IMAP_RES_CONTINUE);
1496 
1497  if (rc != IMAP_RES_RESPOND)
1498  goto cmd_step_fail;
1499 
1500  for (last = EOF, sent = len = 0; (c = fgetc(fp)) != EOF; last = c)
1501  {
1502  if ((c == '\n') && (last != '\r'))
1503  buf[len++] = '\r';
1504 
1505  buf[len++] = c;
1506 
1507  if (len > sizeof(buf) - 3)
1508  {
1509  sent += len;
1510  if (flush_buffer(buf, &len, adata->conn) < 0)
1511  goto fail;
1512  if (m->verbose)
1513  mutt_progress_update(&progress, sent, -1);
1514  }
1515  }
1516 
1517  if (len)
1518  if (flush_buffer(buf, &len, adata->conn) < 0)
1519  goto fail;
1520 
1521  if (mutt_socket_send(adata->conn, "\r\n") < 0)
1522  goto fail;
1523  mutt_file_fclose(&fp);
1524 
1525  do
1526  {
1527  rc = imap_cmd_step(adata);
1528  } while (rc == IMAP_RES_CONTINUE);
1529 
1530  if (rc != IMAP_RES_OK)
1531  goto cmd_step_fail;
1532 
1533  return 0;
1534 
1535 cmd_step_fail:
1536  mutt_debug(LL_DEBUG1, "command failed: %s\n", adata->buf);
1537  if (rc != IMAP_RES_BAD)
1538  {
1539  char *pc = imap_next_word(adata->buf); /* skip sequence number or token */
1540  pc = imap_next_word(pc); /* skip response code */
1541  if (*pc != '\0')
1542  mutt_error("%s", pc);
1543  }
1544 
1545 fail:
1546  mutt_file_fclose(&fp);
1547  return -1;
1548 }
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:44
#define IMAP_RES_RESPOND
+
Definition: private.h:58
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
#define mutt_perror(...)
Definition: logging.h:85
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
bool replied
Definition: mx.h:92
#define _(a)
Definition: message.h:28
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
A progress bar.
Definition: progress.h:50
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
static int flush_buffer(char *buf, size_t *len, struct Connection *conn)
Write data to a connection.
Definition: message.c:500
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:153
void * mdata
Driver specific data.
Definition: mailbox.h:136
bool flagged
Definition: mx.h:91
struct Message::@0 flags
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
bool verbose
Display status messages?
Definition: mailbox.h:118
bool draft
Definition: mx.h:93
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
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
IMAP-specific Account data -.
Definition: private.h:170
Log at debug level 1.
Definition: logging.h:40
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
#define mutt_error(...)
Definition: logging.h:84
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:546
time_t received
the time at which this message was received
Definition: mx.h:95
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_DATELEN
Definition: private.h:90
bool read
Definition: mx.h:90
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
char * munge_name
Munged version of the mailbox name.
Definition: private.h:220
char * path
path to temp file
Definition: mx.h:85
struct Connection * conn
Definition: private.h:172
#define IMAP_RES_BAD
<tag> BAD ...
Definition: private.h:55
+ 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 1840 of file message.c.

1841 {
1842  if (!m || !msg)
1843  return -1;
1844 
1845  struct Envelope *newenv = NULL;
1846  char buf[1024];
1847  char *pc = NULL;
1848  unsigned int bytes;
1849  struct Progress progress;
1850  unsigned int uid;
1851  bool retried = false;
1852  bool read;
1853  int rc;
1854 
1855  /* Sam's weird courier server returns an OK response even when FETCH
1856  * fails. Thanks Sam. */
1857  bool fetched = false;
1858 
1859  struct ImapAccountData *adata = imap_adata_get(m);
1860 
1861  if (!adata || (adata->mailbox != m))
1862  return -1;
1863 
1864  struct Email *e = m->emails[msgno];
1865  if (!e)
1866  return -1;
1867 
1868  msg->fp = msg_cache_get(m, e);
1869  if (msg->fp)
1870  {
1871  if (imap_edata_get(e)->parsed)
1872  return 0;
1873  goto parsemsg;
1874  }
1875 
1876  /* This function is called in a few places after endwin()
1877  * e.g. mutt_pipe_message(). */
1878  bool output_progress = !isendwin() && m->verbose;
1879  if (output_progress)
1880  mutt_message(_("Fetching message..."));
1881 
1882  msg->fp = msg_cache_put(m, e);
1883  if (!msg->fp)
1884  {
1885  struct Buffer *path = mutt_buffer_pool_get();
1886  mutt_buffer_mktemp(path);
1887  msg->fp = mutt_file_fopen(mutt_b2s(path), "w+");
1888  unlink(mutt_b2s(path));
1889  mutt_buffer_pool_release(&path);
1890 
1891  if (!msg->fp)
1892  return -1;
1893  }
1894 
1895  /* mark this header as currently inactive so the command handler won't
1896  * also try to update it. HACK until all this code can be moved into the
1897  * command handler */
1898  e->active = false;
1899 
1900  snprintf(buf, sizeof(buf), "UID FETCH %u %s", imap_edata_get(e)->uid,
1901  ((adata->capabilities & IMAP_CAP_IMAP4REV1) ?
1902  (C_ImapPeek ? "BODY.PEEK[]" : "BODY[]") :
1903  "RFC822"));
1904 
1905  imap_cmd_start(adata, buf);
1906  do
1907  {
1908  rc = imap_cmd_step(adata);
1909  if (rc != IMAP_RES_CONTINUE)
1910  break;
1911 
1912  pc = adata->buf;
1913  pc = imap_next_word(pc);
1914  pc = imap_next_word(pc);
1915 
1916  if (mutt_istr_startswith(pc, "FETCH"))
1917  {
1918  while (*pc)
1919  {
1920  pc = imap_next_word(pc);
1921  if (pc[0] == '(')
1922  pc++;
1923  if (mutt_istr_startswith(pc, "UID"))
1924  {
1925  pc = imap_next_word(pc);
1926  if (mutt_str_atoui(pc, &uid) < 0)
1927  goto bail;
1928  if (uid != imap_edata_get(e)->uid)
1929  {
1930  mutt_error(_(
1931  "The message index is incorrect. Try reopening the mailbox."));
1932  }
1933  }
1934  else if (mutt_istr_startswith(pc, "RFC822") || mutt_istr_startswith(pc, "BODY[]"))
1935  {
1936  pc = imap_next_word(pc);
1937  if (imap_get_literal_count(pc, &bytes) < 0)
1938  {
1939  imap_error("imap_msg_open()", buf);
1940  goto bail;
1941  }
1942  if (output_progress)
1943  {
1944  mutt_progress_init(&progress, _("Fetching message..."), MUTT_PROGRESS_NET, bytes);
1945  }
1946  if (imap_read_literal(msg->fp, adata, bytes, output_progress ? &progress : NULL) < 0)
1947  {
1948  goto bail;
1949  }
1950  /* pick up trailing line */
1951  rc = imap_cmd_step(adata);
1952  if (rc != IMAP_RES_CONTINUE)
1953  goto bail;
1954  pc = adata->buf;
1955 
1956  fetched = true;
1957  }
1958  /* UW-IMAP will provide a FLAGS update here if the FETCH causes a
1959  * change (eg from \Unseen to \Seen).
1960  * Uncommitted changes in neomutt take precedence. If we decide to
1961  * incrementally update flags later, this won't stop us syncing */
1962  else if (!e->changed && mutt_istr_startswith(pc, "FLAGS"))
1963  {
1964  pc = imap_set_flags(m, e, pc, NULL);
1965  if (!pc)
1966  goto bail;
1967  }
1968  }
1969  }
1970  } while (rc == IMAP_RES_CONTINUE);
1971 
1972  /* see comment before command start. */
1973  e->active = true;
1974 
1975  fflush(msg->fp);
1976  if (ferror(msg->fp))
1977  goto bail;
1978 
1979  if (rc != IMAP_RES_OK)
1980  goto bail;
1981 
1982  if (!fetched || !imap_code(adata->buf))
1983  goto bail;
1984 
1985  msg_cache_commit(m, e);
1986 
1987 parsemsg:
1988  /* Update the header information. Previously, we only downloaded a
1989  * portion of the headers, those required for the main display. */
1990  rewind(msg->fp);
1991  /* It may be that the Status header indicates a message is read, but the
1992  * IMAP server doesn't know the message has been \Seen. So we capture
1993  * the server's notion of 'read' and if it differs from the message info
1994  * picked up in mutt_rfc822_read_header, we mark the message (and context
1995  * changed). Another possibility: ignore Status on IMAP? */
1996  read = e->read;
1997  newenv = mutt_rfc822_read_header(msg->fp, e, false, false);
1998  mutt_env_merge(e->env, &newenv);
1999 
2000  /* see above. We want the new status in e->read, so we unset it manually
2001  * and let mutt_set_flag set it correctly, updating context. */
2002  if (read != e->read)
2003  {
2004  e->read = read;
2005  mutt_set_flag(m, e, MUTT_NEW, read);
2006  }
2007 
2008  e->lines = 0;
2009  fgets(buf, sizeof(buf), msg->fp);
2010  while (!feof(msg->fp))
2011  {
2012  e->lines++;
2013  fgets(buf, sizeof(buf), msg->fp);
2014  }
2015 
2016  e->body->length = ftell(msg->fp) - e->body->offset;
2017 
2018  mutt_clear_error();
2019  rewind(msg->fp);
2020  imap_edata_get(e)->parsed = true;
2021 
2022  /* retry message parse if cached message is empty */
2023  if (!retried && ((e->lines == 0) || (e->body->length == 0)))
2024  {
2025  imap_cache_del(m, e);
2026  retried = true;
2027  goto parsemsg;
2028  }
2029 
2030  return 0;
2031 
2032 bail:
2033  e->active = true;
2034  mutt_file_fclose(&msg->fp);
2035  imap_cache_del(m, e);
2036  return -1;
2037 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:44
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
int lines
How many lines in the body of this message?
Definition: email.h:85
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:56
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
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
struct Body * body
List of MIME parts.
Definition: email.h:91
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
static FILE * msg_cache_put(struct Mailbox *m, struct Email *e)
Put an email into the message cache.
Definition: message.c:159
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1732
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:138
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
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:1057
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:574
A progress bar.
Definition: progress.h:50
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
bool read
Email is read.
Definition: email.h:51
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:90
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
#define mutt_b2s(buf)
Definition: buffer.h:41
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: private.h:124
bool active
Message is not to be removed.
Definition: email.h:59
bool C_ImapPeek
Config: (imap) Don&#39;t mark messages as read when fetching them from the server.
Definition: config.c:53
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
New messages.
Definition: mutt.h:93
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
bool verbose
Display status messages?
Definition: mailbox.h:118
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
ImapCapFlags capabilities
Definition: private.h:186
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
int imap_get_literal_count(const char *buf, unsigned int *bytes)
write number of bytes in an IMAP literal into bytes
Definition: util.c:879
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
char * buf
Definition: private.h:190
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mx.h:84
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:1783
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1111
bool parsed
Definition: message.h:42
bool imap_code(const char *s)
Was the command successful.
Definition: command.c:1194
The header of an Email.
Definition: envelope.h:54
int msgno
Number displayed to the user.
Definition: email.h:87
static int msg_cache_commit(struct Mailbox *m, struct Email *e)
Add to the message cache.
Definition: message.c:180
+ 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 2058 of file message.c.

2059 {
2060  return mutt_file_fclose(&msg->fp);
2061 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
FILE * fp
pointer to the message data
Definition: mx.h:84
+ 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 2044 of file message.c.

2045 {
2046  int rc = mutt_file_fclose(&msg->fp);
2047  if (rc != 0)
2048  return rc;
2049 
2050  return imap_append_message(m, msg);
2051 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int imap_append_message(struct Mailbox *m, struct Message *msg)
Write an email back to the server.
Definition: message.c:1430
FILE * fp
pointer to the message data
Definition: mx.h:84
+ 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 2066 of file message.c.

2067 {
2068  int rc = 0;
2069 #ifdef USE_HCACHE
2070  bool close_hc = true;
2071  struct ImapAccountData *adata = imap_adata_get(m);
2072  struct ImapMboxData *mdata = imap_mdata_get(m);
2073  if (!mdata || !adata)
2074  return -1;
2075  if (mdata->hcache)
2076  close_hc = false;
2077  else
2078  imap_hcache_open(adata, mdata);
2079  rc = imap_hcache_put(mdata, e);
2080  if (close_hc)
2081  imap_hcache_close(mdata);
2082 #endif
2083  return rc;
2084 }
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:516
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
struct HeaderCache * hcache
Definition: private.h:241
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
+ 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 114 of file util.c.

115 {
116  if (!m || (m->type != MUTT_IMAP) || !m->account)
117  return NULL;
118  return m->account->adata;
119 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ 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 244 of file util.c.

245 {
246  if (!m || (m->type != MUTT_IMAP) || !m->mdata)
247  return NULL;
248  return m->mdata;
249 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the caller graph for this function:

◆ imap_hcache_open()

void imap_hcache_open ( struct ImapAccountData adata,
struct ImapMboxData mdata 
)

Open a header cache.

Parameters
adataImap Account data
mdataImap Mailbox data

Definition at line 435 of file util.c.

436 {
437  if (!adata || !mdata)
438  return;
439 
440  if (mdata->hcache)
441  return;
442 
443  struct HeaderCache *hc = NULL;
444  struct Buffer *mbox = mutt_buffer_pool_get();
445  struct Buffer *cachepath = mutt_buffer_pool_get();
446 
447  imap_cachepath(adata->delim, mdata->name, mbox);
448 
449  if (strstr(mutt_b2s(mbox), "/../") || mutt_str_equal(mutt_b2s(mbox), "..") ||
450  mutt_strn_equal(mutt_b2s(mbox), "../", 3))
451  {
452  goto cleanup;
453  }
454  size_t len = mutt_buffer_len(mbox);
455  if ((len > 3) && (strcmp(mutt_b2s(mbox) + len - 3, "/..") == 0))
456  goto cleanup;
457 
458  struct Url url = { 0 };
459  mutt_account_tourl(&adata->conn->account, &url);
460  url.path = mbox->data;
461  url_tobuffer(&url, cachepath, U_PATH);
462 
464 
465 cleanup:
467  mutt_buffer_pool_release(&cachepath);
468  mdata->hcache = hc;
469 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
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:425
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:40
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
header cache structure
Definition: lib.h:85
String manipulation buffer.
Definition: buffer.h:33
struct HeaderCache * hcache
Definition: private.h:241
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:320
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:850
#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: private.h:219
char * path
Path.
Definition: url.h:73
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
int url_tobuffer(struct Url *url, struct Buffer *buf, int flags)
Output the URL string for a given Url object.
Definition: url.c:353
#define U_PATH
Definition: url.h:48
struct Connection * conn
Definition: private.h:172
+ 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 475 of file util.c.

476 {
477  if (!mdata->hcache)
478  return;
479 
480  mutt_hcache_close(mdata->hcache);
481  mdata->hcache = NULL;
482 }
struct HeaderCache * hcache
Definition: private.h:241
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:417
+ 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 491 of file util.c.

492 {
493  if (!mdata->hcache)
494  return NULL;
495 
496  char key[16];
497 
498  sprintf(key, "/%u", uid);
499  struct HCacheEntry hce =
500  mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key), mdata->uidvalidity);
501  if (!hce.email && hce.uidvalidity)
502  {
503  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
504  }
505 
506  return hce.email;
507 }
Wrapper for Email retrieved from the header cache.
Definition: lib.h:96
uint32_t uidvalidity
Definition: private.h:229
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:98
struct HeaderCache * hcache
Definition: private.h:241
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:436
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Email * email
Retrieved email.
Definition: lib.h:100
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 516 of file util.c.

517 {
518  if (!mdata->hcache)
519  return -1;
520 
521  char key[16];
522 
523  sprintf(key, "/%u", imap_edata_get(e)->uid);
524  return mutt_hcache_store(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
525 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
uint32_t uidvalidity
Definition: private.h:229
struct HeaderCache * hcache
Definition: private.h:241
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:525
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
+ 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 534 of file util.c.

535 {
536  if (!mdata->hcache)
537  return -1;
538 
539  char key[16];
540 
541  sprintf(key, "/%u", uid);
542  return mutt_hcache_delete_record(mdata->hcache, key, mutt_str_len(key));
543 }
struct HeaderCache * hcache
Definition: private.h:241
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:602
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
+ 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 551 of file util.c.

552 {
553  if (!mdata->hcache)
554  return -1;
555 
556  /* The seqset is likely large. Preallocate to reduce reallocs */
557  struct Buffer buf = mutt_buffer_make(8192);
558  imap_msn_index_to_uid_seqset(&buf, mdata);
559 
560  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
561  mutt_buffer_len(&buf) + 1);
562  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
563  mutt_buffer_dealloc(&buf);
564  return rc;
565 }
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
struct HeaderCache * hcache
Definition: private.h:241
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
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:582
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:369
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 573 of file util.c.

574 {
575  if (!mdata->hcache)
576  return -1;
577 
578  return mutt_hcache_delete_record(mdata->hcache, "/UIDSEQSET", 10);
579 }
struct HeaderCache * hcache
Definition: private.h:241
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:602
+ 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 587 of file util.c.

588 {
589  if (!mdata->hcache)
590  return NULL;
591 
592  char *seqset = NULL;
593  size_t dlen = 0;
594  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
595  if (hc_seqset)
596  {
597  seqset = mutt_strn_dup(hc_seqset, dlen);
598  mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
599  }
600  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
601 
602  return seqset;
603 }
#define NONULL(x)
Definition: string2.h:37
struct HeaderCache * hcache
Definition: private.h:241
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:512
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:548
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:494
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 787 of file util.c.

788 {
789  imap_error(msg, resp);
790  return mutt_yesorno(_("Continue?"), MUTT_NO);
791 }
#define _(a)
Definition: message.h:28
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
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 798 of file util.c.

799 {
800  mutt_error("%s [%s]", where, msg);
801 }
#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 92 of file util.c.

93 {
94  struct ImapAccountData *adata = mutt_mem_calloc(1, sizeof(struct ImapAccountData));
95  adata->account = a;
96 
97  static unsigned char new_seqid = 'a';
98 
99  adata->seqid = new_seqid;
100  adata->cmdslots = C_ImapPipelineDepth + 2;
101  adata->cmds = mutt_mem_calloc(adata->cmdslots, sizeof(*adata->cmds));
102 
103  if (++new_seqid > 'z')
104  new_seqid = 'a';
105 
106  return adata;
107 }
struct ImapCommand * cmds
Definition: private.h:200
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
unsigned char seqid
tag sequence prefix
Definition: private.h:187
struct Account * account
Parent Account.
Definition: private.h:209
short C_ImapPipelineDepth
Config: (imap) Number of IMAP commands that may be queued up.
Definition: config.c:54
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
+ 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)

Free the private Account data - Implements Account::adata_free()

Definition at line 66 of file util.c.

67 {
68  if (!ptr || !*ptr)
69  return;
70 
71  struct ImapAccountData *adata = *ptr;
72 
73  FREE(&adata->capstr);
74  mutt_buffer_dealloc(&adata->cmdbuf);
75  FREE(&adata->buf);
76  FREE(&adata->cmds);
77 
78  if (adata->conn)
79  {
80  if (adata->conn->close)
81  adata->conn->close(adata->conn);
82  FREE(&adata->conn);
83  }
84 
85  FREE(ptr);
86 }
struct ImapCommand * cmds
Definition: private.h:200
char * capstr
Definition: private.h:185
struct Buffer cmdbuf
Definition: private.h:204
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
int(* close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:100
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
char * buf
Definition: private.h:190
#define FREE(x)
Definition: memory.h:40
struct Connection * conn
Definition: private.h:172
+ 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 165 of file util.c.

166 {
167  char buf[1024];
168  struct ImapMboxData *mdata = mutt_mem_calloc(1, sizeof(struct ImapMboxData));
169 
170  mdata->real_name = mutt_str_dup(name);
171 
172  imap_fix_path(adata->delim, name, buf, sizeof(buf));
173  if (buf[0] == '\0')
174  mutt_str_copy(buf, "INBOX", sizeof(buf));
175  mdata->name = mutt_str_dup(buf);
176 
177  imap_munge_mbox_name(adata->unicode, buf, sizeof(buf), mdata->name);
178  mdata->munge_name = mutt_str_dup(buf);
179 
180  mdata->reopen &= IMAP_REOPEN_ALLOW;
181 
182  STAILQ_INIT(&mdata->flags);
183 
184 #ifdef USE_HCACHE
185  imap_hcache_open(adata, mdata);
186  if (mdata->hcache)
187  {
188  size_t dlen = 0;
189  void *uidvalidity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12, &dlen);
190  void *uidnext = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8, &dlen);
191  unsigned long long *modseq =
192  mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7, &dlen);
193  if (uidvalidity)
194  {
195  mdata->uidvalidity = *(uint32_t *) uidvalidity;
196  mdata->uid_next = uidnext ? *(unsigned int *) uidnext : 0;
197  mdata->modseq = modseq ? *modseq : 0;
198  mutt_debug(LL_DEBUG3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
199  mdata->uidvalidity, mdata->uid_next, mdata->modseq);
200  }
201  mutt_hcache_free_raw(mdata->hcache, &uidvalidity);
202  mutt_hcache_free_raw(mdata->hcache, &uidnext);
203  mutt_hcache_free_raw(mdata->hcache, (void **) &modseq);
204  imap_hcache_close(mdata);
205  }
206 #endif
207 
208  return mdata;
209 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
uint32_t uidvalidity
Definition: private.h:229
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct HeaderCache * hcache
Definition: private.h:241
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:512
#define STAILQ_INIT(head)
Definition: queue.h:369
void * mdata
Driver specific data.
Definition: mailbox.h:136
unsigned long long modseq
Definition: private.h:231
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
struct ListHead flags
Definition: private.h:228
char * name
Mailbox name.
Definition: private.h:219
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:221
unsigned int uid_next
Definition: private.h:230
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
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:1045
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:494
char * munge_name
Munged version of the mailbox name.
Definition: private.h:220
Log at debug level 3.
Definition: logging.h:42
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
+ 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)

Free the private Mailbox data - Implements Mailbox::mdata_free()

Definition at line 225 of file util.c.

226 {
227  if (!ptr || !*ptr)
228  return;
229 
230  struct ImapMboxData *mdata = *ptr;
231 
232  imap_mdata_cache_reset(mdata);
233  mutt_list_free(&mdata->flags);
234  FREE(&mdata->name);
235  FREE(&mdata->real_name);
236  FREE(&mdata->munge_name);
237  FREE(ptr);
238 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct ListHead flags
Definition: private.h:228
char * name
Mailbox name.
Definition: private.h:219
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:215
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:221
IMAP-specific Mailbox data -.
Definition: private.h:217
#define FREE(x)
Definition: memory.h:40
char * munge_name
Munged version of the mailbox name.
Definition: private.h:220
+ 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 215 of file util.c.

216 {
217  mutt_hash_free(&mdata->uid_hash);
218  imap_msn_free(&mdata->msn);
219  mutt_bcache_close(&mdata->bcache);
220 }
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
struct BodyCache * bcache
Definition: private.h:239
void imap_msn_free(struct MSN *msn)
Free the cache.
Definition: msn.c:59
struct HashTable * uid_hash
Definition: private.h:237
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:157
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_fix_path()

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

Fix up the imap path.

Parameters
delimDelimiter specified by the server, '\0' for C_ImapDelimChars
mailboxMailbox path
pathBuffer for the result
plenLength of buffer
Return values
ptrFixed-up path
Note
if delim is '\0', the first character in mailbox matching any of the characters in C_ImapDelimChars is used as a delimiter.

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 820 of file util.c.

821 {
822  int i = 0;
823  for (; mailbox && *mailbox && (i < plen - 1); i++)
824  {
825  if (*mailbox == delim || (!delim && strchr(NONULL(C_ImapDelimChars), *mailbox)))
826  {
827  delim = *mailbox;
828  /* Skip multiple occurrences of delim */
829  while (*mailbox && *(mailbox + 1) == delim)
830  mailbox++;
831  }
832  path[i] = *mailbox++;
833  }
834 
835  /* Do not terminate with a delimiter */
836  if (i && path[i - 1] == delim)
837  i--;
838 
839  /* Ensure null termination */
840  path[i] = '\0';
841  return path;
842 }
#define NONULL(x)
Definition: string2.h:37
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: config.c:43
+ 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 850 of file util.c.

851 {
852  const char *p = mailbox;
853  mutt_buffer_reset(dest);
854  if (!p)
855  return;
856 
857  while (*p)
858  {
859  if (p[0] == delim)
860  {
861  mutt_buffer_addch(dest, '/');
862  /* simple way to avoid collisions with UIDs */
863  if ((p[1] >= '0') && (p[1] <= '9'))
864  mutt_buffer_addch(dest, '_');
865  }
866  else
867  mutt_buffer_addch(dest, *p);
868  p++;
869  }
870 }
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 879 of file util.c.

880 {
881  char *pc = NULL;
882  char *pn = NULL;
883 
884  if (!buf || !(pc = strchr(buf, '{')))
885  return -1;
886 
887  pc++;
888  pn = pc;
889  while (isdigit((unsigned char) *pc))
890  pc++;
891  *pc = '\0';
892  if (mutt_str_atoui(pn, bytes) < 0)
893  return -1;
894 
895  return 0;
896 }
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
+ 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 906 of file util.c.

907 {
908  char *s = buf;
909 
910  /* skip tag */
911  s = imap_next_word(s);
912  /* skip OK/NO/BAD response */
913  s = imap_next_word(s);
914 
915  return s;
916 }
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
+ 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 923 of file util.c.

924 {
925  bool quoted = false;
926 
927  while (*s)
928  {
929  if (*s == '\\')
930  {
931  s++;
932  if (*s)
933  s++;
934  continue;
935  }
936  if (*s == '\"')
937  quoted = !quoted;
938  if (!quoted && IS_SPACE(*s))
939  break;
940  s++;
941  }
942 
943  SKIPWS(s);
944  return s;
945 }
#define SKIPWS(ch)
Definition: string2.h:46
#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 954 of file util.c.

955 {
956  struct Url url = { 0 };
957  mutt_account_tourl(cac, &url);
958  url.path = path;
959  url_tostring(&url, buf, buflen, 0);
960 }
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:79
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:418
+ 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 971 of file util.c.

972 {
973  const char *quote = "`\"\\";
974  if (!quote_backtick)
975  quote++;
976 
977  char *pt = dest;
978  const char *s = src;
979 
980  *pt++ = '"';
981  /* save room for quote-chars */
982  dlen -= 3;
983 
984  for (; *s && dlen; s++)
985  {
986  if (strchr(quote, *s))
987  {
988  if (dlen < 2)
989  break;
990  dlen -= 2;
991  *pt++ = '\\';
992  *pt++ = *s;
993  }
994  else
995  {
996  *pt++ = *s;
997  dlen--;
998  }
999  }
1000  *pt++ = '"';
1001  *pt = '\0';
1002 }
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 1008 of file util.c.

1009 {
1010  char *d = s;
1011 
1012  if (*s == '\"')
1013  s++;
1014  else
1015  return;
1016 
1017  while (*s)
1018  {
1019  if (*s == '\"')
1020  {
1021  *d = '\0';
1022  return;
1023  }
1024  if (*s == '\\')
1025  {
1026  s++;
1027  }
1028  if (*s)
1029  {
1030  *d = *s;
1031  d++;
1032  s++;
1033  }
1034  }
1035  *d = '\0';
1036 }
+ 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 1045 of file util.c.

1046 {
1047  char *buf = mutt_str_dup(src);
1048  imap_utf_encode(unicode, &buf);
1049 
1050  imap_quote_string(dest, dlen, buf, false);
1051 
1052  FREE(&buf);
1053 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
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:971
#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 1062 of file util.c.

1063 {
1065 
1066  char *buf = mutt_str_dup(s);
1067  if (buf)
1068  {
1069  imap_utf_decode(unicode, &buf);
1070  strncpy(s, buf, strlen(s));
1071  }
1072 
1073  FREE(&buf);
1074 }
void imap_unquote_string(char *s)
equally stupid unquoting routine
Definition: util.c:1008
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:345
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#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 1209 of file util.c.

1210 {
1211  if (!seqset || (*seqset == '\0'))
1212  return NULL;
1213 
1214  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1215  iter->full_seqset = mutt_str_dup(seqset);
1216  iter->eostr = strchr(iter->full_seqset, '\0');
1217  iter->substr_cur = iter->substr_end = iter->full_seqset;
1218 
1219  return iter;
1220 }
char * eostr
Definition: private.h:250
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
char * substr_cur
Definition: private.h:255
char * substr_end
Definition: private.h:256
char * full_seqset
Definition: private.h:249
UID Sequence Set Iterator.
Definition: private.h:247
+ 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 1230 of file util.c.

1231 {
1232  if (!iter || !next)
1233  return -1;
1234 
1235  if (iter->in_range)
1236  {
1237  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1238  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1239  {
1240  iter->in_range = 0;
1241  }
1242  }
1243 
1244  if (!iter->in_range)
1245  {
1246  iter->substr_cur = iter->substr_end;
1247  if (iter->substr_cur == iter->eostr)
1248  return 1;
1249 
1250  while (!*(iter->substr_cur))
1251  iter->substr_cur++;
1252  iter->substr_end = strchr(iter->substr_cur, ',');
1253  if (!iter->substr_end)
1254  iter->substr_end = iter->eostr;
1255  else
1256  *(iter->substr_end) = '\0';
1257 
1258  char *range_sep = strchr(iter->substr_cur, ':');
1259  if (range_sep)
1260  *range_sep++ = '\0';
1261 
1262  if (mutt_str_atoui(iter->substr_cur, &iter->range_cur) != 0)
1263  return -1;
1264  if (range_sep)
1265  {
1266  if (mutt_str_atoui(range_sep, &iter->range_end) != 0)
1267  return -1;
1268  }
1269  else
1270  iter->range_end = iter->range_cur;
1271 
1272  iter->down = (iter->range_end < iter->range_cur);
1273  iter->in_range = 1;
1274  }
1275 
1276  *next = iter->range_cur;
1277  if (iter->down)
1278  iter->range_cur--;
1279  else
1280  iter->range_cur++;
1281 
1282  return 0;
1283 }
char * eostr
Definition: private.h:250
unsigned int range_end
Definition: private.h:254
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
char * substr_cur
Definition: private.h:255
char * substr_end
Definition: private.h:256
unsigned int range_cur
Definition: private.h:253
+ 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 1289 of file util.c.

1290 {
1291  if (!ptr || !*ptr)
1292  return;
1293 
1294  struct SeqsetIterator *iter = *ptr;
1295  FREE(&iter->full_seqset);
1296  FREE(ptr);
1297 }
#define FREE(x)
Definition: memory.h:40
char * full_seqset
Definition: private.h:249
UID Sequence Set Iterator.
Definition: private.h:247
+ 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 1178 of file util.c.

1179 {
1180  if (!a1 || !a2)
1181  return false;
1182  if (a1->type != a2->type)
1183  return false;
1184  if (!mutt_istr_equal(a1->host, a2->host))
1185  return false;
1186  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1187  return false;
1188  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1189  return strcmp(a1->user, a2->user) == 0;
1190 
1191  const char *user = NONULL(Username);
1192 
1193  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && C_ImapUser)
1194  user = C_ImapUser;
1195 
1196  if (a1->flags & MUTT_ACCT_USER)
1197  return strcmp(a1->user, user) == 0;
1198  if (a2->flags & MUTT_ACCT_USER)
1199  return strcmp(a2->user, user) == 0;
1200 
1201  return true;
1202 }
#define NONULL(x)
Definition: string2.h:37
char user[128]
Username.
Definition: connaccount.h:55
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
char host[128]
Server to login to.
Definition: connaccount.h:53
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:52
char * C_ImapUser
Config: (imap) Username for the IMAP server.
Definition: config.c:59
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
unsigned short port
Port to connect to.
Definition: connaccount.h:57
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
Imap Account.
Definition: mutt_account.h:37
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
+ 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 258 of file util.c.

259 {
260  /* Make a copy of the mailbox name, but only if the pointers are different */
261  if (mbox != buf)
262  mutt_str_copy(buf, mbox, buflen);
263 
264  int n = mutt_str_len(buf);
265 
266  /* Let's go backwards until the next delimiter
267  *
268  * If buf[n] is a '/', the first n-- will allow us
269  * to ignore it. If it isn't, then buf looks like
270  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
271  * the "/" after the 'a's.
272  *
273  * If buf == '/', then n-- => n == 0, so the loop ends
274  * immediately */
275  for (n--; (n >= 0) && (buf[n] != delim); n--)
276  ; // do nothing
277 
278  /* We stopped before the beginning. There is a trailing slash. */
279  if (n > 0)
280  {
281  /* Strip the trailing delimiter. */
282  buf[n] = '\0';
283  }
284  else
285  {
286  buf[0] = (n == 0) ? delim : '\0';
287  }
288 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
+ 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 }
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:754
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 mutt_ch_is_utf8(str)
Definition: charset.h:95
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
+ 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 }
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags)
Convert a string between encodings.
Definition: charset.c:754
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 mutt_ch_is_utf8(str)
Definition: charset.h:95
#define FREE(x)
Definition: memory.h:40
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
+ 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 1150 of file util.c.

1151 {
1152  struct ImapAccountData *adata = imap_adata_get(m);
1153  struct ImapMboxData *mdata = imap_mdata_get(m);
1154  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1155  return;
1156  mdata->reopen |= IMAP_REOPEN_ALLOW;
1157 }
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
IMAP-specific Mailbox data -.
Definition: private.h:217
+ 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 1163 of file util.c.

1164 {
1165  struct ImapAccountData *adata = imap_adata_get(m);
1166  struct ImapMboxData *mdata = imap_mdata_get(m);
1167  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1168  return;
1169  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1170 }
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
IMAP-specific Mailbox data -.
Definition: private.h:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cmd_parse_search()

void cmd_parse_search ( struct ImapAccountData adata,
const char *  s 
)

store SEARCH response for later use

Parameters
adataImap Account data
sCommand string with search results

Definition at line 258 of file search.c.

259 {
260  unsigned int uid;
261  struct Email *e = NULL;
262  struct ImapMboxData *mdata = adata->mailbox->mdata;
263 
264  mutt_debug(LL_DEBUG2, "Handling SEARCH\n");
265 
266  while ((s = imap_next_word((char *) s)) && (*s != '\0'))
267  {
268  if (mutt_str_atoui(s, &uid) < 0)
269  continue;
270  e = mutt_hash_int_find(mdata->uid_hash, uid);
271  if (e)
272  e->matched = true;
273  }
274 }
The envelope/body of an email.
Definition: email.h:37
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
void * mutt_hash_int_find(const struct HashTable *table, unsigned int intkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:384
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
Log at debug level 2.
Definition: logging.h:41
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct HashTable * uid_hash
Definition: private.h:237
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
IMAP-specific Mailbox data -.
Definition: private.h:217
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool matched
Search matches this Email.
Definition: email.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ImapAuthenticators

struct Slist* C_ImapAuthenticators

Config: (imap) List of allowed IMAP authentication methods.

Definition at line 37 of file config.c.

◆ C_ImapCheckSubscribed

bool C_ImapCheckSubscribed

Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.

Definition at line 38 of file config.c.

◆ C_ImapCondstore

bool C_ImapCondstore

Config: (imap) Enable the CONDSTORE extension.

Definition at line 39 of file config.c.

◆ C_ImapDeflate

bool C_ImapDeflate

Config: (imap) Compress network traffic.

Definition at line 41 of file config.c.

◆ C_ImapDelimChars

char* C_ImapDelimChars

Config: (imap) Characters that denote separators in IMAP folders.

Definition at line 43 of file config.c.

◆ C_ImapFetchChunkSize

long C_ImapFetchChunkSize

Config: (imap) Download headers in blocks of this size.

Definition at line 44 of file config.c.

◆ C_ImapHeaders

char* C_ImapHeaders

Config: (imap) Additional email headers to download when getting index.

Definition at line 45 of file config.c.

◆ C_ImapIdle

bool C_ImapIdle

Config: (imap) Use the IMAP IDLE extension to check for new mail.

Definition at line 46 of file config.c.

◆ C_ImapLogin

char* C_ImapLogin

Config: (imap) Login name for the IMAP server (defaults to C_ImapUser)

Definition at line 49 of file config.c.

◆ C_ImapOauthRefreshCommand

char* C_ImapOauthRefreshCommand

Config: (imap) External command to generate OAUTH refresh token.

Definition at line 50 of file config.c.

◆ C_ImapPass

char* C_ImapPass

Config: (imap) Password for the IMAP server.

Definition at line 51 of file config.c.

◆ C_ImapPipelineDepth

short C_ImapPipelineDepth

Config: (imap) Number of IMAP commands that may be queued up.

Definition at line 54 of file config.c.

◆ C_ImapPollTimeout

short C_ImapPollTimeout

Config: (imap) Maximum time to wait for a server response.

Definition at line 55 of file config.c.

◆ C_ImapQresync

bool C_ImapQresync

Config: (imap) Enable the QRESYNC extension.

Definition at line 56 of file config.c.

◆ C_ImapRfc5161

bool C_ImapRfc5161

Config: (imap) Use the IMAP ENABLE extension to select capabilities.

Definition at line 57 of file config.c.

◆ C_ImapServernoise

bool C_ImapServernoise

Config: (imap) Display server warnings as error messages.

Definition at line 58 of file config.c.

◆ C_ImapUser

char* C_ImapUser

Config: (imap) Username for the IMAP server.

Definition at line 59 of file config.c.