NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
imap.c File Reference
#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "lib.h"
#include "bcache/lib.h"
#include "pattern/lib.h"
#include "adata.h"
#include "auth.h"
#include "command_parse.h"
#include "commands.h"
#include "edata.h"
#include "hook.h"
#include "init.h"
#include "mdata.h"
#include "message.h"
#include "msn.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "mutt_socket.h"
#include "muttlib.h"
#include "mx.h"
#include "progress.h"
#include "sort.h"
#include <libintl.h>
+ Include dependency graph for imap.c:

Go to the source code of this file.

Functions

void imap_init (void)
 Setup feature commands. More...
 
static int check_capabilities (struct ImapAccountData *adata)
 Make sure we can log in to this server. More...
 
static char * get_flags (struct ListHead *hflags, char *s)
 Make a simple list out of a FLAGS response. More...
 
static void set_flag (struct Mailbox *m, AclFlags aclflag, bool flag, const char *str, char *flags, size_t flsize)
 append str to flags if we currently have permission according to aclflag More...
 
static int make_msg_set (struct Mailbox *m, struct Buffer *buf, enum MessageType flag, bool changed, bool invert, int *pos)
 Make a message set. More...
 
static bool compare_flags_for_copy (struct Email *e)
 Compare local flags against the server. More...
 
static int sync_helper (struct Mailbox *m, AclFlags right, enum MessageType flag, const char *name)
 Sync flag changes to the server. More...
 
static size_t longest_common_prefix (char *dest, const char *src, size_t start, size_t dlen)
 Find longest prefix common to two strings. More...
 
static int complete_hosts (char *buf, size_t buflen)
 Look for completion matches for mailboxes. More...
 
int imap_create_mailbox (struct ImapAccountData *adata, char *mailbox)
 Create a new mailbox. More...
 
int imap_access (const char *path)
 Check permissions on an IMAP mailbox with a new connection. More...
 
int imap_rename_mailbox (struct ImapAccountData *adata, char *oldname, const char *newname)
 Rename a mailbox. More...
 
int imap_delete_mailbox (struct Mailbox *m, char *path)
 Delete a mailbox. More...
 
static void imap_logout (struct ImapAccountData *adata)
 Gracefully log out of server. More...
 
void imap_logout_all (void)
 close all open connections 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_notify_delete_email (struct Mailbox *m, struct Email *e)
 Inform IMAP that an Email has been deleted. More...
 
void imap_expunge_mailbox (struct Mailbox *m)
 Purge messages from the server. 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...
 
bool imap_has_flag (struct ListHead *flag_list, const char *flag)
 Does the flag exist in the list. More...
 
static int compare_uid (const void *a, const void *b)
 Compare two Emails by UID - Implements sort_t. More...
 
int imap_exec_msgset (struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
 Prepare commands for all messages matching conditions. 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...
 
enum MxStatus imap_check_mailbox (struct Mailbox *m, bool force)
 use the NOOP or IDLE command to poll for new mail More...
 
static int imap_status (struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
 Refresh the number of total and new messages. More...
 
static enum MxStatus imap_mbox_check_stats (struct Mailbox *m, uint8_t flags)
 Check the Mailbox statistics - Implements MxOps::mbox_check_stats() More...
 
int imap_path_status (const char *path, bool queue)
 Refresh the number of total and new messages. More...
 
int imap_mailbox_status (struct Mailbox *m, bool queue)
 Refresh the number of total and new messages. More...
 
int imap_subscribe (char *path, bool subscribe)
 Subscribe to a mailbox. More...
 
int imap_complete (char *buf, size_t buflen, const char *path)
 Try to complete an IMAP folder path. More...
 
int imap_fast_trash (struct Mailbox *m, char *dest)
 Use server COPY command to copy deleted messages to trash. More...
 
enum MxStatus imap_sync_mailbox (struct Mailbox *m, bool expunge, bool close)
 Sync all the changes to the server. More...
 
static bool imap_ac_owns_path (struct Account *a, const char *path)
 Check whether an Account owns a Mailbox path - Implements MxOps::ac_owns_path() More...
 
static bool imap_ac_add (struct Account *a, struct Mailbox *m)
 Add a Mailbox to an Account - Implements MxOps::ac_add() More...
 
static void imap_mbox_select (struct Mailbox *m)
 Select a Mailbox. More...
 
int imap_login (struct ImapAccountData *adata)
 Open an IMAP connection. More...
 
static enum MxOpenReturns imap_mbox_open (struct Mailbox *m)
 Open a mailbox - Implements MxOps::mbox_open() More...
 
static bool imap_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() More...
 
static enum MxStatus imap_mbox_check (struct Mailbox *m)
 Check for new mail - Implements MxOps::mbox_check() More...
 
static enum MxStatus imap_mbox_close (struct Mailbox *m)
 Close a Mailbox - Implements MxOps::mbox_close() More...
 
static bool imap_msg_open_new (struct Mailbox *m, struct Message *msg, const struct Email *e)
 Open a new message in a Mailbox - Implements MxOps::msg_open_new() More...
 
static int imap_tags_edit (struct Mailbox *m, const char *tags, char *buf, size_t buflen)
 Prompt and validate new messages tags - Implements MxOps::tags_edit() More...
 
static int imap_tags_commit (struct Mailbox *m, struct Email *e, char *buf)
 Save the tags to a message - Implements MxOps::tags_commit() More...
 
enum MailboxType imap_path_probe (const char *path, const struct stat *st)
 Is this an IMAP Mailbox? - Implements MxOps::path_probe() More...
 
int imap_path_canon (char *buf, size_t buflen)
 Canonicalise a Mailbox path - Implements MxOps::path_canon() More...
 
int imap_expand_path (struct Buffer *buf)
 Buffer wrapper around imap_path_canon() More...
 
static int imap_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a Mailbox path - Implements MxOps::path_pretty() More...
 
static int imap_path_parent (char *buf, size_t buflen)
 Find the parent of a Mailbox path - Implements MxOps::path_parent() More...
 
static int imap_path_is_empty (const char *path)
 Is the mailbox empty - Implements MxOps::path_is_empty() More...
 

Variables

static const struct Command imap_commands []
 
struct MxOps MxImapOps
 IMAP Mailbox - Implements MxOps. More...
 

Detailed Description

IMAP network mailbox

Authors
  • Michael R. Elkins
  • Brandon Long
  • Brendan Cully
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file imap.c.

Function Documentation

◆ imap_init()

void imap_init ( void  )

Setup feature commands.

Definition at line 82 of file imap.c.

83 {
85 }
+ Here is the caller graph for this function:

◆ check_capabilities()

static int check_capabilities ( struct ImapAccountData adata)
static

Make sure we can log in to this server.

Parameters
adataImap Account data
Return values
0Success
-1Failure

Definition at line 93 of file imap.c.

94 {
95  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
96  {
97  imap_error("check_capabilities", adata->buf);
98  return -1;
99  }
100 
101  if (!((adata->capabilities & IMAP_CAP_IMAP4) || (adata->capabilities & IMAP_CAP_IMAP4REV1)))
102  {
103  mutt_error(
104  _("This IMAP server is ancient. NeoMutt does not work with it."));
105  return -1;
106  }
107 
108  return 0;
109 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_flags()

static char* get_flags ( struct ListHead *  hflags,
char *  s 
)
static

Make a simple list out of a FLAGS response.

Parameters
hflagsList to store flags
sString containing flags
Return values
ptrEnd of the flags
NULLFailure

return stream following FLAGS response

Definition at line 120 of file imap.c.

121 {
122  /* sanity-check string */
123  const size_t plen = mutt_istr_startswith(s, "FLAGS");
124  if (plen == 0)
125  {
126  mutt_debug(LL_DEBUG1, "not a FLAGS response: %s\n", s);
127  return NULL;
128  }
129  s += plen;
130  SKIPWS(s);
131  if (*s != '(')
132  {
133  mutt_debug(LL_DEBUG1, "bogus FLAGS response: %s\n", s);
134  return NULL;
135  }
136 
137  /* update caller's flags handle */
138  while (*s && (*s != ')'))
139  {
140  s++;
141  SKIPWS(s);
142  const char *flag_word = s;
143  while (*s && (*s != ')') && !IS_SPACE(*s))
144  s++;
145  const char ctmp = *s;
146  *s = '\0';
147  if (*flag_word)
148  mutt_list_insert_tail(hflags, mutt_str_dup(flag_word));
149  *s = ctmp;
150  }
151 
152  /* note bad flags response */
153  if (*s != ')')
154  {
155  mutt_debug(LL_DEBUG1, "Unterminated FLAGS response: %s\n", s);
156  mutt_list_free(hflags);
157 
158  return NULL;
159  }
160 
161  s++;
162 
163  return s;
164 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_flag()

static void set_flag ( struct Mailbox m,
AclFlags  aclflag,
bool  flag,
const char *  str,
char *  flags,
size_t  flsize 
)
static

append str to flags if we currently have permission according to aclflag

Parameters
[in]mSelected Imap Mailbox
[in]aclflagPermissions, see AclFlags
[in]flagDoes the email have the flag set?
[in]strServer flag name
[out]flagsBuffer for server command
[in]flsizeLength of buffer

Definition at line 175 of file imap.c.

177 {
178  if (m->rights & aclflag)
179  if (flag && imap_has_flag(&imap_mdata_get(m)->flags, str))
180  mutt_str_cat(flags, flsize, str);
181 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_msg_set()

static int make_msg_set ( struct Mailbox m,
struct Buffer buf,
enum MessageType  flag,
bool  changed,
bool  invert,
int *  pos 
)
static

Make a message set.

Parameters
[in]mSelected Imap Mailbox
[in]bufBuffer to store message set
[in]flagFlags to match, e.g. MUTT_DELETED
[in]changedMatched messages that have been altered
[in]invertFlag matches should be inverted
[out]posCursor used for multiple calls to this function
Return values
numMessages in the set
Note
Headers must be in SORT_ORDER. See imap_exec_msgset() for args. Pos is an opaque pointer a la strtok(). It should be 0 at first call.

Definition at line 196 of file imap.c.

198 {
199  int count = 0; /* number of messages in message set */
200  unsigned int setstart = 0; /* start of current message range */
201  int n;
202  bool started = false;
203 
204  struct ImapAccountData *adata = imap_adata_get(m);
205  if (!adata || (adata->mailbox != m))
206  return -1;
207 
208  for (n = *pos; (n < m->msg_count) && (mutt_buffer_len(buf) < IMAP_MAX_CMDLEN); n++)
209  {
210  struct Email *e = m->emails[n];
211  if (!e)
212  break;
213  bool match = false; /* whether current message matches flag condition */
214  /* don't include pending expunged messages.
215  *
216  * TODO: can we unset active in cmd_parse_expunge() and
217  * cmd_parse_vanished() instead of checking for index != INT_MAX. */
218  if (e->active && (e->index != INT_MAX))
219  {
220  switch (flag)
221  {
222  case MUTT_DELETED:
223  if (e->deleted != imap_edata_get(e)->deleted)
224  match = invert ^ e->deleted;
225  break;
226  case MUTT_FLAG:
227  if (e->flagged != imap_edata_get(e)->flagged)
228  match = invert ^ e->flagged;
229  break;
230  case MUTT_OLD:
231  if (e->old != imap_edata_get(e)->old)
232  match = invert ^ e->old;
233  break;
234  case MUTT_READ:
235  if (e->read != imap_edata_get(e)->read)
236  match = invert ^ e->read;
237  break;
238  case MUTT_REPLIED:
239  if (e->replied != imap_edata_get(e)->replied)
240  match = invert ^ e->replied;
241  break;
242  case MUTT_TAG:
243  if (e->tagged)
244  match = true;
245  break;
246  case MUTT_TRASH:
247  if (e->deleted && !e->purge)
248  match = true;
249  break;
250  default:
251  break;
252  }
253  }
254 
255  if (match && (!changed || e->changed))
256  {
257  count++;
258  if (setstart == 0)
259  {
260  setstart = imap_edata_get(e)->uid;
261  if (started)
262  {
263  mutt_buffer_add_printf(buf, ",%u", imap_edata_get(e)->uid);
264  }
265  else
266  {
267  mutt_buffer_add_printf(buf, "%u", imap_edata_get(e)->uid);
268  started = true;
269  }
270  }
271  /* tie up if the last message also matches */
272  else if (n == (m->msg_count - 1))
273  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(e)->uid);
274  }
275  /* End current set if message doesn't match or we've reached the end
276  * of the mailbox via inactive messages following the last match. */
277  else if (setstart && (e->active || (n == adata->mailbox->msg_count - 1)))
278  {
279  if (imap_edata_get(m->emails[n - 1])->uid > setstart)
280  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(m->emails[n - 1])->uid);
281  setstart = 0;
282  }
283  }
284 
285  *pos = n;
286 
287  return count;
288 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compare_flags_for_copy()

static bool compare_flags_for_copy ( struct Email e)
static

Compare local flags against the server.

Parameters
eEmail
Return values
trueFlags have changed
falseFlags match cached server flags

The comparison of flags EXCLUDES the deleted flag.

Definition at line 298 of file imap.c.

299 {
300  struct ImapEmailData *edata = e->edata;
301 
302  if (e->read != edata->read)
303  return true;
304  if (e->old != edata->old)
305  return true;
306  if (e->flagged != edata->flagged)
307  return true;
308  if (e->replied != edata->replied)
309  return true;
310 
311  return false;
312 }
+ Here is the caller graph for this function:

◆ sync_helper()

static int sync_helper ( struct Mailbox m,
AclFlags  right,
enum MessageType  flag,
const char *  name 
)
static

Sync flag changes to the server.

Parameters
mSelected Imap Mailbox
rightACL, see AclFlags
flagNeoMutt flag, e.g. MUTT_DELETED
nameName of server flag
Return values
>=0Success, number of messages
-1Failure

Definition at line 323 of file imap.c.

325 {
326  int count = 0;
327  int rc;
328  char buf[1024];
329 
330  if (!m)
331  return -1;
332 
333  if ((m->rights & right) == 0)
334  return 0;
335 
336  if ((right == MUTT_ACL_WRITE) && !imap_has_flag(&imap_mdata_get(m)->flags, name))
337  return 0;
338 
339  snprintf(buf, sizeof(buf), "+FLAGS.SILENT (%s)", name);
340  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, false);
341  if (rc < 0)
342  return rc;
343  count += rc;
344 
345  buf[0] = '-';
346  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, true);
347  if (rc < 0)
348  return rc;
349  count += rc;
350 
351  return count;
352 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ longest_common_prefix()

static size_t longest_common_prefix ( char *  dest,
const char *  src,
size_t  start,
size_t  dlen 
)
static

Find longest prefix common to two strings.

Parameters
destDestination buffer
srcSource buffer
startStarting offset into string
dlenDestination buffer length
Return values
numLength of the common string

Trim dest to the length of the longest prefix it shares with src.

Definition at line 364 of file imap.c.

365 {
366  size_t pos = start;
367 
368  while ((pos < dlen) && dest[pos] && (dest[pos] == src[pos]))
369  pos++;
370  dest[pos] = '\0';
371 
372  return pos;
373 }
+ Here is the caller graph for this function:

◆ complete_hosts()

static int complete_hosts ( char *  buf,
size_t  buflen 
)
static

Look for completion matches for mailboxes.

Parameters
bufPartial mailbox name to complete
buflenLength of buffer
Return values
0Success
-1Failure

look for IMAP URLs to complete from defined mailboxes. Could be extended to complete over open connections and account/folder hooks too.

Definition at line 385 of file imap.c.

386 {
387  // struct Connection *conn = NULL;
388  int rc = -1;
389  size_t matchlen;
390 
391  matchlen = mutt_str_len(buf);
392  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
394  struct MailboxNode *np = NULL;
395  STAILQ_FOREACH(np, &ml, entries)
396  {
397  if (!mutt_str_startswith(mailbox_path(np->mailbox), buf))
398  continue;
399 
400  if (rc)
401  {
402  mutt_str_copy(buf, mailbox_path(np->mailbox), buflen);
403  rc = 0;
404  }
405  else
406  longest_common_prefix(buf, mailbox_path(np->mailbox), matchlen, buflen);
407  }
409 
410 #if 0
411  TAILQ_FOREACH(conn, mutt_socket_head(), entries)
412  {
413  struct Url url = { 0 };
414  char urlstr[1024];
415 
416  if (conn->account.type != MUTT_ACCT_TYPE_IMAP)
417  continue;
418 
419  mutt_account_tourl(&conn->account, &url);
420  /* FIXME: how to handle multiple users on the same host? */
421  url.user = NULL;
422  url.path = NULL;
423  url_tostring(&url, urlstr, sizeof(urlstr), U_NO_FLAGS);
424  if (mutt_strn_equal(buf, urlstr, matchlen))
425  {
426  if (rc)
427  {
428  mutt_str_copy(buf, urlstr, buflen);
429  rc = 0;
430  }
431  else
432  longest_common_prefix(buf, urlstr, matchlen, buflen);
433  }
434  }
435 #endif
436 
437  return rc;
438 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

448 {
449  char buf[2048], mbox[1024];
450 
451  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), mailbox);
452  snprintf(buf, sizeof(buf), "CREATE %s", mbox);
453 
454  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
455  {
456  mutt_error(_("CREATE failed: %s"), imap_cmd_trailer(adata));
457  return -1;
458  }
459 
460  return 0;
461 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_access()

int imap_access ( const char *  path)

Check permissions on an IMAP mailbox with a new connection.

Parameters
pathMailbox path
Return values
0Success
<0Failure

TODO: ACL checks. Right now we assume if it exists we can mess with it. TODO: This method should take a Mailbox as parameter to be able to reuse the existing connection.

Definition at line 473 of file imap.c.

474 {
475  if (imap_path_status(path, false) >= 0)
476  return 0;
477  return -1;
478 }
+ 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 488 of file imap.c.

489 {
490  char oldmbox[1024];
491  char newmbox[1024];
492  int rc = 0;
493 
494  imap_munge_mbox_name(adata->unicode, oldmbox, sizeof(oldmbox), oldname);
495  imap_munge_mbox_name(adata->unicode, newmbox, sizeof(newmbox), newname);
496 
497  struct Buffer *buf = mutt_buffer_pool_get();
498  mutt_buffer_printf(buf, "RENAME %s %s", oldmbox, newmbox);
499 
501  rc = -1;
502 
504 
505  return rc;
506 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_delete_mailbox()

int imap_delete_mailbox ( struct Mailbox m,
char *  path 
)

Delete a mailbox.

Parameters
mMailbox
pathname of the mailbox to delete
Return values
0Success
-1Failure

Definition at line 515 of file imap.c.

516 {
517  char buf[PATH_MAX + 7];
518  char mbox[PATH_MAX];
519  struct Url *url = url_parse(path);
520 
521  struct ImapAccountData *adata = imap_adata_get(m);
522  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), url->path);
523  url_free(&url);
524  snprintf(buf, sizeof(buf), "DELETE %s", mbox);
526  return -1;
527 
528  return 0;
529 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_logout()

static void imap_logout ( struct ImapAccountData adata)
static

Gracefully log out of server.

Parameters
adataImap Account data

Definition at line 535 of file imap.c.

536 {
537  /* we set status here to let imap_handle_untagged know we _expect_ to
538  * receive a bye response (so it doesn't freak out and close the conn) */
539  if (adata->state == IMAP_DISCONNECTED)
540  {
541  return;
542  }
543 
544  adata->status = IMAP_BYE;
545  imap_cmd_start(adata, "LOGOUT");
546  if ((C_ImapPollTimeout <= 0) || (mutt_socket_poll(adata->conn, C_ImapPollTimeout) != 0))
547  {
549  ; // do nothing
550  }
551  mutt_socket_close(adata->conn);
552  adata->state = IMAP_DISCONNECTED;
553 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_logout_all()

void imap_logout_all ( void  )

close all open connections

Quick and dirty until we can make sure we've got all the context we need.

Definition at line 560 of file imap.c.

561 {
562  struct Account *np = NULL;
563  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
564  {
565  if (np->type != MUTT_IMAP)
566  continue;
567 
568  struct ImapAccountData *adata = np->adata;
569  if (!adata)
570  continue;
571 
572  struct Connection *conn = adata->conn;
573  if (!conn || (conn->fd < 0))
574  continue;
575 
576  mutt_message(_("Closing connection to %s..."), conn->account.host);
577  imap_logout(np->adata);
579  }
580 }
+ 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 596 of file imap.c.

598 {
599  char c;
600  bool r = false;
601  struct Buffer buf = { 0 }; // Do not allocate, maybe it won't be used
602 
604  mutt_buffer_alloc(&buf, bytes + 10);
605 
606  mutt_debug(LL_DEBUG2, "reading %ld bytes\n", bytes);
607 
608  for (unsigned long pos = 0; pos < bytes; pos++)
609  {
610  if (mutt_socket_readchar(adata->conn, &c) != 1)
611  {
612  mutt_debug(LL_DEBUG1, "error during read, %ld bytes read\n", pos);
613  adata->status = IMAP_FATAL;
614 
615  mutt_buffer_dealloc(&buf);
616  return -1;
617  }
618 
619  if (r && (c != '\n'))
620  fputc('\r', fp);
621 
622  if (c == '\r')
623  {
624  r = true;
625  continue;
626  }
627  else
628  r = false;
629 
630  fputc(c, fp);
631 
632  if (pbar && !(pos % 1024))
633  mutt_progress_update(pbar, pos, -1);
635  mutt_buffer_addch(&buf, c);
636  }
637 
639  {
640  mutt_debug(IMAP_LOG_LTRL, "\n%s", buf.data);
641  mutt_buffer_dealloc(&buf);
642  }
643  return 0;
644 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_notify_delete_email()

void imap_notify_delete_email ( struct Mailbox m,
struct Email e 
)

Inform IMAP that an Email has been deleted.

Parameters
mMailbox
eEmail

Definition at line 651 of file imap.c.

652 {
653  struct ImapMboxData *mdata = imap_mdata_get(m);
654  struct ImapEmailData *edata = imap_edata_get(e);
655 
656  if (!mdata || !edata)
657  return;
658 
659  imap_msn_remove(&mdata->msn, edata->msn - 1);
660  edata->msn = 0;
661 }
+ 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 671 of file imap.c.

672 {
673  struct ImapAccountData *adata = imap_adata_get(m);
674  struct ImapMboxData *mdata = imap_mdata_get(m);
675  if (!adata || !mdata)
676  return;
677 
678  struct Email *e = NULL;
679 
680 #ifdef USE_HCACHE
681  imap_hcache_open(adata, mdata);
682 #endif
683 
684  for (int i = 0; i < m->msg_count; i++)
685  {
686  e = m->emails[i];
687  if (!e)
688  break;
689 
690  if (e->index == INT_MAX)
691  {
692  mutt_debug(LL_DEBUG2, "Expunging message UID %u\n", imap_edata_get(e)->uid);
693 
694  e->deleted = true;
695 
696  imap_cache_del(m, e);
697 #ifdef USE_HCACHE
698  imap_hcache_del(mdata, imap_edata_get(e)->uid);
699 #endif
700 
701  mutt_hash_int_delete(mdata->uid_hash, imap_edata_get(e)->uid, e);
702 
703  imap_edata_free((void **) &e->edata);
704  }
705  else
706  {
707  /* NeoMutt has several places where it turns off e->active as a
708  * hack. For example to avoid FLAG updates, or to exclude from
709  * imap_exec_msgset.
710  *
711  * Unfortunately, when a reopen is allowed and the IMAP_EXPUNGE_PENDING
712  * flag becomes set (e.g. a flag update to a modified header),
713  * this function will be called by imap_cmd_finish().
714  *
715  * The ctx_update_tables() will free and remove these "inactive" headers,
716  * despite that an EXPUNGE was not received for them.
717  * This would result in memory leaks and segfaults due to dangling
718  * pointers in the msn_index and uid_hash.
719  *
720  * So this is another hack to work around the hacks. We don't want to
721  * remove the messages, so make sure active is on. */
722  e->active = true;
723  }
724  }
725 
726 #ifdef USE_HCACHE
727  imap_hcache_close(mdata);
728 #endif
729 
732 }
+ 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 740 of file imap.c.

741 {
742  if (mutt_socket_open(adata->conn) < 0)
743  return -1;
744 
745  adata->state = IMAP_CONNECTED;
746 
747  if (imap_cmd_step(adata) != IMAP_RES_OK)
748  {
749  imap_close_connection(adata);
750  return -1;
751  }
752 
753  if (mutt_istr_startswith(adata->buf, "* OK"))
754  {
755  if (!mutt_istr_startswith(adata->buf, "* OK [CAPABILITY") && check_capabilities(adata))
756  {
757  goto bail;
758  }
759 #ifdef USE_SSL
760  /* Attempt STARTTLS if available and desired. */
761  if ((adata->conn->ssf == 0) && (C_SslForceTls || (adata->capabilities & IMAP_CAP_STARTTLS)))
762  {
763  enum QuadOption ans;
764 
765  if (C_SslForceTls)
766  ans = MUTT_YES;
767  else if ((ans = query_quadoption(C_SslStarttls,
768  _("Secure connection with TLS?"))) == MUTT_ABORT)
769  {
770  goto bail;
771  }
772  if (ans == MUTT_YES)
773  {
774  enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_SINGLE);
775  // Clear any data after the STARTTLS acknowledgement
776  mutt_socket_empty(adata->conn);
777 
778  if (rc == IMAP_EXEC_FATAL)
779  goto bail;
780  if (rc != IMAP_EXEC_ERROR)
781  {
782  if (mutt_ssl_starttls(adata->conn))
783  {
784  mutt_error(_("Could not negotiate TLS connection"));
785  goto bail;
786  }
787  else
788  {
789  /* RFC2595 demands we recheck CAPABILITY after TLS completes. */
790  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS))
791  goto bail;
792  }
793  }
794  }
795  }
796 
797  if (C_SslForceTls && (adata->conn->ssf == 0))
798  {
799  mutt_error(_("Encrypted connection unavailable"));
800  goto bail;
801  }
802 #endif
803  }
804  else if (mutt_istr_startswith(adata->buf, "* PREAUTH"))
805  {
806 #ifdef USE_SSL
807  /* Unless using a secure $tunnel, an unencrypted PREAUTH response may be a
808  * MITM attack. The only way to stop "STARTTLS" MITM attacks is via
809  * $ssl_force_tls: an attacker can easily spoof "* OK" and strip the
810  * STARTTLS capability. So consult $ssl_force_tls, not $ssl_starttls, to
811  * decide whether to abort. Note that if using $tunnel and
812  * $tunnel_is_secure, adata->conn->ssf will be set to 1. */
813  if ((adata->conn->ssf == 0) && C_SslForceTls)
814  {
815  mutt_error(_("Encrypted connection unavailable"));
816  goto bail;
817  }
818 #endif
819 
820  adata->state = IMAP_AUTHENTICATED;
821  if (check_capabilities(adata) != 0)
822  goto bail;
823  FREE(&adata->capstr);
824  }
825  else
826  {
827  imap_error("imap_open_connection()", adata->buf);
828  goto bail;
829  }
830 
831  return 0;
832 
833 bail:
834  imap_close_connection(adata);
835  FREE(&adata->capstr);
836  return -1;
837 }
+ 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 843 of file imap.c.

844 {
845  if (adata->state != IMAP_DISCONNECTED)
846  {
847  mutt_socket_close(adata->conn);
848  adata->state = IMAP_DISCONNECTED;
849  }
850  adata->seqno = 0;
851  adata->nextcmd = 0;
852  adata->lastcmd = 0;
853  adata->status = 0;
854  memset(adata->cmds, 0, sizeof(struct ImapCommand) * adata->cmdslots);
855 }
+ 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 868 of file imap.c.

869 {
870  if (STAILQ_EMPTY(flag_list))
871  return false;
872 
873  const size_t flaglen = mutt_str_len(flag);
874  struct ListNode *np = NULL;
875  STAILQ_FOREACH(np, flag_list, entries)
876  {
877  const size_t nplen = strlen(np->data);
878  if ((flaglen >= nplen) && ((flag[nplen] == '\0') || (flag[nplen] == ' ')) &&
879  mutt_istrn_equal(np->data, flag, nplen))
880  {
881  return true;
882  }
883 
884  if (mutt_str_equal(np->data, "\\*"))
885  return true;
886  }
887 
888  return false;
889 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compare_uid()

static int compare_uid ( const void *  a,
const void *  b 
)
static

Compare two Emails by UID - Implements sort_t.

Definition at line 894 of file imap.c.

895 {
896  const struct Email *ea = *(struct Email const *const *) a;
897  const struct Email *eb = *(struct Email const *const *) b;
898  return imap_edata_get((struct Email *) ea)->uid -
899  imap_edata_get((struct Email *) eb)->uid;
900 }
+ 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,
enum MessageType  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 917 of file imap.c.

919 {
920  struct ImapAccountData *adata = imap_adata_get(m);
921  if (!adata || (adata->mailbox != m))
922  return -1;
923 
924  struct Email **emails = NULL;
925  short oldsort;
926  int pos;
927  int rc;
928  int count = 0;
929 
930  struct Buffer cmd = mutt_buffer_make(0);
931 
932  /* We make a copy of the headers just in case resorting doesn't give
933  exactly the original order (duplicate messages?), because other parts of
934  the ctx are tied to the header order. This may be overkill. */
935  oldsort = C_Sort;
936  if (C_Sort != SORT_ORDER)
937  {
938  emails = m->emails;
939  // We overcommit here, just in case new mail arrives whilst we're sync-ing
940  m->emails = mutt_mem_malloc(m->email_max * sizeof(struct Email *));
941  memcpy(m->emails, emails, m->email_max * sizeof(struct Email *));
942 
943  C_Sort = SORT_ORDER;
944  qsort(m->emails, m->msg_count, sizeof(struct Email *), compare_uid);
945  }
946 
947  pos = 0;
948 
949  do
950  {
951  mutt_buffer_reset(&cmd);
952  mutt_buffer_add_printf(&cmd, "%s ", pre);
953  rc = make_msg_set(m, &cmd, flag, changed, invert, &pos);
954  if (rc > 0)
955  {
956  mutt_buffer_add_printf(&cmd, " %s", post);
957  if (imap_exec(adata, cmd.data, IMAP_CMD_QUEUE) != IMAP_EXEC_SUCCESS)
958  {
959  rc = -1;
960  goto out;
961  }
962  count += rc;
963  }
964  } while (rc > 0);
965 
966  rc = count;
967 
968 out:
969  mutt_buffer_dealloc(&cmd);
970  if (oldsort != C_Sort)
971  {
972  C_Sort = oldsort;
973  FREE(&m->emails);
974  m->emails = emails;
975  }
976 
977  return rc;
978 }
+ 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 995 of file imap.c.

997 {
998  struct ImapAccountData *adata = imap_adata_get(m);
999  if (!adata || (adata->mailbox != m))
1000  return -1;
1001 
1002  char flags[1024];
1003  char *tags = NULL;
1004  char uid[11];
1005 
1006  if (!compare_flags_for_copy(e))
1007  {
1008  if (e->deleted == imap_edata_get(e)->deleted)
1009  e->changed = false;
1010  return 0;
1011  }
1012 
1013  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
1014  mutt_buffer_reset(cmd);
1015  mutt_buffer_addstr(cmd, "UID STORE ");
1016  mutt_buffer_addstr(cmd, uid);
1017 
1018  flags[0] = '\0';
1019 
1020  set_flag(m, MUTT_ACL_SEEN, e->read, "\\Seen ", flags, sizeof(flags));
1021  set_flag(m, MUTT_ACL_WRITE, e->old, "Old ", flags, sizeof(flags));
1022  set_flag(m, MUTT_ACL_WRITE, e->flagged, "\\Flagged ", flags, sizeof(flags));
1023  set_flag(m, MUTT_ACL_WRITE, e->replied, "\\Answered ", flags, sizeof(flags));
1024  set_flag(m, MUTT_ACL_DELETE, imap_edata_get(e)->deleted, "\\Deleted ", flags,
1025  sizeof(flags));
1026 
1027  if (m->rights & MUTT_ACL_WRITE)
1028  {
1029  /* restore system flags */
1030  if (imap_edata_get(e)->flags_system)
1031  mutt_str_cat(flags, sizeof(flags), imap_edata_get(e)->flags_system);
1032  /* set custom flags */
1033  tags = driver_tags_get_with_hidden(&e->tags);
1034  if (tags)
1035  {
1036  mutt_str_cat(flags, sizeof(flags), tags);
1037  FREE(&tags);
1038  }
1039  }
1040 
1042 
1043  /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
1044  * explicitly revoke all system flags (if we have permission) */
1045  if (*flags == '\0')
1046  {
1047  set_flag(m, MUTT_ACL_SEEN, true, "\\Seen ", flags, sizeof(flags));
1048  set_flag(m, MUTT_ACL_WRITE, true, "Old ", flags, sizeof(flags));
1049  set_flag(m, MUTT_ACL_WRITE, true, "\\Flagged ", flags, sizeof(flags));
1050  set_flag(m, MUTT_ACL_WRITE, true, "\\Answered ", flags, sizeof(flags));
1051  set_flag(m, MUTT_ACL_DELETE, !imap_edata_get(e)->deleted, "\\Deleted ",
1052  flags, sizeof(flags));
1053 
1054  /* erase custom flags */
1055  if ((m->rights & MUTT_ACL_WRITE) && imap_edata_get(e)->flags_remote)
1056  mutt_str_cat(flags, sizeof(flags), imap_edata_get(e)->flags_remote);
1057 
1059 
1060  mutt_buffer_addstr(cmd, " -FLAGS.SILENT (");
1061  }
1062  else
1063  mutt_buffer_addstr(cmd, " FLAGS.SILENT (");
1064 
1065  mutt_buffer_addstr(cmd, flags);
1066  mutt_buffer_addstr(cmd, ")");
1067 
1068  /* after all this it's still possible to have no flags, if you
1069  * have no ACL rights */
1070  if (*flags && (imap_exec(adata, cmd->data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS) &&
1071  err_continue && (*err_continue != MUTT_YES))
1072  {
1073  *err_continue = imap_continue("imap_sync_message: STORE failed", adata->buf);
1074  if (*err_continue != MUTT_YES)
1075  return -1;
1076  }
1077 
1078  /* server have now the updated flags */
1079  FREE(&imap_edata_get(e)->flags_remote);
1081 
1082  if (e->deleted == imap_edata_get(e)->deleted)
1083  e->changed = false;
1084 
1085  return 0;
1086 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_check_mailbox()

enum MxStatus imap_check_mailbox ( struct Mailbox m,
bool  force 
)

use the NOOP or IDLE command to poll for new mail

Parameters
mMailbox
forceDon't wait return enum MxStatus

Definition at line 1094 of file imap.c.

1095 {
1096  if (!m || !m->account)
1097  return MX_STATUS_ERROR;
1098 
1099  struct ImapAccountData *adata = imap_adata_get(m);
1100  struct ImapMboxData *mdata = imap_mdata_get(m);
1101 
1102  /* overload keyboard timeout to avoid many mailbox checks in a row.
1103  * Most users don't like having to wait exactly when they press a key. */
1104  int rc = 0;
1105 
1106  /* try IDLE first, unless force is set */
1107  if (!force && C_ImapIdle && (adata->capabilities & IMAP_CAP_IDLE) &&
1108  ((adata->state != IMAP_IDLE) || (mutt_date_epoch() >= adata->lastread + C_ImapKeepalive)))
1109  {
1110  if (imap_cmd_idle(adata) < 0)
1111  return MX_STATUS_ERROR;
1112  }
1113  if (adata->state == IMAP_IDLE)
1114  {
1115  while ((rc = mutt_socket_poll(adata->conn, 0)) > 0)
1116  {
1117  if (imap_cmd_step(adata) != IMAP_RES_CONTINUE)
1118  {
1119  mutt_debug(LL_DEBUG1, "Error reading IDLE response\n");
1120  return MX_STATUS_ERROR;
1121  }
1122  }
1123  if (rc < 0)
1124  {
1125  mutt_debug(LL_DEBUG1, "Poll failed, disabling IDLE\n");
1126  adata->capabilities &= ~IMAP_CAP_IDLE; // Clear the flag
1127  }
1128  }
1129 
1130  if ((force || ((adata->state != IMAP_IDLE) &&
1131  (mutt_date_epoch() >= adata->lastread + C_Timeout))) &&
1132  (imap_exec(adata, "NOOP", IMAP_CMD_POLL) != IMAP_EXEC_SUCCESS))
1133  {
1134  return MX_STATUS_ERROR;
1135  }
1136 
1137  /* We call this even when we haven't run NOOP in case we have pending
1138  * changes to process, since we can reopen here. */
1139  imap_cmd_finish(adata);
1140 
1141  enum MxStatus check = MX_STATUS_OK;
1142  if (mdata->check_status & IMAP_EXPUNGE_PENDING)
1143  check = MX_STATUS_REOPENED;
1144  else if (mdata->check_status & IMAP_NEWMAIL_PENDING)
1145  check = MX_STATUS_NEW_MAIL;
1146  else if (mdata->check_status & IMAP_FLAGS_PENDING)
1147  check = MX_STATUS_FLAGS;
1148  else if (rc < 0)
1149  check = MX_STATUS_ERROR;
1150 
1151  mdata->check_status = IMAP_OPEN_NO_FLAGS;
1152 
1153  return check;
1154 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_status()

static int imap_status ( struct ImapAccountData adata,
struct ImapMboxData mdata,
bool  queue 
)
static

Refresh the number of total and new messages.

Parameters
adataIMAP Account data
mdataIMAP Mailbox data
queueQueue the STATUS command
Return values
numTotal number of messages

Definition at line 1163 of file imap.c.

1164 {
1165  char *uidvalidity_flag = NULL;
1166  char cmd[2048];
1167 
1168  if (!adata || !mdata)
1169  return -1;
1170 
1171  /* Don't issue STATUS on the selected mailbox, it will be NOOPed or
1172  * IDLEd elsewhere.
1173  * adata->mailbox may be NULL for connections other than the current
1174  * mailbox's. */
1175  if (adata->mailbox && (adata->mailbox->mdata == mdata))
1176  {
1177  adata->mailbox->has_new = false;
1178  return mdata->messages;
1179  }
1180 
1181  if (adata->capabilities & IMAP_CAP_IMAP4REV1)
1182  uidvalidity_flag = "UIDVALIDITY";
1183  else if (adata->capabilities & IMAP_CAP_STATUS)
1184  uidvalidity_flag = "UID-VALIDITY";
1185  else
1186  {
1187  mutt_debug(LL_DEBUG2, "Server doesn't support STATUS\n");
1188  return -1;
1189  }
1190 
1191  snprintf(cmd, sizeof(cmd), "STATUS %s (UIDNEXT %s UNSEEN RECENT MESSAGES)",
1192  mdata->munge_name, uidvalidity_flag);
1193 
1194  int rc = imap_exec(adata, cmd, queue ? IMAP_CMD_QUEUE : IMAP_CMD_NO_FLAGS | IMAP_CMD_POLL);
1195  if (rc < 0)
1196  {
1197  mutt_debug(LL_DEBUG1, "Error queueing command\n");
1198  return rc;
1199  }
1200  return mdata->messages;
1201 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mbox_check_stats()

static enum MxStatus imap_mbox_check_stats ( struct Mailbox m,
uint8_t  flags 
)
static

Check the Mailbox statistics - Implements MxOps::mbox_check_stats()

Definition at line 1206 of file imap.c.

1207 {
1208  const int new_msgs = imap_mailbox_status(m, true);
1209  if (new_msgs == -1)
1210  return MX_STATUS_ERROR;
1211  if (new_msgs == 0)
1212  return MX_STATUS_OK;
1213  return MX_STATUS_NEW_MAIL;
1214 }
+ Here is the call graph for this function:

◆ imap_path_status()

int imap_path_status ( const char *  path,
bool  queue 
)

Refresh the number of total and new messages.

Parameters
pathMailbox path
queueQueue the STATUS command
Return values
numTotal number of messages

Definition at line 1222 of file imap.c.

1223 {
1224  struct Mailbox *m = mx_mbox_find2(path);
1225 
1226  const bool is_temp = !m;
1227  if (is_temp)
1228  {
1229  m = mx_path_resolve(path);
1230  if (!mx_mbox_ac_link(m))
1231  {
1232  mailbox_free(&m);
1233  return 0;
1234  }
1235  }
1236 
1237  int rc = imap_mailbox_status(m, queue);
1238 
1239  if (is_temp)
1240  {
1241  mx_ac_remove(m);
1242  }
1243 
1244  return rc;
1245 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mailbox_status()

int imap_mailbox_status ( struct Mailbox m,
bool  queue 
)

Refresh the number of total and new messages.

Parameters
mMailbox
queueQueue the STATUS command
Return values
numTotal number of messages
-1Error
Note
Prepare the mailbox if we are not connected

Definition at line 1256 of file imap.c.

1257 {
1258  struct ImapAccountData *adata = imap_adata_get(m);
1259  struct ImapMboxData *mdata = imap_mdata_get(m);
1260  if (!adata || !mdata)
1261  return -1;
1262  return imap_status(adata, mdata, queue);
1263 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_subscribe()

int imap_subscribe ( char *  path,
bool  subscribe 
)

Subscribe to a mailbox.

Parameters
pathMailbox path
subscribeTrue: subscribe, false: unsubscribe
Return values
0Success
-1Failure

Definition at line 1272 of file imap.c.

1273 {
1274  struct ImapAccountData *adata = NULL;
1275  struct ImapMboxData *mdata = NULL;
1276  char buf[2048];
1277  struct Buffer err;
1278 
1279  if (imap_adata_find(path, &adata, &mdata) < 0)
1280  return -1;
1281 
1282  if (subscribe)
1283  mutt_message(_("Subscribing to %s..."), mdata->name);
1284  else
1285  mutt_message(_("Unsubscribing from %s..."), mdata->name);
1286 
1287  snprintf(buf, sizeof(buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mdata->munge_name);
1288 
1289  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1290  {
1291  imap_mdata_free((void *) &mdata);
1292  return -1;
1293  }
1294 
1296  {
1297  char mbox[1024];
1298  mutt_buffer_init(&err);
1299  err.dsize = 256;
1300  err.data = mutt_mem_malloc(err.dsize);
1301  size_t len = snprintf(mbox, sizeof(mbox), "%smailboxes ", subscribe ? "" : "un");
1302  imap_quote_string(mbox + len, sizeof(mbox) - len, path, true);
1303  if (mutt_parse_rc_line(mbox, &err))
1304  mutt_debug(LL_DEBUG1, "Error adding subscribed mailbox: %s\n", err.data);
1305  FREE(&err.data);
1306  }
1307 
1308  if (subscribe)
1309  mutt_message(_("Subscribed to %s"), mdata->name);
1310  else
1311  mutt_message(_("Unsubscribed from %s"), mdata->name);
1312  imap_mdata_free((void *) &mdata);
1313  return 0;
1314 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_complete()

int imap_complete ( char *  buf,
size_t  buflen,
const char *  path 
)

Try to complete an IMAP folder path.

Parameters
bufBuffer for result
buflenLength of buffer
pathPartial mailbox name to complete
Return values
0Success
-1Failure

Given a partial IMAP folder path, return a string which adds as much to the path as is unique

Definition at line 1327 of file imap.c.

1328 {
1329  struct ImapAccountData *adata = NULL;
1330  struct ImapMboxData *mdata = NULL;
1331  char tmp[2048];
1332  struct ImapList listresp = { 0 };
1333  char completion[1024];
1334  int clen;
1335  size_t matchlen = 0;
1336  int completions = 0;
1337  int rc;
1338 
1339  if (imap_adata_find(path, &adata, &mdata) < 0)
1340  {
1341  mutt_str_copy(buf, path, buflen);
1342  return complete_hosts(buf, buflen);
1343  }
1344 
1345  /* fire off command */
1346  snprintf(tmp, sizeof(tmp), "%s \"\" \"%s%%\"",
1347  C_ImapListSubscribed ? "LSUB" : "LIST", mdata->real_name);
1348 
1349  imap_cmd_start(adata, tmp);
1350 
1351  /* and see what the results are */
1352  mutt_str_copy(completion, mdata->name, sizeof(completion));
1353  imap_mdata_free((void *) &mdata);
1354 
1355  adata->cmdresult = &listresp;
1356  do
1357  {
1358  listresp.name = NULL;
1359  rc = imap_cmd_step(adata);
1360 
1361  if ((rc == IMAP_RES_CONTINUE) && listresp.name)
1362  {
1363  /* if the folder isn't selectable, append delimiter to force browse
1364  * to enter it on second tab. */
1365  if (listresp.noselect)
1366  {
1367  clen = strlen(listresp.name);
1368  listresp.name[clen++] = listresp.delim;
1369  listresp.name[clen] = '\0';
1370  }
1371  /* copy in first word */
1372  if (!completions)
1373  {
1374  mutt_str_copy(completion, listresp.name, sizeof(completion));
1375  matchlen = strlen(completion);
1376  completions++;
1377  continue;
1378  }
1379 
1380  matchlen = longest_common_prefix(completion, listresp.name, 0, matchlen);
1381  completions++;
1382  }
1383  } while (rc == IMAP_RES_CONTINUE);
1384  adata->cmdresult = NULL;
1385 
1386  if (completions)
1387  {
1388  /* reformat output */
1389  imap_qualify_path(buf, buflen, &adata->conn->account, completion);
1390  mutt_pretty_mailbox(buf, buflen);
1391  return 0;
1392  }
1393 
1394  return -1;
1395 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_fast_trash()

int imap_fast_trash ( struct Mailbox m,
char *  dest 
)

Use server COPY command to copy deleted messages to trash.

Parameters
mMailbox
destMailbox to move to
Return values
-1Error
0Success
1Non-fatal error - try fetch/append

Definition at line 1405 of file imap.c.

1406 {
1407  char prompt[1024];
1408  int rc = -1;
1409  bool triedcreate = false;
1410  enum QuadOption err_continue = MUTT_NO;
1411 
1412  struct ImapAccountData *adata = imap_adata_get(m);
1413  struct ImapAccountData *dest_adata = NULL;
1414  struct ImapMboxData *dest_mdata = NULL;
1415 
1416  if (imap_adata_find(dest, &dest_adata, &dest_mdata) < 0)
1417  return -1;
1418 
1419  struct Buffer sync_cmd = mutt_buffer_make(0);
1420 
1421  /* check that the save-to folder is in the same account */
1422  if (!imap_account_match(&(adata->conn->account), &(dest_adata->conn->account)))
1423  {
1424  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1425  goto out;
1426  }
1427 
1428  for (int i = 0; i < m->msg_count; i++)
1429  {
1430  struct Email *e = m->emails[i];
1431  if (!e)
1432  break;
1433  if (e->active && e->changed && e->deleted && !e->purge)
1434  {
1435  rc = imap_sync_message_for_copy(m, e, &sync_cmd, &err_continue);
1436  if (rc < 0)
1437  {
1438  mutt_debug(LL_DEBUG1, "could not sync\n");
1439  goto out;
1440  }
1441  }
1442  }
1443 
1444  /* loop in case of TRYCREATE */
1445  do
1446  {
1447  rc = imap_exec_msgset(m, "UID COPY", dest_mdata->munge_name, MUTT_TRASH, false, false);
1448  if (rc == 0)
1449  {
1450  mutt_debug(LL_DEBUG1, "No messages to trash\n");
1451  rc = -1;
1452  goto out;
1453  }
1454  else if (rc < 0)
1455  {
1456  mutt_debug(LL_DEBUG1, "could not queue copy\n");
1457  goto out;
1458  }
1459  else if (m->verbose)
1460  {
1461  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1462  rc, dest_mdata->name);
1463  }
1464 
1465  /* let's get it on */
1466  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1467  if (rc == IMAP_EXEC_ERROR)
1468  {
1469  if (triedcreate)
1470  {
1471  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", dest_mdata->name);
1472  break;
1473  }
1474  /* bail out if command failed for reasons other than nonexistent target */
1475  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1476  break;
1477  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1478  snprintf(prompt, sizeof(prompt), _("Create %s?"), dest_mdata->name);
1479  if (C_ConfirmCreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1480  {
1481  mutt_clear_error();
1482  goto out;
1483  }
1484  if (imap_create_mailbox(adata, dest_mdata->name) < 0)
1485  break;
1486  triedcreate = true;
1487  }
1488  } while (rc == IMAP_EXEC_ERROR);
1489 
1490  if (rc != IMAP_EXEC_SUCCESS)
1491  {
1492  imap_error("imap_fast_trash", adata->buf);
1493  goto out;
1494  }
1495 
1496  rc = IMAP_EXEC_SUCCESS;
1497 
1498 out:
1499  mutt_buffer_dealloc(&sync_cmd);
1500  imap_mdata_free((void *) &dest_mdata);
1501 
1502  return ((rc == IMAP_EXEC_SUCCESS) ? 0 : -1);
1503 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_sync_mailbox()

enum MxStatus imap_sync_mailbox ( struct Mailbox m,
bool  expunge,
bool  close 
)

Sync all the changes to the server.

Parameters
mMailbox
expungeif true do expunge
closeif true we move imap state to CLOSE
Return values
enumMxStatus
Note
The flag retvals come from a call to imap_check_mailbox()

Definition at line 1514 of file imap.c.

1515 {
1516  if (!m)
1517  return -1;
1518 
1519  struct Email **emails = NULL;
1520  int oldsort;
1521  int rc;
1522 
1523  struct ImapAccountData *adata = imap_adata_get(m);
1524  struct ImapMboxData *mdata = imap_mdata_get(m);
1525 
1526  if (adata->state < IMAP_SELECTED)
1527  {
1528  mutt_debug(LL_DEBUG2, "no mailbox selected\n");
1529  return -1;
1530  }
1531 
1532  /* This function is only called when the calling code expects the context
1533  * to be changed. */
1534  imap_allow_reopen(m);
1535 
1536  enum MxStatus check = imap_check_mailbox(m, false);
1537  if (check == MX_STATUS_ERROR)
1538  return check;
1539 
1540  /* if we are expunging anyway, we can do deleted messages very quickly... */
1541  if (expunge && (m->rights & MUTT_ACL_DELETE))
1542  {
1543  rc = imap_exec_msgset(m, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
1544  MUTT_DELETED, true, false);
1545  if (rc < 0)
1546  {
1547  mutt_error(_("Expunge failed"));
1548  return rc;
1549  }
1550 
1551  if (rc > 0)
1552  {
1553  /* mark these messages as unchanged so second pass ignores them. Done
1554  * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
1555  for (int i = 0; i < m->msg_count; i++)
1556  {
1557  struct Email *e = m->emails[i];
1558  if (!e)
1559  break;
1560  if (e->deleted && e->changed)
1561  e->active = false;
1562  }
1563  if (m->verbose)
1564  {
1565  mutt_message(ngettext("Marking %d message deleted...",
1566  "Marking %d messages deleted...", rc),
1567  rc);
1568  }
1569  }
1570  }
1571 
1572 #ifdef USE_HCACHE
1573  imap_hcache_open(adata, mdata);
1574 #endif
1575 
1576  /* save messages with real (non-flag) changes */
1577  for (int i = 0; i < m->msg_count; i++)
1578  {
1579  struct Email *e = m->emails[i];
1580  if (!e)
1581  break;
1582 
1583  if (e->deleted)
1584  {
1585  imap_cache_del(m, e);
1586 #ifdef USE_HCACHE
1587  imap_hcache_del(mdata, imap_edata_get(e)->uid);
1588 #endif
1589  }
1590 
1591  if (e->active && e->changed)
1592  {
1593 #ifdef USE_HCACHE
1594  imap_hcache_put(mdata, e);
1595 #endif
1596  /* if the message has been rethreaded or attachments have been deleted
1597  * we delete the message and reupload it.
1598  * This works better if we're expunging, of course. */
1599  /* TODO: why the e->env check? */
1600  if ((e->env && e->env->changed) || e->attach_del)
1601  {
1602  /* L10N: The plural is chosen by the last %d, i.e. the total number */
1603  if (m->verbose)
1604  {
1605  mutt_message(ngettext("Saving changed message... [%d/%d]",
1606  "Saving changed messages... [%d/%d]", m->msg_count),
1607  i + 1, m->msg_count);
1608  }
1609  bool save_append = m->append;
1610  m->append = true;
1612  m->append = save_append;
1613  /* TODO: why the check for e->env? Is this possible? */
1614  if (e->env)
1615  e->env->changed = 0;
1616  }
1617  }
1618  }
1619 
1620 #ifdef USE_HCACHE
1621  imap_hcache_close(mdata);
1622 #endif
1623 
1624  /* presort here to avoid doing 10 resorts in imap_exec_msgset */
1625  oldsort = C_Sort;
1626  if (C_Sort != SORT_ORDER)
1627  {
1628  emails = m->emails;
1629  m->emails = mutt_mem_malloc(m->msg_count * sizeof(struct Email *));
1630  memcpy(m->emails, emails, m->msg_count * sizeof(struct Email *));
1631 
1632  C_Sort = SORT_ORDER;
1633  qsort(m->emails, m->msg_count, sizeof(struct Email *), mutt_get_sort_func(SORT_ORDER));
1634  }
1635 
1636  rc = sync_helper(m, MUTT_ACL_DELETE, MUTT_DELETED, "\\Deleted");
1637  if (rc >= 0)
1638  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_FLAG, "\\Flagged");
1639  if (rc >= 0)
1640  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_OLD, "Old");
1641  if (rc >= 0)
1642  rc |= sync_helper(m, MUTT_ACL_SEEN, MUTT_READ, "\\Seen");
1643  if (rc >= 0)
1644  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
1645 
1646  if (oldsort != C_Sort)
1647  {
1648  C_Sort = oldsort;
1649  FREE(&m->emails);
1650  m->emails = emails;
1651  }
1652 
1653  /* Flush the queued flags if any were changed in sync_helper. */
1654  if (rc > 0)
1655  if (imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1656  rc = -1;
1657 
1658  if (rc < 0)
1659  {
1660  if (close)
1661  {
1662  if (mutt_yesorno(_("Error saving flags. Close anyway?"), MUTT_NO) == MUTT_YES)
1663  {
1664  adata->state = IMAP_AUTHENTICATED;
1665  return 0;
1666  }
1667  }
1668  else
1669  mutt_error(_("Error saving flags"));
1670  return -1;
1671  }
1672 
1673  /* Update local record of server state to reflect the synchronization just
1674  * completed. imap_read_headers always overwrites hcache-origin flags, so
1675  * there is no need to mutate the hcache after flag-only changes. */
1676  for (int i = 0; i < m->msg_count; i++)
1677  {
1678  struct Email *e = m->emails[i];
1679  if (!e)
1680  break;
1681  struct ImapEmailData *edata = imap_edata_get(e);
1682  edata->deleted = e->deleted;
1683  edata->flagged = e->flagged;
1684  edata->old = e->old;
1685  edata->read = e->read;
1686  edata->replied = e->replied;
1687  e->changed = false;
1688  }
1689  m->changed = false;
1690 
1691  /* We must send an EXPUNGE command if we're not closing. */
1692  if (expunge && !close && (m->rights & MUTT_ACL_DELETE))
1693  {
1694  if (m->verbose)
1695  mutt_message(_("Expunging messages from server..."));
1696  /* Set expunge bit so we don't get spurious reopened messages */
1697  mdata->reopen |= IMAP_EXPUNGE_EXPECTED;
1698  if (imap_exec(adata, "EXPUNGE", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1699  {
1700  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1701  imap_error(_("imap_sync_mailbox: EXPUNGE failed"), adata->buf);
1702  return -1;
1703  }
1704  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1705  }
1706 
1707  if (expunge && close)
1708  {
1709  adata->closing = true;
1710  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
1711  adata->state = IMAP_AUTHENTICATED;
1712  }
1713 
1714  if (C_MessageCacheClean)
1715  imap_cache_clean(m);
1716 
1717  return check;
1718 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_ac_owns_path()

static bool imap_ac_owns_path ( struct Account a,
const char *  path 
)
static

Check whether an Account owns a Mailbox path - Implements MxOps::ac_owns_path()

Definition at line 1723 of file imap.c.

1724 {
1725  struct Url *url = url_parse(path);
1726  if (!url)
1727  return false;
1728 
1729  struct ImapAccountData *adata = a->adata;
1730  struct ConnAccount *cac = &adata->conn->account;
1731 
1732  const bool ret = mutt_istr_equal(url->host, cac->host) &&
1733  (!url->user || mutt_istr_equal(url->user, cac->user));
1734  url_free(&url);
1735  return ret;
1736 }
+ Here is the call graph for this function:

◆ imap_ac_add()

static bool imap_ac_add ( struct Account a,
struct Mailbox m 
)
static

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

Definition at line 1741 of file imap.c.

1742 {
1743  struct ImapAccountData *adata = a->adata;
1744 
1745  if (!adata)
1746  {
1747  struct ConnAccount cac = { { 0 } };
1748  char mailbox[PATH_MAX];
1749 
1750  if (imap_parse_path(mailbox_path(m), &cac, mailbox, sizeof(mailbox)) < 0)
1751  return false;
1752 
1753  adata = imap_adata_new(a);
1754  adata->conn = mutt_conn_new(&cac);
1755  if (!adata->conn)
1756  {
1757  imap_adata_free((void **) &adata);
1758  return false;
1759  }
1760 
1762 
1763  if (imap_login(adata) < 0)
1764  {
1765  imap_adata_free((void **) &adata);
1766  return false;
1767  }
1768 
1769  a->adata = adata;
1771  }
1772 
1773  if (!m->mdata)
1774  {
1775  struct Url *url = url_parse(mailbox_path(m));
1776  struct ImapMboxData *mdata = imap_mdata_new(adata, url->path);
1777 
1778  /* fixup path and realpath, mainly to replace / by /INBOX */
1779  char buf[1024];
1780  imap_qualify_path(buf, sizeof(buf), &adata->conn->account, mdata->name);
1781  mutt_buffer_strcpy(&m->pathbuf, buf);
1783 
1784  m->mdata = mdata;
1786  url_free(&url);
1787  }
1788  return true;
1789 }
+ Here is the call graph for this function:

◆ imap_mbox_select()

static void imap_mbox_select ( struct Mailbox m)
static

Select a Mailbox.

Parameters
mMailbox

Definition at line 1795 of file imap.c.

1796 {
1797  struct ImapAccountData *adata = imap_adata_get(m);
1798  struct ImapMboxData *mdata = imap_mdata_get(m);
1799  if (!adata || !mdata)
1800  return;
1801 
1802  const char *condstore = NULL;
1803 #ifdef USE_HCACHE
1805  condstore = " (CONDSTORE)";
1806  else
1807 #endif
1808  condstore = "";
1809 
1810  char buf[PATH_MAX];
1811  snprintf(buf, sizeof(buf), "%s %s%s", m->readonly ? "EXAMINE" : "SELECT",
1812  mdata->munge_name, condstore);
1813 
1814  adata->state = IMAP_SELECTED;
1815 
1816  imap_cmd_start(adata, buf);
1817 }
+ 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 1827 of file imap.c.

1828 {
1829  if (!adata)
1830  return -1;
1831 
1832  if (adata->state == IMAP_DISCONNECTED)
1833  {
1834  mutt_buffer_reset(&adata->cmdbuf); // purge outstanding queued commands
1835  imap_open_connection(adata);
1836  }
1837  if (adata->state == IMAP_CONNECTED)
1838  {
1839  if (imap_authenticate(adata) == IMAP_AUTH_SUCCESS)
1840  {
1841  adata->state = IMAP_AUTHENTICATED;
1842  FREE(&adata->capstr);
1843  if (adata->conn->ssf != 0)
1844  {
1845  mutt_debug(LL_DEBUG2, "Communication encrypted at %d bits\n",
1846  adata->conn->ssf);
1847  }
1848  }
1849  else
1851  }
1852  if (adata->state == IMAP_AUTHENTICATED)
1853  {
1854  /* capabilities may have changed */
1855  imap_exec(adata, "CAPABILITY", IMAP_CMD_PASS);
1856 
1857 #ifdef USE_ZLIB
1858  /* RFC4978 */
1859  if ((adata->capabilities & IMAP_CAP_COMPRESS) && C_ImapDeflate &&
1860  (imap_exec(adata, "COMPRESS DEFLATE", IMAP_CMD_PASS) == IMAP_EXEC_SUCCESS))
1861  {
1862  mutt_debug(LL_DEBUG2, "IMAP compression is enabled on connection to %s\n",
1863  adata->conn->account.host);
1864  mutt_zstrm_wrap_conn(adata->conn);
1865  }
1866 #endif
1867 
1868  /* enable RFC6855, if the server supports that */
1869  if (C_ImapRfc5161 && (adata->capabilities & IMAP_CAP_ENABLE))
1870  imap_exec(adata, "ENABLE UTF8=ACCEPT", IMAP_CMD_QUEUE);
1871 
1872  /* enable QRESYNC. Advertising QRESYNC also means CONDSTORE
1873  * is supported (even if not advertised), so flip that bit. */
1874  if (adata->capabilities & IMAP_CAP_QRESYNC)
1875  {
1876  adata->capabilities |= IMAP_CAP_CONDSTORE;
1878  imap_exec(adata, "ENABLE QRESYNC", IMAP_CMD_QUEUE);
1879  }
1880 
1881  /* get root delimiter, '/' as default */
1882  adata->delim = '/';
1883  imap_exec(adata, "LIST \"\" \"\"", IMAP_CMD_QUEUE);
1884 
1885  /* we may need the root delimiter before we open a mailbox */
1886  imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1887 
1888  /* select the mailbox that used to be open before disconnect */
1889  if (adata->mailbox)
1890  {
1891  imap_mbox_select(adata->mailbox);
1892  }
1893  }
1894 
1895  if (adata->state < IMAP_AUTHENTICATED)
1896  return -1;
1897 
1898  return 0;
1899 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mbox_open()

static enum MxOpenReturns imap_mbox_open ( struct Mailbox m)
static

Open a mailbox - Implements MxOps::mbox_open()

Definition at line 1904 of file imap.c.

1905 {
1906  if (!m->account || !m->mdata)
1907  return MX_OPEN_ERROR;
1908 
1909  char buf[PATH_MAX];
1910  int count = 0;
1911  int rc;
1912 
1913  struct ImapAccountData *adata = imap_adata_get(m);
1914  struct ImapMboxData *mdata = imap_mdata_get(m);
1915 
1916  mutt_debug(LL_DEBUG3, "opening %s, saving %s\n", m->pathbuf.data,
1917  (adata->mailbox ? adata->mailbox->pathbuf.data : "(none)"));
1918  adata->prev_mailbox = adata->mailbox;
1919  adata->mailbox = m;
1920 
1921  /* clear mailbox status */
1922  adata->status = 0;
1923  m->rights = 0;
1924  mdata->new_mail_count = 0;
1925 
1926  if (m->verbose)
1927  mutt_message(_("Selecting %s..."), mdata->name);
1928 
1929  /* pipeline ACL test */
1930  if (adata->capabilities & IMAP_CAP_ACL)
1931  {
1932  snprintf(buf, sizeof(buf), "MYRIGHTS %s", mdata->munge_name);
1933  imap_exec(adata, buf, IMAP_CMD_QUEUE);
1934  }
1935  /* assume we have all rights if ACL is unavailable */
1936  else
1937  {
1940  }
1941 
1942  /* pipeline the postponed count if possible */
1943  struct Mailbox *m_postponed = mx_mbox_find2(C_Postponed);
1944  struct ImapAccountData *postponed_adata = imap_adata_get(m_postponed);
1945  if (postponed_adata &&
1946  imap_account_match(&postponed_adata->conn->account, &adata->conn->account))
1947  {
1948  imap_mailbox_status(m_postponed, true);
1949  }
1950 
1952  imap_exec(adata, "LSUB \"\" \"*\"", IMAP_CMD_QUEUE);
1953 
1954  imap_mbox_select(m);
1955 
1956  do
1957  {
1958  char *pc = NULL;
1959 
1960  rc = imap_cmd_step(adata);
1961  if (rc != IMAP_RES_CONTINUE)
1962  break;
1963 
1964  pc = adata->buf + 2;
1965 
1966  /* Obtain list of available flags here, may be overridden by a
1967  * PERMANENTFLAGS tag in the OK response */
1968  if (mutt_istr_startswith(pc, "FLAGS"))
1969  {
1970  /* don't override PERMANENTFLAGS */
1971  if (STAILQ_EMPTY(&mdata->flags))
1972  {
1973  mutt_debug(LL_DEBUG3, "Getting mailbox FLAGS\n");
1974  pc = get_flags(&mdata->flags, pc);
1975  if (!pc)
1976  goto fail;
1977  }
1978  }
1979  /* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */
1980  else if (mutt_istr_startswith(pc, "OK [PERMANENTFLAGS"))
1981  {
1982  mutt_debug(LL_DEBUG3, "Getting mailbox PERMANENTFLAGS\n");
1983  /* safe to call on NULL */
1984  mutt_list_free(&mdata->flags);
1985  /* skip "OK [PERMANENT" so syntax is the same as FLAGS */
1986  pc += 13;
1987  pc = get_flags(&(mdata->flags), pc);
1988  if (!pc)
1989  goto fail;
1990  }
1991  /* save UIDVALIDITY for the header cache */
1992  else if (mutt_istr_startswith(pc, "OK [UIDVALIDITY"))
1993  {
1994  mutt_debug(LL_DEBUG3, "Getting mailbox UIDVALIDITY\n");
1995  pc += 3;
1996  pc = imap_next_word(pc);
1997  if (mutt_str_atoui(pc, &mdata->uidvalidity) < 0)
1998  goto fail;
1999  }
2000  else if (mutt_istr_startswith(pc, "OK [UIDNEXT"))
2001  {
2002  mutt_debug(LL_DEBUG3, "Getting mailbox UIDNEXT\n");
2003  pc += 3;
2004  pc = imap_next_word(pc);
2005  if (mutt_str_atoui(pc, &mdata->uid_next) < 0)
2006  goto fail;
2007  }
2008  else if (mutt_istr_startswith(pc, "OK [HIGHESTMODSEQ"))
2009  {
2010  mutt_debug(LL_DEBUG3, "Getting mailbox HIGHESTMODSEQ\n");
2011  pc += 3;
2012  pc = imap_next_word(pc);
2013  if (mutt_str_atoull(pc, &mdata->modseq) < 0)
2014  goto fail;
2015  }
2016  else if (mutt_istr_startswith(pc, "OK [NOMODSEQ"))
2017  {
2018  mutt_debug(LL_DEBUG3, "Mailbox has NOMODSEQ set\n");
2019  mdata->modseq = 0;
2020  }
2021  else
2022  {
2023  pc = imap_next_word(pc);
2024  if (mutt_istr_startswith(pc, "EXISTS"))
2025  {
2026  count = mdata->new_mail_count;
2027  mdata->new_mail_count = 0;
2028  }
2029  }
2030  } while (rc == IMAP_RES_CONTINUE);
2031 
2032  if (rc == IMAP_RES_NO)
2033  {
2034  char *s = imap_next_word(adata->buf); /* skip seq */
2035  s = imap_next_word(s); /* Skip response */
2036  mutt_error("%s", s);
2037  goto fail;
2038  }
2039 
2040  if (rc != IMAP_RES_OK)
2041  goto fail;
2042 
2043  /* check for READ-ONLY notification */
2044  if (mutt_istr_startswith(imap_get_qualifier(adata->buf), "[READ-ONLY]") &&
2045  !(adata->capabilities & IMAP_CAP_ACL))
2046  {
2047  mutt_debug(LL_DEBUG2, "Mailbox is read-only\n");
2048  m->readonly = true;
2049  }
2050 
2051  /* dump the mailbox flags we've found */
2052  if (C_DebugLevel > LL_DEBUG2)
2053  {
2054  if (STAILQ_EMPTY(&mdata->flags))
2055  mutt_debug(LL_DEBUG3, "No folder flags found\n");
2056  else
2057  {
2058  struct ListNode *np = NULL;
2059  struct Buffer flag_buffer;
2060  mutt_buffer_init(&flag_buffer);
2061  mutt_buffer_printf(&flag_buffer, "Mailbox flags: ");
2062  STAILQ_FOREACH(np, &mdata->flags, entries)
2063  {
2064  mutt_buffer_add_printf(&flag_buffer, "[%s] ", np->data);
2065  }
2066  mutt_debug(LL_DEBUG3, "%s\n", flag_buffer.data);
2067  FREE(&flag_buffer.data);
2068  }
2069  }
2070 
2071  if (!((m->rights & MUTT_ACL_DELETE) || (m->rights & MUTT_ACL_SEEN) ||
2072  (m->rights & MUTT_ACL_WRITE) || (m->rights & MUTT_ACL_INSERT)))
2073  {
2074  m->readonly = true;
2075  }
2076 
2077  while (m->email_max < count)
2078  mx_alloc_memory(m);
2079 
2080  m->msg_count = 0;
2081  m->msg_unread = 0;
2082  m->msg_flagged = 0;
2083  m->msg_new = 0;
2084  m->msg_deleted = 0;
2085  m->size = 0;
2086  m->vcount = 0;
2087 
2088  if (count && (imap_read_headers(m, 1, count, true) < 0))
2089  {
2090  mutt_error(_("Error opening mailbox"));
2091  goto fail;
2092  }
2093 
2094  mutt_debug(LL_DEBUG2, "msg_count is %d\n", m->msg_count);
2095  return MX_OPEN_OK;
2096 
2097 fail:
2098  if (adata->state == IMAP_SELECTED)
2099  adata->state = IMAP_AUTHENTICATED;
2100  return MX_OPEN_ERROR;
2101 }
+ Here is the call graph for this function:

◆ imap_mbox_open_append()

static bool imap_mbox_open_append ( struct Mailbox m,
OpenMailboxFlags  flags 
)
static

Open a Mailbox for appending - Implements MxOps::mbox_open_append()

Definition at line 2106 of file imap.c.

2107 {
2108  if (!m->account)
2109  return false;
2110 
2111  /* in APPEND mode, we appear to hijack an existing IMAP connection -
2112  * ctx is brand new and mostly empty */
2113  struct ImapAccountData *adata = imap_adata_get(m);
2114  struct ImapMboxData *mdata = imap_mdata_get(m);
2115 
2116  int rc = imap_mailbox_status(m, false);
2117  if (rc >= 0)
2118  return true;
2119  if (rc == -1)
2120  return false;
2121 
2122  char buf[PATH_MAX + 64];
2123  snprintf(buf, sizeof(buf), _("Create %s?"), mdata->name);
2124  if (C_ConfirmCreate && (mutt_yesorno(buf, MUTT_YES) != MUTT_YES))
2125  return false;
2126 
2127  if (imap_create_mailbox(adata, mdata->name) < 0)
2128  return false;
2129 
2130  return true;
2131 }
+ Here is the call graph for this function:

◆ imap_mbox_check()

static enum MxStatus imap_mbox_check ( struct Mailbox m)
static

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

Parameters
mMailbox
Return values
>0Success, e.g. MX_STATUS_REOPENED
-1Failure

Definition at line 2139 of file imap.c.

2140 {
2141  imap_allow_reopen(m);
2142  enum MxStatus rc = imap_check_mailbox(m, false);
2143  /* NOTE - ctx might have been changed at this point. In particular,
2144  * m could be NULL. Beware. */
2146 
2147  return rc;
2148 }
+ Here is the call graph for this function:

◆ imap_mbox_close()

static enum MxStatus imap_mbox_close ( struct Mailbox m)
static

Close a Mailbox - Implements MxOps::mbox_close()

Definition at line 2153 of file imap.c.

2154 {
2155  struct ImapAccountData *adata = imap_adata_get(m);
2156  struct ImapMboxData *mdata = imap_mdata_get(m);
2157 
2158  /* Check to see if the mailbox is actually open */
2159  if (!adata || !mdata)
2160  return MX_STATUS_OK;
2161 
2162  /* imap_mbox_open_append() borrows the struct ImapAccountData temporarily,
2163  * just for the connection.
2164  *
2165  * So when these are equal, it means we are actually closing the
2166  * mailbox and should clean up adata. Otherwise, we don't want to
2167  * touch adata - it's still being used. */
2168  if (m == adata->mailbox)
2169  {
2170  if ((adata->status != IMAP_FATAL) && (adata->state >= IMAP_SELECTED))
2171  {
2172  /* mx_mbox_close won't sync if there are no deleted messages
2173  * and the mailbox is unchanged, so we may have to close here */
2174  if (m->msg_deleted == 0)
2175  {
2176  adata->closing = true;
2177  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
2178  }
2179  adata->state = IMAP_AUTHENTICATED;
2180  }
2181 
2182  mutt_debug(LL_DEBUG3, "closing %s, restoring %s\n", m->pathbuf.data,
2183  (adata->prev_mailbox ? adata->prev_mailbox->pathbuf.data : "(none)"));
2184  adata->mailbox = adata->prev_mailbox;
2187  }
2188 
2189  return MX_STATUS_OK;
2190 }
+ Here is the call graph for this function:

◆ imap_msg_open_new()

static bool imap_msg_open_new ( struct Mailbox m,
struct Message msg,
const struct Email e 
)
static

Open a new message in a Mailbox - Implements MxOps::msg_open_new()

Definition at line 2195 of file imap.c.

2196 {
2197  bool success = false;
2198 
2199  struct Buffer *tmp = mutt_buffer_pool_get();
2200  mutt_buffer_mktemp(tmp);
2201 
2202  msg->fp = mutt_file_fopen(mutt_buffer_string(tmp), "w");
2203  if (!msg->fp)
2204  {
2206  goto cleanup;
2207  }
2208 
2209  msg->path = mutt_buffer_strdup(tmp);
2210  success = true;
2211 
2212 cleanup:
2214  return success;
2215 }
+ Here is the call graph for this function:

◆ imap_tags_edit()

static int imap_tags_edit ( struct Mailbox m,
const char *  tags,
char *  buf,
size_t  buflen 
)
static

Prompt and validate new messages tags - Implements MxOps::tags_edit()

Definition at line 2220 of file imap.c.

2221 {
2222  struct ImapMboxData *mdata = imap_mdata_get(m);
2223  if (!mdata)
2224  return -1;
2225 
2226  char *new_tag = NULL;
2227  char *checker = NULL;
2228 
2229  /* Check for \* flags capability */
2230  if (!imap_has_flag(&mdata->flags, NULL))
2231  {
2232  mutt_error(_("IMAP server doesn't support custom flags"));
2233  return -1;
2234  }
2235 
2236  *buf = '\0';
2237  if (tags)
2238  mutt_str_copy(buf, tags, buflen);
2239 
2240  if (mutt_get_field("Tags: ", buf, buflen, MUTT_COMP_NO_FLAGS, false, NULL, NULL) != 0)
2241  return -1;
2242 
2243  /* each keyword must be atom defined by rfc822 as:
2244  *
2245  * atom = 1*<any CHAR except specials, SPACE and CTLs>
2246  * CHAR = ( 0.-127. )
2247  * specials = "(" / ")" / "<" / ">" / "@"
2248  * / "," / ";" / ":" / "\" / <">
2249  * / "." / "[" / "]"
2250  * SPACE = ( 32. )
2251  * CTLS = ( 0.-31., 127.)
2252  *
2253  * And must be separated by one space.
2254  */
2255 
2256  new_tag = buf;
2257  checker = buf;
2258  SKIPWS(checker);
2259  while (*checker != '\0')
2260  {
2261  if ((*checker < 32) || (*checker >= 127) || // We allow space because it's the separator
2262  (*checker == 40) || // (
2263  (*checker == 41) || // )
2264  (*checker == 60) || // <
2265  (*checker == 62) || // >
2266  (*checker == 64) || // @
2267  (*checker == 44) || // ,
2268  (*checker == 59) || // ;
2269  (*checker == 58) || // :
2270  (*checker == 92) || // backslash
2271  (*checker == 34) || // "
2272  (*checker == 46) || // .
2273  (*checker == 91) || // [
2274  (*checker == 93)) // ]
2275  {
2276  mutt_error(_("Invalid IMAP flags"));
2277  return 0;
2278  }
2279 
2280  /* Skip duplicate space */
2281  while ((checker[0] == ' ') && (checker[1] == ' '))
2282  checker++;
2283 
2284  /* copy char to new_tag and go the next one */
2285  *new_tag++ = *checker++;
2286  }
2287  *new_tag = '\0';
2288  new_tag = buf; /* rewind */
2289  mutt_str_remove_trailing_ws(new_tag);
2290 
2291  return !mutt_str_equal(tags, buf);
2292 }
+ Here is the call graph for this function:

◆ imap_tags_commit()

static int imap_tags_commit ( struct Mailbox m,
struct Email e,
char *  buf 
)
static

Save the tags to a message - Implements MxOps::tags_commit()

This method update the server flags on the server by removing the last know custom flags of a header and adds the local flags

If everything success we push the local flags to the last know custom flags (flags_remote).

Also this method check that each flags is support by the server first and remove unsupported one.

Definition at line 2307 of file imap.c.

2308 {
2309  char uid[11];
2310 
2311  struct ImapAccountData *adata = imap_adata_get(m);
2312 
2313  if (*buf == '\0')
2314  buf = NULL;
2315 
2316  if (!(adata->mailbox->rights & MUTT_ACL_WRITE))
2317  return 0;
2318 
2319  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
2320 
2321  /* Remove old custom flags */
2322  if (imap_edata_get(e)->flags_remote)
2323  {
2324  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2325  mutt_buffer_addstr(&cmd, "UID STORE ");
2326  mutt_buffer_addstr(&cmd, uid);
2327  mutt_buffer_addstr(&cmd, " -FLAGS.SILENT (");
2328  mutt_buffer_addstr(&cmd, imap_edata_get(e)->flags_remote);
2329  mutt_buffer_addstr(&cmd, ")");
2330 
2331  /* Should we return here, or we are fine and we could
2332  * continue to add new flags */
2333  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2334  mutt_buffer_dealloc(&cmd);
2335  if (rc != IMAP_EXEC_SUCCESS)
2336  {
2337  return -1;
2338  }
2339  }
2340 
2341  /* Add new custom flags */
2342  if (buf)
2343  {
2344  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2345  mutt_buffer_addstr(&cmd, "UID STORE ");
2346  mutt_buffer_addstr(&cmd, uid);
2347  mutt_buffer_addstr(&cmd, " +FLAGS.SILENT (");
2348  mutt_buffer_addstr(&cmd, buf);
2349  mutt_buffer_addstr(&cmd, ")");
2350 
2351  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2352  mutt_buffer_dealloc(&cmd);
2353  if (rc != IMAP_EXEC_SUCCESS)
2354  {
2355  mutt_debug(LL_DEBUG1, "fail to add new flags\n");
2356  return -1;
2357  }
2358  }
2359 
2360  /* We are good sync them */
2361  mutt_debug(LL_DEBUG1, "NEW TAGS: %s\n", buf);
2362  driver_tags_replace(&e->tags, buf);
2363  FREE(&imap_edata_get(e)->flags_remote);
2365  imap_msg_save_hcache(m, e);
2366  return 0;
2367 }
+ Here is the call graph for this function:

◆ imap_path_probe()

enum MailboxType imap_path_probe ( const char *  path,
const struct stat *  st 
)

Is this an IMAP Mailbox? - Implements MxOps::path_probe()

Definition at line 2372 of file imap.c.

2373 {
2374  if (mutt_istr_startswith(path, "imap://"))
2375  return MUTT_IMAP;
2376 
2377  if (mutt_istr_startswith(path, "imaps://"))
2378  return MUTT_IMAP;
2379 
2380  return MUTT_UNKNOWN;
2381 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_path_canon()

int imap_path_canon ( char *  buf,
size_t  buflen 
)

Canonicalise a Mailbox path - Implements MxOps::path_canon()

Definition at line 2386 of file imap.c.

2387 {
2388  struct Url *url = url_parse(buf);
2389  if (!url)
2390  return 0;
2391 
2392  char tmp[PATH_MAX];
2393  char tmp2[PATH_MAX];
2394 
2395  imap_fix_path('\0', url->path, tmp, sizeof(tmp));
2396  url->path = tmp;
2397  url_tostring(url, tmp2, sizeof(tmp2), U_NO_FLAGS);
2398  mutt_str_copy(buf, tmp2, buflen);
2399  url_free(&url);
2400 
2401  return 0;
2402 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_expand_path()

int imap_expand_path ( struct Buffer buf)

Buffer wrapper around imap_path_canon()

Parameters
bufPath to expand
Return values
0Success
-1Failure
Note
The path is expanded in place

Definition at line 2412 of file imap.c.

2413 {
2415  return imap_path_canon(buf->data, PATH_MAX);
2416 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_path_pretty()

static int imap_path_pretty ( char *  buf,
size_t  buflen,
const char *  folder 
)
static

Abbreviate a Mailbox path - Implements MxOps::path_pretty()

Definition at line 2421 of file imap.c.

2422 {
2423  if (!folder)
2424  return -1;
2425 
2426  imap_pretty_mailbox(buf, buflen, folder);
2427  return 0;
2428 }
+ Here is the call graph for this function:

◆ imap_path_parent()

static int imap_path_parent ( char *  buf,
size_t  buflen 
)
static

Find the parent of a Mailbox path - Implements MxOps::path_parent()

Definition at line 2433 of file imap.c.

2434 {
2435  char tmp[PATH_MAX] = { 0 };
2436 
2437  imap_get_parent_path(buf, tmp, sizeof(tmp));
2438  mutt_str_copy(buf, tmp, buflen);
2439  return 0;
2440 }
+ Here is the call graph for this function:

◆ imap_path_is_empty()

static int imap_path_is_empty ( const char *  path)
static

Is the mailbox empty - Implements MxOps::path_is_empty()

Definition at line 2445 of file imap.c.

2446 {
2447  int rc = imap_path_status(path, false);
2448  if (rc < 0)
2449  return -1;
2450  if (rc == 0)
2451  return 1;
2452  return 0;
2453 }
+ Here is the call graph for this function:

Variable Documentation

◆ imap_commands

const struct Command imap_commands[]
static
Initial value:
= {
{ "subscribe-to", parse_subscribe_to, 0 },
{ "unsubscribe-from", parse_unsubscribe_from, 0 },
}

Definition at line 72 of file imap.c.

◆ MxImapOps

struct MxOps MxImapOps
Initial value:
= {
.type = MUTT_IMAP,
.name = "imap",
.is_local = false,
.ac_owns_path = imap_ac_owns_path,
.ac_add = imap_ac_add,
.mbox_open = imap_mbox_open,
.mbox_open_append = imap_mbox_open_append,
.mbox_check = imap_mbox_check,
.mbox_check_stats = imap_mbox_check_stats,
.mbox_sync = NULL,
.mbox_close = imap_mbox_close,
.msg_open = imap_msg_open,
.msg_open_new = imap_msg_open_new,
.msg_commit = imap_msg_commit,
.msg_close = imap_msg_close,
.msg_padding_size = NULL,
.msg_save_hcache = imap_msg_save_hcache,
.tags_edit = imap_tags_edit,
.tags_commit = imap_tags_commit,
.path_probe = imap_path_probe,
.path_canon = imap_path_canon,
.path_pretty = imap_path_pretty,
.path_parent = imap_path_parent,
.path_is_empty = imap_path_is_empty,
}

IMAP Mailbox - Implements MxOps.

Definition at line 2459 of file imap.c.

C_SslForceTls
bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: config.c:46
IMAP_RES_OK
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:58
Mailbox::mdata_free
void(* mdata_free)(void **ptr)
Free the private data attached to the Mailbox.
Definition: mailbox.h:142
C_ImapDeflate
bool C_ImapDeflate
Config: (imap) Compress network traffic.
Definition: config.c:43
imap_cache_del
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1796
parse_subscribe_to
enum CommandResult parse_subscribe_to(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'subscribe-to' command - Implements Command::parse()
Definition: command_parse.c:1684
ImapMboxData::real_name
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
imap_tags_commit
static int imap_tags_commit(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message - Implements MxOps::tags_commit()
Definition: imap.c:2307
mutt_conn_new
struct Connection * mutt_conn_new(const struct ConnAccount *cac)
Create a new Connection.
Definition: mutt_socket.c:46
ConnAccount
Login details for a remote server.
Definition: connaccount.h:51
C_Timeout
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: mutt_globals.h:115
IMAP_LOG_LTRL
#define IMAP_LOG_LTRL
Definition: private.h:52
Mailbox::rights
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
C_ImapKeepalive
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
mutt_parse_rc_line
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1044
Connection
An open network connection (socket)
Definition: connection.h:34
MUTT_FLAG
@ MUTT_FLAG
Flagged messages.
Definition: mutt.h:102
imap_hcache_open
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:299
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
imap_hcache_put
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:381
ImapMboxData::uid_next
unsigned int uid_next
Definition: mdata.h:51
MxStatus
MxStatus
Return values from mx_mbox_check(), mx_mbox_sync(), and mx_mbox_close()
Definition: mx.h:71
ConnAccount::host
char host[128]
Server to login to.
Definition: connaccount.h:53
MailboxNode
List of Mailboxes.
Definition: mailbox.h:152
ImapExecResult
ImapExecResult
imap_exec return code
Definition: private.h:84
NeoMutt::accounts
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
ImapMboxData::flags
struct ListHead flags
Definition: mdata.h:49
ImapEmailData::replied
bool replied
Definition: edata.h:40
_
#define _(a)
Definition: message.h:28
imap_quote_string
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:836
IMAP_CAP_ACL
#define IMAP_CAP_ACL
RFC2086: IMAP4 ACL extension.
Definition: private.h:128
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.
Definition: imap.c:995
Mailbox
A mailbox.
Definition: mailbox.h:81
ImapMboxData::munge_name
char * munge_name
Munged version of the mailbox name.
Definition: mdata.h:41
imap_pretty_mailbox
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:590
TRANSFORM_NONE
@ TRANSFORM_NONE
No transformation.
Definition: commands.h:51
C_ImapCheckSubscribed
bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: config.c:40
imap_disallow_reopen
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1028
IMAP_EXPUNGE_PENDING
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: private.h:70
Mailbox::emails
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
Mailbox::append
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
MUTT_ACL_CREATE
#define MUTT_ACL_CREATE
Create a mailbox.
Definition: mailbox.h:65
IMAP_FATAL
@ IMAP_FATAL
Unrecoverable error occurred.
Definition: private.h:99
longest_common_prefix
static size_t longest_common_prefix(char *dest, const char *src, size_t start, size_t dlen)
Find longest prefix common to two strings.
Definition: imap.c:364
imap_mdata_free
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:36
ImapMboxData::uid_hash
struct HashTable * uid_hash
Definition: mdata.h:58
ImapMboxData::new_mail_count
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: mdata.h:46
IMAP_EXEC_SUCCESS
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
Definition: private.h:86
MUTT_ACL_LOOKUP
#define MUTT_ACL_LOOKUP
Lookup mailbox (visible to 'list')
Definition: mailbox.h:70
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
IMAP_BYE
@ IMAP_BYE
Logged out from server.
Definition: private.h:100
Account::type
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
ImapAccountData::closing
bool closing
If true, we are waiting for CLOSE completion.
Definition: adata.h:40
LL_DEBUG3
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
Connection::account
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
ImapList::delim
char delim
Definition: private.h:153
IMAP_DISCONNECTED
@ IMAP_DISCONNECTED
Disconnected from server.
Definition: private.h:109
MUTT_ACL_INSERT
#define MUTT_ACL_INSERT
Add/copy into the mailbox (used when editing a message)
Definition: mailbox.h:69
imap_msg_open_new
static bool imap_msg_open_new(struct Mailbox *m, struct Message *msg, const struct Email *e)
Open a new message in a Mailbox - Implements MxOps::msg_open_new()
Definition: imap.c:2195
IMAP_IDLE
@ IMAP_IDLE
Connection is idle.
Definition: private.h:115
Mailbox::msg_deleted
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
imap_adata_new
struct ImapAccountData * imap_adata_new(struct Account *a)
Allocate and initialise a new ImapAccountData structure.
Definition: adata.c:64
driver_tags_replace
bool driver_tags_replace(struct TagList *head, char *tags)
Replace all tags.
Definition: tags.c:185
mutt_socket_empty
void mutt_socket_empty(struct Connection *conn)
Clear out any queued data.
Definition: socket.c:312
MUTT_ACL_DELETE
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
imap_authenticate
int imap_authenticate(struct ImapAccountData *adata)
Authenticate to an IMAP server.
Definition: auth.c:105
C_ImapQresync
bool C_ImapQresync
Config: (imap) Enable the QRESYNC extension.
Definition: config.c:58
C_SslStarttls
unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: config.c:47
C_ImapIdle
bool C_ImapIdle
Config: (imap) Use the IMAP IDLE extension to check for new mail.
Definition: config.c:48
mutt_buffer_add_printf
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
mutt_account_tourl
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
ImapEmailData::flags_remote
char * flags_remote
Definition: edata.h:48
ImapEmailData::old
bool old
Definition: edata.h:37
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.
Definition: util.c:910
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: message.c:2127
make_msg_set
static int make_msg_set(struct Mailbox *m, struct Buffer *buf, enum MessageType flag, bool changed, bool invert, int *pos)
Make a message set.
Definition: imap.c:196
imap_mdata_new
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: mdata.c:68
ImapAccountData::cmdresult
struct ImapList * cmdresult
Definition: adata.h:63
imap_qualify_path
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:819
U_NO_FLAGS
#define U_NO_FLAGS
Definition: url.h:48
IMAP_CAP_ENABLE
#define IMAP_CAP_ENABLE
RFC5161.
Definition: private.h:138
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
ImapAccountData::buf
char * buf
Definition: adata.h:56
ImapAccountData::capabilities
ImapCapFlags capabilities
Definition: adata.h:52
mutt_socket_readchar
int mutt_socket_readchar(struct Connection *conn, char *c)
simple read buffering to speed things up
Definition: socket.c:209
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
ImapAccountData::status
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: adata.h:42
imap_cmd_step
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1074
mutt_buffer_init
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
ImapAccountData::cmdslots
int cmdslots
Definition: adata.h:67
mutt_socket_close
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:96
neomutt_mailboxlist_get_all
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
check_capabilities
static int check_capabilities(struct ImapAccountData *adata)
Make sure we can log in to this server.
Definition: imap.c:93
ImapEmailData::deleted
bool deleted
Definition: edata.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
IMAP_FLAGS_PENDING
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: private.h:72
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
imap_msg_close
int imap_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close()
Definition: message.c:2119
MUTT_ACL_READ
#define MUTT_ACL_READ
Read the mailbox.
Definition: mailbox.h:72
IMAP_CMD_POLL
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:78
Mailbox::size
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
Mailbox::has_new
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
SAVE_MOVE
@ SAVE_MOVE
Move message to another mailbox, removing the original.
Definition: commands.h:62
FREE
#define FREE(x)
Definition: memory.h:40
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
MX_OPEN_OK
@ MX_OPEN_OK
Open succeeded.
Definition: mx.h:86
imap_mbox_close
static enum MxStatus imap_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close()
Definition: imap.c:2153
MUTT_DELETED
@ MUTT_DELETED
Deleted messages.
Definition: mutt.h:101
imap_mbox_open_append
static bool imap_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append()
Definition: imap.c:2106
mutt_get_sort_func
sort_t mutt_get_sort_func(enum SortType method)
Get the sort function for a given sort id.
Definition: sort.c:325
imap_hcache_del
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:399
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
ImapList
Items in an IMAP browser.
Definition: private.h:150
MailboxNode::mailbox
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
MUTT_ABORT
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:38
ImapAccountData::lastread
time_t lastread
last time we read a command for the server
Definition: adata.h:55
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_socket_poll
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
STAILQ_EMPTY
#define STAILQ_EMPTY(head)
Definition: queue.h:345
imap_exec_msgset
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:917
imap_adata_get
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:86
mailbox_free
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
url_parse
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
mx_path_resolve
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
mutt_list_insert_tail
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
C_MessageCacheClean
bool C_MessageCacheClean
Config: (imap/pop) Clean out obsolete entries from the message cache.
Definition: bcache.c:44
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
ImapAccountData::conn
struct Connection * conn
Definition: adata.h:38
Mailbox::vcount
int vcount
The number of virtual messages.
Definition: mailbox.h:102
MX_STATUS_REOPENED
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mx.h:77
mutt_buffer_alloc
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
imap_cmd_finish
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1309
imap_open_connection
int imap_open_connection(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:740
imap_get_parent_path
void imap_get_parent_path(const char *path, char *buf, size_t buflen)
Get the path of the parent folder.
Definition: util.c:163
Account::adata_free
void(* adata_free)(void **ptr)
Free the private data attached to the Account.
Definition: account.h:49
MUTT_READ
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:96
SKIPWS
#define SKIPWS(ch)
Definition: string2.h:46
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
MX_STATUS_NEW_MAIL
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mx.h:75
IMAP_CAP_IMAP4REV1
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: private.h:126
Connection::fd
int fd
Socket file descriptor.
Definition: connection.h:40
Email::old
bool old
Email is seen, but unread.
Definition: email.h:50
Email::active
bool active
Message is not to be removed.
Definition: email.h:59
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
imap_account_match
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1043
mx_alloc_memory
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1230
imap_status
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1163
mutt_buffer_addch
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_account_unsetpass
void mutt_account_unsetpass(struct ConnAccount *cac)
Unset ConnAccount's password.
Definition: connaccount.c:141
imap_hcache_close
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:340
imap_adata_find
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:74
IMAP_CAP_STARTTLS
#define IMAP_CAP_STARTTLS
RFC2595: STARTTLS.
Definition: private.h:134
Mailbox::mdata
void * mdata
Driver specific data.
Definition: mailbox.h:136
Envelope::changed
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
url_tostring
int url_tostring(struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:418
NT_MAILBOX_UPDATE
@ NT_MAILBOX_UPDATE
Update internal tables.
Definition: mailbox.h:176
imap_commands
static const struct Command imap_commands[]
Definition: imap.c:72
imap_mbox_check_stats
static enum MxStatus imap_mbox_check_stats(struct Mailbox *m, uint8_t flags)
Check the Mailbox statistics - Implements MxOps::mbox_check_stats()
Definition: imap.c:1206
imap_logout
static void imap_logout(struct ImapAccountData *adata)
Gracefully log out of server.
Definition: imap.c:535
Account
A group of associated Mailboxes.
Definition: account.h:36
Email::tagged
bool tagged
Email is tagged.
Definition: email.h:44
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.
Definition: message.c:1283
Message::path
char * path
path to temp file
Definition: mx.h:97
mutt_account_hook
void mutt_account_hook(const char *url)
Perform an account hook.
Definition: hook.c:756
ImapAccountData::cmds
struct ImapCommand * cmds
Definition: adata.h:66
Mailbox::changed
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
Url
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:67
Mailbox::account
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
imap_mailbox_status
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1256
ImapEmailData
IMAP-specific Email data -.
Definition: edata.h:33
MUTT_ACCT_TYPE_IMAP
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:37
MUTT_ACL_POST
#define MUTT_ACL_POST
Post (submit messages to the server)
Definition: mailbox.h:71
IMAP_MAX_CMDLEN
#define IMAP_MAX_CMDLEN
Maximum length of command lines before they must be split (for lazy servers)
Definition: private.h:64
url_free
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
Mailbox::msg_count
int msg_count
Total number of messages.
Definition: mailbox.h:91
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
MUTT_MAILBOX_ANY
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition: mailbox.h:45
imap_msg_open
bool imap_msg_open(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox - Implements MxOps::msg_open()
Definition: message.c:1904
imap_next_word
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:788
ImapAccountData::unicode
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: adata.h:59
MUTT_UNKNOWN
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
ImapEmailData::uid
unsigned int uid
32-bit Message UID
Definition: edata.h:44
mutt_hash_int_delete
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_RES_NO
#define IMAP_RES_NO
<tag> NO ...
Definition: private.h:56
imap_cmd_start
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1060
mutt_zstrm_wrap_conn
void mutt_zstrm_wrap_conn(struct Connection *conn)
Wrap a compression layer around a Connection.
Definition: zstrm.c:288
mutt_save_message_ctx
int mutt_save_message_ctx(struct Email *e, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt, struct Mailbox *m)
Save a message to a given mailbox.
Definition: commands.c:1001
imap_msn_remove
void imap_msn_remove(struct MSN *msn, size_t idx)
Remove an entry from the cache.
Definition: msn.c:113
MUTT_IMAP
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:53
imap_path_pretty
static int imap_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
Definition: imap.c:2421
imap_cmd_idle
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
Definition: command.c:1376
parse_unsubscribe_from
enum CommandResult parse_unsubscribe_from(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unsubscribe-from' command - Implements Command::parse()
Definition: command_parse.c:2108
C_ImapRfc5161
bool C_ImapRfc5161
Config: (imap) Use the IMAP ENABLE extension to select capabilities.
Definition: config.c:59
imap_error
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:663
ImapMboxData::modseq
unsigned long long modseq
Definition: mdata.h:52
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Mailbox::email_max
int email_max
Number of pointers in emails.
Definition: mailbox.h:100
MUTT_REPLIED
@ MUTT_REPLIED
Messages that have been replied to.
Definition: mutt.h:95
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
IMAP_CAP_STATUS
#define IMAP_CAP_STATUS
Server supports STATUS command.
Definition: private.h:127
Email::purge
bool purge
Skip trash folder when deleting.
Definition: email.h:46
ImapAccountData::seqno
unsigned int seqno
tag sequence number, e.g. '{seqid}0001'
Definition: adata.h:54
imap_path_canon
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: imap.c:2386
Mailbox::msg_flagged
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
Mailbox::realpath
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Message::fp
FILE * fp
pointer to the message data
Definition: mx.h:96
MX_STATUS_ERROR
@ MX_STATUS_ERROR
An error occurred.
Definition: mx.h:73
Email::flagged
bool flagged
Marked important?
Definition: email.h:43
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
Url::user
char * user
Username.
Definition: url.h:70
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
Mailbox::verbose
bool verbose
Display status messages?
Definition: mailbox.h:118
IMAP_OPEN_NO_FLAGS
#define IMAP_OPEN_NO_FLAGS
No flags are set.
Definition: private.h:67
ImapAccountData::lastcmd
int lastcmd
Definition: adata.h:69
mutt_date_epoch
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
imap_adata_free
void imap_adata_free(void **ptr)
Free the private Account data - Implements Account::adata_free()
Definition: adata.c:38
SORT_ORDER
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:50
complete_hosts
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:385
ImapAccountData
IMAP-specific Account data -.
Definition: adata.h:36
imap_close_connection
void imap_close_connection(struct ImapAccountData *adata)
Close an IMAP connection.
Definition: imap.c:843
MUTT_ACL_WRITE
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
ImapMboxData
IMAP-specific Mailbox data -.
Definition: mdata.h:38
IMAP_CONNECTED
@ IMAP_CONNECTED
Connected to server.
Definition: private.h:110
MUTT_OLD
@ MUTT_OLD
Old messages.
Definition: mutt.h:94
imap_edata_free
void imap_edata_free(void **ptr)
Free the private Email data - Implements Email::edata_free()
Definition: edata.c:37
imap_cache_clean
int imap_cache_clean(struct Mailbox *m)
Delete all the entries in the message cache.
Definition: message.c:1815
Email::deleted
bool deleted
Email is deleted.
Definition: email.h:45
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
MUTT_TRASH
@ MUTT_TRASH
Trashed messages.
Definition: mutt.h:108
imap_fix_path
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:685
Mailbox::readonly
bool readonly
Don't allow changes to the mailbox.
Definition: mailbox.h:119
imap_path_is_empty
static int imap_path_is_empty(const char *path)
Is the mailbox empty - Implements MxOps::path_is_empty()
Definition: imap.c:2445
imap_ac_owns_path
static bool imap_ac_owns_path(struct Account *a, const char *path)
Check whether an Account owns a Mailbox path - Implements MxOps::ac_owns_path()
Definition: imap.c:1723
mutt_str_cat
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
imap_path_status
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1222
IMAP_CAP_CONDSTORE
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: private.h:139
imap_get_qualifier
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:771
IMAP_AUTH_SUCCESS
@ IMAP_AUTH_SUCCESS
Authentication successful.
Definition: auth.h:38
mutt_socket_open
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:75
C_DebugLevel
short C_DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
imap_msg_commit
int imap_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit()
Definition: message.c:2105
C_ImapListSubscribed
bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: config.c:50
IMAP_CMD_PASS
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
Definition: private.h:76
C_Sort
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:60
get_flags
static char * get_flags(struct ListHead *hflags, char *s)
Make a simple list out of a FLAGS response.
Definition: imap.c:120
Email::edata
void * edata
Driver-specific data.
Definition: email.h:111
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
ImapAccountData::state
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: adata.h:41
Email::tags
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
imap_exec
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:1245
IMAP_RES_CONTINUE
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:59
compare_uid
static int compare_uid(const void *a, const void *b)
Compare two Emails by UID - Implements sort_t.
Definition: imap.c:894
MUTT_TAG
@ MUTT_TAG
Tagged messages.
Definition: mutt.h:103
IMAP_CAP_IDLE
#define IMAP_CAP_IDLE
RFC2177: IDLE.
Definition: private.h:136
mutt_str_remove_trailing_ws
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:700
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
IMAP_EXPUNGE_EXPECTED
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: private.h:69
ImapAccountData::mailbox
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:73
mutt_istr_startswith
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
ImapEmailData::flagged
bool flagged
Definition: edata.h:39
C_Postponed
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: mutt_globals.h:101
ImapAccountData::cmdbuf
struct Buffer cmdbuf
Definition: adata.h:70
imap_allow_reopen
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1015
IMAP_EXEC_ERROR
@ IMAP_EXEC_ERROR
Imap command failure.
Definition: private.h:87
mx_ac_remove
int mx_ac_remove(struct Mailbox *m)
Remove a Mailbox from an Account and delete Account if empty.
Definition: mx.c:1780
Url::host
char * host
Host.
Definition: url.h:72
mailbox_changed
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:186
imap_path_probe
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2372
imap_has_flag
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:868
imap_mdata_get
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:55
mutt_buffer_len
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
ImapList::noselect
bool noselect
Definition: private.h:154
IMAP_CMD_QUEUE
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:77
ImapEmailData::read
bool read
Definition: edata.h:36
Account::adata
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
ListNode::data
char * data
String.
Definition: list.h:36
Email::index
int index
The absolute (unsorted) message number.
Definition: email.h:86
imap_parse_path
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:483
set_flag
static void set_flag(struct Mailbox *m, AclFlags aclflag, bool flag, const char *str, char *flags, size_t flsize)
append str to flags if we currently have permission according to aclflag
Definition: imap.c:175
imap_create_mailbox
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:447
mutt_progress_update
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
plen
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
IMAP_AUTHENTICATED
@ IMAP_AUTHENTICATED
Connection is authenticated.
Definition: private.h:111
IMAP_EXEC_FATAL
@ IMAP_EXEC_FATAL
Imap connection failure.
Definition: private.h:88
mutt_istrn_equal
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:621
Mailbox::msg_unread
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
IMAP_CMD_NO_FLAGS
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:75
ImapMboxData::reopen
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: mdata.h:44
mutt_get_field
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:311
imap_path_parent
static int imap_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
Definition: imap.c:2433
IMAP_NEWMAIL_PENDING
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:71
imap_tags_edit
static int imap_tags_edit(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags - Implements MxOps::tags_edit()
Definition: imap.c:2220
Url::path
char * path
Path.
Definition: url.h:74
mutt_buffer_strdup
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:432
MX_STATUS_FLAGS
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mx.h:78
Email::attach_del
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
mailbox_path
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:206
C_ImapPollTimeout
short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: config.c:57
mutt_str_atoui
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
ImapAccountData::prev_mailbox
struct Mailbox * prev_mailbox
Previously selected mailbox.
Definition: adata.h:74
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
Email::replied
bool replied
Email has been replied to.
Definition: email.h:54
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
IS_SPACE
#define IS_SPACE(ch)
Definition: string2.h:38
IMAP_CAP_IMAP4
#define IMAP_CAP_IMAP4
Server supports IMAP4.
Definition: private.h:125
ImapAccountData::capstr
char * capstr
Definition: adata.h:51
Email
The envelope/body of an email.
Definition: email.h:37
mutt_ssl_starttls
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1136
MUTT_ACL_SEEN
#define MUTT_ACL_SEEN
Change the 'seen' status of a message.
Definition: mailbox.h:73
compare_flags_for_copy
static bool compare_flags_for_copy(struct Email *e)
Compare local flags against the server.
Definition: imap.c:298
mutt_str_startswith
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
mutt_str_atoull
int mutt_str_atoull(const char *str, unsigned long long *dst)
Convert ASCII string to an unsigned long long.
Definition: string.c:343
imap_mdata_cache_reset
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:108
mutt_message
#define mutt_message(...)
Definition: logging.h:83
Mailbox::msg_new
int msg_new
Number of new messages.
Definition: mailbox.h:95
IMAP_SELECTED
@ IMAP_SELECTED
Mailbox is selected.
Definition: private.h:112
MX_OPEN_ERROR
@ MX_OPEN_ERROR
Open failed with an error.
Definition: mx.h:87
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
imap_edata_get
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:63
imap_mbox_check
static enum MxStatus imap_mbox_check(struct Mailbox *m)
Check for new mail - Implements MxOps::mbox_check()
Definition: imap.c:2139
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
mx_mbox_ac_link
bool mx_mbox_ac_link(struct Mailbox *m)
Link a Mailbox to an existing or new Account.
Definition: mx.c:272
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
ImapAccountData::nextcmd
int nextcmd
Definition: adata.h:68
NT_MAILBOX_RESORT
@ NT_MAILBOX_RESORT
Email list needs resorting.
Definition: mailbox.h:174
Email::read
bool read
Email is read.
Definition: email.h:51
IMAP_CMD_SINGLE
#define IMAP_CMD_SINGLE
Run a single command.
Definition: private.h:79
IMAP_CAP_QRESYNC
#define IMAP_CAP_QRESYNC
RFC7162.
Definition: private.h:140
C_ConfirmCreate
WHERE bool C_ConfirmCreate
Config: Confirm before creating a new mailbox.
Definition: mutt_globals.h:142
Connection::ssf
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:37
COMMANDS_REGISTER
#define COMMANDS_REGISTER(cmds)
Definition: mutt_commands.h:77
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
ConnAccount::user
char user[128]
Username.
Definition: connaccount.h:55
imap_mbox_open
static enum MxOpenReturns imap_mbox_open(struct Mailbox *m)
Open a mailbox - Implements MxOps::mbox_open()
Definition: imap.c:1904
C_ImapCondstore
bool C_ImapCondstore
Config: (imap) Enable the CONDSTORE extension.
Definition: config.c:41
LL_DEBUG2
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
neomutt_mailboxlist_clear
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
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
Definition: util.c:652
ImapMboxData::uidvalidity
uint32_t uidvalidity
Definition: mdata.h:50
IMAP_CAP_COMPRESS
#define IMAP_CAP_COMPRESS
RFC4978: COMPRESS=DEFLATE.
Definition: private.h:142
Mailbox::pathbuf
struct Buffer pathbuf
Definition: mailbox.h:83
Email::changed
bool changed
Email has been edited.
Definition: email.h:48
imap_ac_add
static bool imap_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
Definition: imap.c:1741
ImapCommand
IMAP command structure.
Definition: private.h:161
imap_cmd_trailer
const char * imap_cmd_trailer(struct ImapAccountData *adata)
Extra information after tagged command response if any.
Definition: command.c:1208
ImapMboxData::name
char * name
Mailbox name.
Definition: mdata.h:40
mx_mbox_find2
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1654
ImapList::name
char * name
Definition: private.h:152
sync_helper
static int sync_helper(struct Mailbox *m, AclFlags right, enum MessageType flag, const char *name)
Sync flag changes to the server.
Definition: imap.c:323
imap_check_mailbox
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1094
imap_login
int imap_login(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:1827
MX_STATUS_OK
@ MX_STATUS_OK
No changes.
Definition: mx.h:74
driver_tags_get_with_hidden
char * driver_tags_get_with_hidden(struct TagList *list)
Get tags with hiddens.
Definition: tags.c:157
ImapAccountData::delim
char delim
Definition: adata.h:72
mutt_error
#define mutt_error(...)
Definition: logging.h:84
imap_mbox_select
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1795
mutt_str_copy
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
MUTT_COMP_NO_FLAGS
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56