63#define IMAP_CMD_BUFSIZE 512
66#define IMAP_MAX_RETRIES 5
69#define IMAP_MAX_BACKOFF 30
72#define IMAP_CONN_STALE_THRESHOLD 300
136 snprintf(cmd->
seq,
sizeof(cmd->
seq),
"%c%04u", adata->
seqid, adata->
seqno++);
137 if (adata->
seqno > 9999)
221 mutt_message(
_(
"Connection lost. Retrying in %u seconds..."), delay);
241 mutt_error(
_(
"Failed to reconnect to %s after %d attempts"),
247 mutt_error(
_(
"Reconnection to %s failed. Will retry automatically."),
321 unsigned int exp_msn = 0;
322 struct Email *e = NULL;
351 for (
unsigned int cur = exp_msn; cur < max_msn; cur++)
377 bool earlier =
false;
379 unsigned int uid = 0;
395 char *end_of_seqset = s;
396 while (*end_of_seqset)
398 if (!strchr(
"0123456789:,", *end_of_seqset))
399 *end_of_seqset =
'\0';
442 for (
unsigned int cur = exp_msn; cur < max_msn; cur++)
473 unsigned int msn, uid;
474 struct Email *e = NULL;
477 bool server_changes =
false;
539 while (*s && (*s !=
')'))
580 while (*s && (*s !=
')'))
627 char *bracket = strchr(s,
']');
639 if (len != 0 && ((s[len] ==
'\0') ||
mutt_isspace(s[len])))
666 memset(list, 0,
sizeof(
struct ImapList));
695 char delimbuf[5] = { 0 };
696 snprintf(delimbuf,
sizeof(delimbuf),
"%s", s);
698 list->
delim = delimbuf[0];
712 if (strlen(adata->
buf) < litlen)
719 s = list->
name + litlen;
737 if (list->
name[0] ==
'\0')
759 if (!c_imap_check_subscribed)
775 struct Url url = { 0 };
893 unsigned int litlen = 0;
906 if (strlen(adata->
buf) < litlen)
912 mailbox = adata->
buf;
913 s = mailbox + litlen;
932 uint32_t olduv =
mdata->uidvalidity;
933 unsigned int oldun =
mdata->uid_next;
940 while ((s[0] !=
'\0') && (s[0] !=
')'))
945 const unsigned long ulcount = strtoul(value, &value, 10);
946 const bool truncated = ((errno == ERANGE) && (ulcount == ULONG_MAX)) ||
947 ((
unsigned int) ulcount != ulcount);
948 const unsigned int count = (
unsigned int) ulcount;
958 "UIDVALIDITY [%lu] exceeds 32 bits, "
959 "truncated to [%u]\n",
962 mdata->uidvalidity = count;
974 mdata->messages = count;
976 mdata->recent = count;
978 mdata->uid_next = count;
980 mdata->unseen = count;
985 if ((s[0] !=
'\0') && (*s !=
')'))
988 mutt_debug(
LL_DEBUG3,
"%s (UIDVALIDITY: %u, UIDNEXT: %u) %d messages, %d recent, %d unseen\n",
995 mailbox, olduv, oldun,
mdata->unseen);
997 bool new_mail =
false;
999 if (c_mail_check_recent)
1001 if ((olduv != 0) && (olduv ==
mdata->uidvalidity))
1004 new_mail = (
mdata->unseen > 0);
1006 else if ((olduv == 0) && (oldun == 0))
1009 new_mail = (
mdata->recent > 0);
1013 new_mail = (
mdata->unseen > 0);
1018 new_mail = (
mdata->unseen > 0);
1027 mdata->uid_next = oldun;
1060 unsigned int count = 0;
1090 mdata->new_mail_count = count;
1218 int stillrunning = 0;
1231 if (len == adata->
blen)
1249 if (read_duration > 1)
1257 c, errno, strerror(errno));
1269 while (len == adata->
blen);
1290 if (adata->
buf[0] ==
'+')
1307 cmd = &adata->
cmds[c];
1331 }
while (c != adata->
nextcmd);
1365 static const char *notrailer =
"";
1366 const char *s = adata->
buf;
1426 int rc =
cmd_start(adata, cmdstr, flags);
1522 if (
mdata->new_mail_count > max_msn)
1528 max_msn + 1,
mdata->new_mail_count);
1565 mutt_debug(
LL_DEBUG2,
"Waiting for IDLE continuation (timeout=%d)\n", c_imap_poll_timeout);
1567 if ((c_imap_poll_timeout > 0) &&
1571 mutt_error(
_(
"Connection to %s timed out waiting for IDLE response"),
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
#define MUTT_ACL_CREATE
Create a mailbox.
@ NT_MAILBOX_CHANGE
Mailbox has been changed.
#define MUTT_ACL_DELMX
Delete a mailbox.
#define MUTT_ACL_POST
Post (submit messages to the server)
#define MUTT_ACL_LOOKUP
Lookup mailbox (visible to 'list')
#define MUTT_ACL_INSERT
Add/copy into the mailbox (used when editing a message)
#define MUTT_ACL_DELETE
Delete a message.
#define MUTT_ACL_EXPUNGE
Expunge messages.
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
#define MUTT_ACL_SEEN
Change the 'seen' status of a message.
#define MUTT_ACL_ADMIN
Administer the account (get/set permissions)
#define MUTT_ACL_READ
Read the mailbox.
bool mutt_isspace(int arg)
Wrapper for isspace(3)
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
Structs that make up an email.
#define mutt_message(...)
#define mutt_debug(LEVEL,...)
void * mutt_hash_int_find(const struct HashTable *table, unsigned int intkey)
Find the HashElem data in a Hash Table element using a key.
Imap-specific Account data.
static void cmd_parse_list(struct ImapAccountData *adata, char *s)
Parse a server LIST command (list mailboxes)
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
static void cmd_parse_capability(struct ImapAccountData *adata, char *s)
Set capability bits according to CAPABILITY response.
static void cmd_parse_lsub(struct ImapAccountData *adata, char *s)
Parse a server LSUB (list subscribed mailboxes)
static void cmd_parse_status(struct ImapAccountData *adata, char *s)
Parse status from server.
#define IMAP_MAX_RETRIES
Maximum number of reconnection attempts before giving up.
#define IMAP_CONN_STALE_THRESHOLD
Threshold in seconds after which to consider a connection potentially stale.
static int cmd_handle_untagged(struct ImapAccountData *adata)
Fallback parser for otherwise unhandled messages.
static struct Mailbox * find_mailbox(struct ImapAccountData *adata, const char *name)
Find a Mailbox by its name.
static void cmd_parse_exists(struct ImapAccountData *adata, const char *pn)
Parse EXISTS message from serer.
#define IMAP_MAX_BACKOFF
Maximum backoff delay in seconds between reconnection attempts.
static const char *const Capabilities[]
Server capabilities strings that we understand.
const char * imap_cmd_trailer(struct ImapAccountData *adata)
Extra information after tagged command response if any.
static void cmd_parse_myrights(struct ImapAccountData *adata, const char *s)
Set rights bits according to MYRIGHTS response.
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
static int cmd_status(const char *s)
Parse response line for tagged OK/NO/BAD.
static int cmd_start(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Start a new IMAP command.
static void cmd_parse_expunge(struct ImapAccountData *adata, const char *s)
Parse expunge command.
static void cmd_parse_enabled(struct ImapAccountData *adata, const char *s)
Record what the server has enabled.
static int cmd_queue(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Add a IMAP command to the queue.
static void cmd_parse_vanished(struct ImapAccountData *adata, char *s)
Parse vanished command.
bool imap_code(const char *s)
Was the command successful.
static bool cmd_queue_full(struct ImapAccountData *adata)
Is the IMAP command queue full?
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
static void cmd_handle_fatal(struct ImapAccountData *adata)
When ImapAccountData is in fatal state, do what we can.
static void cmd_parse_fetch(struct ImapAccountData *adata, char *s)
Load fetch response into ImapAccountData.
static struct ImapCommand * cmd_new(struct ImapAccountData *adata)
Create and queue a new command control block.
#define IMAP_CMD_BUFSIZE
Default buffer size for IMAP commands.
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Imap-specific Email data.
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Imap-specific Mailbox data.
char * imap_set_flags(struct Mailbox *m, struct Email *e, char *s, bool *server_changes)
Fill the message header according to the server flags.
int imap_read_headers(struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool initial_download)
Read headers from the server.
Shared constants/structs that are private to IMAP.
void imap_unmunge_mbox_name(bool unicode, char *s)
Remove quoting from a mailbox name.
#define IMAP_CMD_NO_FLAGS
No flags are set.
#define IMAP_RES_RESPOND
+
@ IMAP_IDLE
Connection is idle.
@ IMAP_AUTHENTICATED
Connection is authenticated.
@ IMAP_SELECTED
Mailbox is selected.
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
int imap_get_literal_count(const char *buf, unsigned int *bytes)
Write number of bytes in an IMAP literal into bytes.
#define IMAP_RES_OK
<tag> OK ...
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
struct SeqsetIterator * mutt_seqset_iterator_new(const char *seqset)
Create a new Sequence Set Iterator.
void imap_unquote_string(char *s)
Equally stupid unquoting routine.
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next)
Get the next UID from a Sequence Set.
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
@ IMAP_EXEC_ERROR
Imap command failure.
@ IMAP_EXEC_FATAL
Imap connection failure.
void mutt_seqset_iterator_free(struct SeqsetIterator **ptr)
Free a Sequence Set Iterator.
#define IMAP_LOG_PASS
Log passwords (dangerous!)
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
@ IMAP_BYE
Logged out from server.
@ IMAP_FATAL
Unrecoverable error occurred.
#define IMAP_RES_NEW
ImapCommand.state additions.
#define IMAP_RES_NO
<tag> NO ...
void cmd_parse_search(struct ImapAccountData *adata, const char *s)
Store SEARCH response for later use.
#define IMAP_CMD_SINGLE
Run a single command.
#define IMAP_RES_CONTINUE
* ...
char * imap_next_word(char *s)
Find where the next IMAP word begins.
#define IMAP_RES_BAD
<tag> BAD ...
uint8_t ImapCmdFlags
Flags for imap_exec(), e.g. IMAP_CMD_PASS.
#define IMAP_LOG_CMD
Log commands only.
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
void imap_close_connection(struct ImapAccountData *adata)
Close an IMAP connection.
void imap_expunge_mailbox(struct Mailbox *m, bool resort)
Purge messages from the server.
int imap_login(struct ImapAccountData *adata)
Open an IMAP connection.
@ LL_DEBUG3
Log at debug level 3.
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
bool mailbox_add_simple(const char *mailbox, struct Buffer *err)
Add a new Mailbox.
#define FREE(x)
Free memory and set the pointer to NULL.
#define MUTT_MEM_REALLOC(pptr, n, type)
size_t imap_msn_shrink(struct MSNArray *msn, size_t num)
Remove a number of entries from the end of the cache.
void imap_msn_remove(struct MSNArray *msn, int idx)
Remove an entry from the cache.
struct Email * imap_msn_get(const struct MSNArray *msn, int idx)
Return the Email associated with an msn.
size_t imap_msn_highest(const struct MSNArray *msn)
Return the highest MSN in use.
void imap_msn_set(struct MSNArray *msn, size_t idx, struct Email *e)
Cache an Email into a given position.
IMAP MSN helper functions.
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Convenience wrapper for the library headers.
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
void account_to_url(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
#define MUTT_SOCK_LOG_FULL
Log everything including full protocol.
#define mutt_socket_send_d(conn, buf, dbg)
struct MailboxArray mailboxes
All Mailboxes.
String manipulation buffer.
char * data
Pointer to data.
char host[128]
Server to login to.
struct ConnAccount account
Account details: username, password, etc.
int fd
Socket file descriptor.
The envelope/body of an email.
void * edata
Driver-specific data.
bool active
Message is not to be removed.
bool changed
Email has been edited.
int index
The absolute (unsorted) message number.
An Event that happened to a Mailbox.
IMAP-specific Account data -.
char delim
Path delimiter.
bool qresync
true, if QRESYNC is successfully ENABLE'd
struct ImapList * cmdresult
Resuls of complicated commands.
int lastcmd
Last command in the queue.
bool closing
If true, we are waiting for CLOSE completion.
time_t lastread
last time we read a command for the server
unsigned char seqid
tag sequence prefix
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
ImapCapFlags capabilities
Capability flags.
struct Account * account
Parent Account.
size_t blen
Command buffer length.
int nextcmd
Next command to be sent.
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
struct Mailbox * mailbox
Current selected mailbox.
char * capstr
Capability string from the server.
struct ImapCommand * cmds
Queue of commands for the server.
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
unsigned char retry_count
Number of consecutive reconnection attempts.
time_t last_success
last time a command completed successfully
int cmdslots
Size of the command queue.
char * buf
Command buffer.
unsigned int seqno
tag sequence number, e.g. '{seqid}0001'
bool recovering
Recovering after a fatal error.
struct Connection * conn
Connection to IMAP server.
struct Buffer cmdbuf
Command queue.
int state
Command state, e.g. IMAP_RES_NEW.
char seq[SEQ_LEN+1]
Command tag, e.g. 'a0001'.
IMAP-specific Email data -.
unsigned int uid
32-bit Message UID
unsigned int msn
Message Sequence Number.
Items in an IMAP browser.
bool noselect
Mailbox is not selectable.
bool noinferiors
Mailbox has no children.
char delim
Hierarchy delimiter.
IMAP-specific Mailbox data -.
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
unsigned int uid_next
Next UID for new message.
struct ListHead flags
List of permanent flags.
struct HashTable * uid_hash
Hash Table: "uid" -> Email.
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
bool has_new
Mailbox has new mail.
int msg_count
Total number of messages.
AclFlags rights
ACL bits, see AclFlags.
void * mdata
Driver specific data.
char * name
A short name for the Mailbox.
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
int msg_unread
Number of unread messages.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
UID Sequence Set Iterator.
A parsed URL proto://user:password@host:port/path?a=1&b=2
int url_tobuffer(const struct Url *url, struct Buffer *buf, uint8_t flags)
Output the URL string for a given Url object.
#define U_NO_FLAGS
No flags are set for URL parsing.