NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
imap.c File Reference

IMAP network mailbox. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "imap_private.h"
#include "mutt/mutt.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/conn.h"
#include "gui/lib.h"
#include "mutt.h"
#include "imap.h"
#include "auth.h"
#include "commands.h"
#include "globals.h"
#include "hook.h"
#include "message.h"
#include "mutt_account.h"
#include "mutt_logging.h"
#include "mutt_socket.h"
#include "muttlib.h"
#include "mx.h"
#include "pattern.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

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, int 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, int 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, int flag, const char *name)
 Sync flag changes to the server. More...
 
static int do_search (const struct PatternList *search, bool allpats)
 Perform a search of messages. More...
 
static int compile_search (struct Mailbox *m, const struct PatternList *pat, struct Buffer *buf)
 Convert NeoMutt pattern to IMAP search. 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_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, int 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...
 
int 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 int imap_mbox_check_stats (struct Mailbox *m, int 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_search (struct Mailbox *m, const struct PatternList *pat)
 Find a matching mailbox. 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...
 
int imap_sync_mailbox (struct Mailbox *m, bool expunge, bool close)
 Sync all the changes to the server. More...
 
static struct Accountimap_ac_find (struct Account *a, const char *path)
 Find an Account that matches a Mailbox path - Implements MxOps::ac_find() More...
 
static int 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 int imap_mbox_open (struct Mailbox *m)
 Open a mailbox - Implements MxOps::mbox_open() More...
 
static int imap_mbox_open_append (struct Mailbox *m, OpenMailboxFlags flags)
 Open a Mailbox for appending - Implements MxOps::mbox_open_append() More...
 
static int imap_mbox_check (struct Mailbox *m, int *index_hint)
 Check for new mail - Implements MxOps::mbox_check() More...
 
static int imap_mbox_close (struct Mailbox *m)
 Close a Mailbox - Implements MxOps::mbox_close() More...
 
static int imap_msg_open_new (struct Mailbox *m, struct Message *msg, 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...
 

Variables

bool C_ImapIdle
 Config: (imap) Use the IMAP IDLE extension to check for new mail. More...
 
bool C_ImapRfc5161
 Config: (imap) Use the IMAP ENABLE extension to select capabilities. More...
 
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

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

77 {
78  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
79  {
80  imap_error("check_capabilities", adata->buf);
81  return -1;
82  }
83 
84  if (!((adata->capabilities & IMAP_CAP_IMAP4) || (adata->capabilities & IMAP_CAP_IMAP4REV1)))
85  {
86  mutt_error(
87  _("This IMAP server is ancient. NeoMutt does not work with it."));
88  return -1;
89  }
90 
91  return 0;
92 }
#define _(a)
Definition: message.h:28
Imap command executed or queued successfully.
Definition: imap_private.h:81
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: imap_private.h:121
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:1241
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:778
ImapCapFlags capabilities
Definition: imap_private.h:183
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define IMAP_CAP_IMAP4
Server supports IMAP4.
Definition: imap_private.h:120
+ 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
ptrNULL Failure

return stream following FLAGS response

Definition at line 103 of file imap.c.

104 {
105  /* sanity-check string */
106  const size_t plen = mutt_str_startswith(s, "FLAGS", CASE_IGNORE);
107  if (plen == 0)
108  {
109  mutt_debug(LL_DEBUG1, "not a FLAGS response: %s\n", s);
110  return NULL;
111  }
112  s += plen;
113  SKIPWS(s);
114  if (*s != '(')
115  {
116  mutt_debug(LL_DEBUG1, "bogus FLAGS response: %s\n", s);
117  return NULL;
118  }
119 
120  /* update caller's flags handle */
121  while (*s && (*s != ')'))
122  {
123  s++;
124  SKIPWS(s);
125  const char *flag_word = s;
126  while (*s && (*s != ')') && !IS_SPACE(*s))
127  s++;
128  const char ctmp = *s;
129  *s = '\0';
130  if (*flag_word)
131  mutt_list_insert_tail(hflags, mutt_str_strdup(flag_word));
132  *s = ctmp;
133  }
134 
135  /* note bad flags response */
136  if (*s != ')')
137  {
138  mutt_debug(LL_DEBUG1, "Unterminated FLAGS response: %s\n", s);
139  mutt_list_free(hflags);
140 
141  return NULL;
142  }
143 
144  s++;
145 
146  return s;
147 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
#define SKIPWS(ch)
Definition: string2.h:47
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
Ignore case when comparing strings.
Definition: string2.h:68
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define IS_SPACE(ch)
Definition: string2.h:38
Log at debug level 1.
Definition: logging.h:40
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ 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,
int  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 158 of file imap.c.

160 {
161  if (m->rights & aclflag)
162  if (flag && imap_has_flag(&imap_mdata_get(m)->flags, str))
163  mutt_str_strcat(flags, flsize, str);
164 }
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:966
struct ListHead flags
Definition: imap_private.h:224
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
+ 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,
int  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 179 of file imap.c.

181 {
182  int count = 0; /* number of messages in message set */
183  unsigned int setstart = 0; /* start of current message range */
184  int n;
185  bool started = false;
186 
187  struct ImapAccountData *adata = imap_adata_get(m);
188  if (!adata || (adata->mailbox != m))
189  return -1;
190 
191  for (n = *pos; (n < m->msg_count) && (mutt_buffer_len(buf) < IMAP_MAX_CMDLEN); n++)
192  {
193  struct Email *e = m->emails[n];
194  if (!e)
195  break;
196  bool match = false; /* whether current message matches flag condition */
197  /* don't include pending expunged messages.
198  *
199  * TODO: can we unset active in cmd_parse_expunge() and
200  * cmd_parse_vanished() instead of checking for index != INT_MAX. */
201  if (e->active && (e->index != INT_MAX))
202  {
203  switch (flag)
204  {
205  case MUTT_DELETED:
206  if (e->deleted != imap_edata_get(e)->deleted)
207  match = invert ^ e->deleted;
208  break;
209  case MUTT_FLAG:
210  if (e->flagged != imap_edata_get(e)->flagged)
211  match = invert ^ e->flagged;
212  break;
213  case MUTT_OLD:
214  if (e->old != imap_edata_get(e)->old)
215  match = invert ^ e->old;
216  break;
217  case MUTT_READ:
218  if (e->read != imap_edata_get(e)->read)
219  match = invert ^ e->read;
220  break;
221  case MUTT_REPLIED:
222  if (e->replied != imap_edata_get(e)->replied)
223  match = invert ^ e->replied;
224  break;
225  case MUTT_TAG:
226  if (e->tagged)
227  match = true;
228  break;
229  case MUTT_TRASH:
230  if (e->deleted && !e->purge)
231  match = true;
232  break;
233  }
234  }
235 
236  if (match && (!changed || e->changed))
237  {
238  count++;
239  if (setstart == 0)
240  {
241  setstart = imap_edata_get(e)->uid;
242  if (started)
243  {
244  mutt_buffer_add_printf(buf, ",%u", imap_edata_get(e)->uid);
245  }
246  else
247  {
248  mutt_buffer_add_printf(buf, "%u", imap_edata_get(e)->uid);
249  started = true;
250  }
251  }
252  /* tie up if the last message also matches */
253  else if (n == (m->msg_count - 1))
254  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(e)->uid);
255  }
256  /* End current set if message doesn't match or we've reached the end
257  * of the mailbox via inactive messages following the last match. */
258  else if (setstart && (e->active || (n == adata->mailbox->msg_count - 1)))
259  {
260  if (imap_edata_get(m->emails[n - 1])->uid > setstart)
261  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(m->emails[n - 1])->uid);
262  setstart = 0;
263  }
264  }
265 
266  *pos = n;
267 
268  return count;
269 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
Deleted messages.
Definition: mutt.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
Flagged messages.
Definition: mutt.h:106
struct Mailbox * mailbox
Definition: imap_private.h:205
bool changed
Email has been edited.
Definition: email.h:48
Messages that have been replied to.
Definition: mutt.h:99
bool flagged
Definition: message.h:39
bool deleted
Definition: message.h:38
bool tagged
Email is tagged.
Definition: email.h:44
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
#define IMAP_MAX_CMDLEN
Maximum length of command lines before they must be split (for lazy servers)
Definition: imap_private.h:60
Old messages.
Definition: mutt.h:98
bool active
Message is not to be removed.
Definition: email.h:59
unsigned int uid
32-bit Message UID
Definition: message.h:44
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Tagged messages.
Definition: mutt.h:107
Messages that have been read.
Definition: mutt.h:100
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
bool purge
Skip trash folder when deleting.
Definition: email.h:46
IMAP-specific Account data -.
Definition: imap_private.h:166
bool flagged
Marked important?
Definition: email.h:43
bool deleted
Email is deleted.
Definition: email.h:45
bool replied
Email has been replied to.
Definition: email.h:54
int index
The absolute (unsorted) message number.
Definition: email.h:85
bool read
Definition: message.h:36
Trashed messages.
Definition: mutt.h:112
+ 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 279 of file imap.c.

280 {
281  struct ImapEmailData *edata = e->edata;
282 
283  if (e->read != edata->read)
284  return true;
285  if (e->old != edata->old)
286  return true;
287  if (e->flagged != edata->flagged)
288  return true;
289  if (e->replied != edata->replied)
290  return true;
291 
292  return false;
293 }
bool flagged
Definition: message.h:39
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
bool flagged
Marked important?
Definition: email.h:43
void * edata
Driver-specific data.
Definition: email.h:106
bool replied
Email has been replied to.
Definition: email.h:54
bool read
Definition: message.h:36
IMAP-specific Email data -.
Definition: message.h:33
+ Here is the caller graph for this function:

◆ sync_helper()

static int sync_helper ( struct Mailbox m,
AclFlags  right,
int  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 304 of file imap.c.

305 {
306  int count = 0;
307  int rc;
308  char buf[1024];
309 
310  if (!m)
311  return -1;
312 
313  if ((m->rights & right) == 0)
314  return 0;
315 
316  if ((right == MUTT_ACL_WRITE) && !imap_has_flag(&imap_mdata_get(m)->flags, name))
317  return 0;
318 
319  snprintf(buf, sizeof(buf), "+FLAGS.SILENT (%s)", name);
320  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, false);
321  if (rc < 0)
322  return rc;
323  count += rc;
324 
325  buf[0] = '-';
326  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, true);
327  if (rc < 0)
328  return rc;
329  count += rc;
330 
331  return count;
332 }
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:966
const char * name
Definition: pgpmicalg.c:46
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, int flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:1010
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_search()

static int do_search ( const struct PatternList *  search,
bool  allpats 
)
static

Perform a search of messages.

Parameters
searchList of pattern to match
allpatsMust all patterns match?
Return values
numNumber of patterns search that should be done server-side

Count the number of patterns that can be done by the server (are full-text).

Definition at line 342 of file imap.c.

343 {
344  int rc = 0;
345  const struct Pattern *pat = NULL;
346 
347  SLIST_FOREACH(pat, search, entries)
348  {
349  switch (pat->op)
350  {
351  case MUTT_PAT_BODY:
352  case MUTT_PAT_HEADER:
353  case MUTT_PAT_WHOLE_MSG:
354  if (pat->string_match)
355  rc++;
356  break;
358  rc++;
359  break;
360  default:
361  if (pat->child && do_search(pat->child, true))
362  rc++;
363  }
364 
365  if (!allpats)
366  break;
367  }
368 
369  return rc;
370 }
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:62
Pattern matches email&#39;s header.
Definition: pattern.h:124
A simple (non-regex) pattern.
Definition: pattern.h:49
bool string_match
Check a string for a match.
Definition: pattern.h:54
Server-side pattern matches.
Definition: pattern.h:143
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: pattern.h:51
Pattern matches email&#39;s body.
Definition: pattern.h:123
static int do_search(const struct PatternList *search, bool allpats)
Perform a search of messages.
Definition: imap.c:342
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:230
Pattern matches raw email text.
Definition: pattern.h:126
+ Here is the caller graph for this function:

◆ compile_search()

static int compile_search ( struct Mailbox m,
const struct PatternList *  pat,
struct Buffer buf 
)
static

Convert NeoMutt pattern to IMAP search.

Parameters
mMailbox
patPattern to convert
bufBuffer for result
Return values
0Success
-1Failure

Convert neomutt Pattern to IMAP SEARCH command containing only elements that require full-text search (neomutt already has what it needs for most match types, and does a better job (eg server doesn't support regexes).

Definition at line 384 of file imap.c.

385 {
386  struct Pattern *firstpat = SLIST_FIRST(pat);
387 
388  if (do_search(pat, false) == 0)
389  return 0;
390 
391  if (firstpat->pat_not)
392  mutt_buffer_addstr(buf, "NOT ");
393 
394  if (firstpat->child)
395  {
396  int clauses;
397 
398  clauses = do_search(firstpat->child, true);
399  if (clauses > 0)
400  {
401  mutt_buffer_addch(buf, '(');
402 
403  while (clauses)
404  {
405  if (do_search(firstpat->child, false))
406  {
407  if ((firstpat->op == MUTT_PAT_OR) && (clauses > 1))
408  mutt_buffer_addstr(buf, "OR ");
409  clauses--;
410 
411  if (compile_search(m, firstpat->child, buf) < 0)
412  return -1;
413 
414  if (clauses)
415  mutt_buffer_addch(buf, ' ');
416  }
417 
418  SLIST_REMOVE_HEAD(firstpat->child, entries);
419  }
420 
421  mutt_buffer_addch(buf, ')');
422  }
423  }
424  else
425  {
426  char term[256];
427  char *delim = NULL;
428 
429  switch (firstpat->op)
430  {
431  case MUTT_PAT_HEADER:
432  mutt_buffer_addstr(buf, "HEADER ");
433 
434  /* extract header name */
435  delim = strchr(firstpat->p.str, ':');
436  if (!delim)
437  {
438  mutt_error(_("Header search without header name: %s"), firstpat->p.str);
439  return -1;
440  }
441  *delim = '\0';
442  imap_quote_string(term, sizeof(term), firstpat->p.str, false);
443  mutt_buffer_addstr(buf, term);
444  mutt_buffer_addch(buf, ' ');
445 
446  /* and field */
447  *delim = ':';
448  delim++;
449  SKIPWS(delim);
450  imap_quote_string(term, sizeof(term), delim, false);
451  mutt_buffer_addstr(buf, term);
452  break;
453  case MUTT_PAT_BODY:
454  mutt_buffer_addstr(buf, "BODY ");
455  imap_quote_string(term, sizeof(term), firstpat->p.str, false);
456  mutt_buffer_addstr(buf, term);
457  break;
458  case MUTT_PAT_WHOLE_MSG:
459  mutt_buffer_addstr(buf, "TEXT ");
460  imap_quote_string(term, sizeof(term), firstpat->p.str, false);
461  mutt_buffer_addstr(buf, term);
462  break;
464  {
465  struct ImapAccountData *adata = imap_adata_get(m);
466  if (!(adata->capabilities & IMAP_CAP_X_GM_EXT_1))
467  {
468  mutt_error(_("Server-side custom search not supported: %s"),
469  firstpat->p.str);
470  return -1;
471  }
472  }
473  mutt_buffer_addstr(buf, "X-GM-RAW ");
474  imap_quote_string(term, sizeof(term), firstpat->p.str, false);
475  mutt_buffer_addstr(buf, term);
476  break;
477  }
478  }
479 
480  return 0;
481 }
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:62
Pattern matches email&#39;s header.
Definition: pattern.h:124
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:959
#define _(a)
Definition: message.h:28
#define SLIST_REMOVE_HEAD(head, field)
Definition: queue.h:290
A simple (non-regex) pattern.
Definition: pattern.h:49
#define SKIPWS(ch)
Definition: string2.h:47
bool pat_not
Pattern should be inverted (not)
Definition: pattern.h:52
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
Server-side pattern matches.
Definition: pattern.h:143
#define SLIST_FIRST(head)
Definition: queue.h:228
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Either pattern can match.
Definition: pattern.h:107
static int compile_search(struct Mailbox *m, const struct PatternList *pat, struct Buffer *buf)
Convert NeoMutt pattern to IMAP search.
Definition: imap.c:384
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: pattern.h:51
ImapCapFlags capabilities
Definition: imap_private.h:183
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
IMAP-specific Account data -.
Definition: imap_private.h:166
Pattern matches email&#39;s body.
Definition: pattern.h:123
union Pattern::@2 p
static int do_search(const struct PatternList *search, bool allpats)
Perform a search of messages.
Definition: imap.c:342
char * str
String, if string_match is set.
Definition: pattern.h:66
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CAP_X_GM_EXT_1
https://developers.google.com/gmail/imap/imap-extensions
Definition: imap_private.h:137
Pattern matches raw email text.
Definition: pattern.h:126
+ 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 493 of file imap.c.

494 {
495  size_t pos = start;
496 
497  while ((pos < dlen) && dest[pos] && (dest[pos] == src[pos]))
498  pos++;
499  dest[pos] = '\0';
500 
501  return pos;
502 }
+ 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 514 of file imap.c.

515 {
516  // struct Connection *conn = NULL;
517  int rc = -1;
518  size_t matchlen;
519 
520  matchlen = mutt_str_strlen(buf);
521  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
522  struct MailboxNode *np = NULL;
523  STAILQ_FOREACH(np, &ml, entries)
524  {
526  continue;
527 
528  if (rc)
529  {
530  mutt_str_strfcpy(buf, mailbox_path(np->mailbox), buflen);
531  rc = 0;
532  }
533  else
534  longest_common_prefix(buf, mailbox_path(np->mailbox), matchlen, buflen);
535  }
537 
538 #if 0
539  TAILQ_FOREACH(conn, mutt_socket_head(), entries)
540  {
541  struct Url url;
542  char urlstr[1024];
543 
544  if (conn->account.type != MUTT_ACCT_TYPE_IMAP)
545  continue;
546 
547  mutt_account_tourl(&conn->account, &url);
548  /* FIXME: how to handle multiple users on the same host? */
549  url.user = NULL;
550  url.path = NULL;
551  url_tostring(&url, urlstr, sizeof(urlstr), 0);
552  if (mutt_str_strncmp(buf, urlstr, matchlen) == 0)
553  {
554  if (rc)
555  {
556  mutt_str_strfcpy(buf, urlstr, buflen);
557  rc = 0;
558  }
559  else
560  longest_common_prefix(buf, urlstr, matchlen, buflen);
561  }
562  }
563 #endif
564 
565  return rc;
566 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
Match any Mailbox type.
Definition: mailbox.h:44
Match case when comparing strings.
Definition: string2.h:67
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
int url_tostring(struct Url *u, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:399
Container for Accounts, Notifications.
Definition: neomutt.h:35
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic)
Get a List of all Mailboxes.
Definition: neomutt.c:157
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
Imap Account.
Definition: mutt_account.h:52
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
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:493
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:642
void mutt_account_tourl(struct ConnAccount *account, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:145
List of Mailboxes.
Definition: mailbox.h:144
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ 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 575 of file imap.c.

576 {
577  char buf[2048], mbox[1024];
578 
579  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), mailbox);
580  snprintf(buf, sizeof(buf), "CREATE %s", mbox);
581 
582  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
583  {
584  mutt_error(_("CREATE failed: %s"), imap_cmd_trailer(adata));
585  return -1;
586  }
587 
588  return 0;
589 }
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:1033
#define _(a)
Definition: message.h:28
const char * imap_cmd_trailer(struct ImapAccountData *adata)
Extra information after tagged command response if any.
Definition: command.c:1203
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1241
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

602 {
603  if (imap_path_status(path, false) >= 0)
604  return 0;
605  return -1;
606 }
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1310
char * path
Path.
Definition: url.h:73
+ 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 616 of file imap.c.

617 {
618  char oldmbox[1024];
619  char newmbox[1024];
620  int rc = 0;
621 
622  imap_munge_mbox_name(adata->unicode, oldmbox, sizeof(oldmbox), oldname);
623  imap_munge_mbox_name(adata->unicode, newmbox, sizeof(newmbox), newname);
624 
625  struct Buffer *buf = mutt_buffer_pool_get();
626  mutt_buffer_printf(buf, "RENAME %s %s", oldmbox, newmbox);
627 
629  rc = -1;
630 
632 
633  return rc;
634 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1033
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1241
#define mutt_b2s(buf)
Definition: buffer.h:41
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

644 {
645  char buf[PATH_MAX + 7];
646  char mbox[PATH_MAX];
647  struct Url *url = url_parse(path);
648 
649  struct ImapAccountData *adata = imap_adata_get(m);
650  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), url->path);
651  url_free(&url);
652  snprintf(buf, sizeof(buf), "DELETE %s", mbox);
654  return -1;
655 
656  return 0;
657 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
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:1033
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1241
#define PATH_MAX
Definition: mutt.h:50
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: imap_private.h:166
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:130
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ 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 663 of file imap.c.

664 {
665  /* we set status here to let imap_handle_untagged know we _expect_ to
666  * receive a bye response (so it doesn't freak out and close the conn) */
667  if (adata->state == IMAP_DISCONNECTED)
668  {
669  return;
670  }
671 
672  adata->status = IMAP_BYE;
673  imap_cmd_start(adata, "LOGOUT");
674  if ((C_ImapPollTimeout <= 0) || (mutt_socket_poll(adata->conn, C_ImapPollTimeout) != 0))
675  {
676  while (imap_cmd_step(adata) == IMAP_RES_CONTINUE)
677  ;
678  }
679  mutt_socket_close(adata->conn);
680  adata->state = IMAP_DISCONNECTED;
681 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
WHERE short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: globals.h:156
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:190
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
Logged out from server.
Definition: imap_private.h:95
Disconnected from server.
Definition: imap_private.h:104
struct Connection * conn
Definition: imap_private.h:168
+ 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 688 of file imap.c.

689 {
690  struct Account *np = NULL;
691  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
692  {
693  if (np->magic != MUTT_IMAP)
694  continue;
695 
696  struct ImapAccountData *adata = np->adata;
697  if (!adata)
698  continue;
699 
700  struct Connection *conn = adata->conn;
701  if (!conn || (conn->fd < 0))
702  continue;
703 
704  mutt_message(_("Closing connection to %s..."), conn->account.host);
705  imap_logout(np->adata);
707  }
708 }
struct ConnAccount account
Definition: connection.h:36
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
#define mutt_message(...)
Definition: logging.h:83
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:39
A group of associated Mailboxes.
Definition: account.h:36
An open network connection (socket)
Definition: connection.h:34
static void imap_logout(struct ImapAccountData *adata)
Gracefully log out of server.
Definition: imap.c:663
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:35
char host[128]
Definition: connaccount.h:36
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
enum MailboxType magic
Type of Mailboxes this Account contains.
Definition: account.h:38
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: imap_private.h:166
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
struct Connection * conn
Definition: imap_private.h:168
+ 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 724 of file imap.c.

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

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

◆ imap_open_connection()

int imap_open_connection ( struct ImapAccountData adata)

Open an IMAP connection.

Parameters
adataImap Account data
Return values
0Success
-1Failure

Definition at line 853 of file imap.c.

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

◆ imap_close_connection()

void imap_close_connection ( struct ImapAccountData adata)

Close an IMAP connection.

Parameters
adataImap Account data

Definition at line 943 of file imap.c.

944 {
945  if (adata->state != IMAP_DISCONNECTED)
946  {
947  mutt_socket_close(adata->conn);
948  adata->state = IMAP_DISCONNECTED;
949  }
950  adata->seqno = 0;
951  adata->nextcmd = 0;
952  adata->lastcmd = 0;
953  adata->status = 0;
954  memset(adata->cmds, 0, sizeof(struct ImapCommand) * adata->cmdslots);
955 }
struct ImapCommand * cmds
Definition: imap_private.h:198
unsigned int seqno
tag sequence number, e.g. &#39;{seqid}0001&#39;
Definition: imap_private.h:185
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
IMAP command structure.
Definition: imap_private.h:155
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
Disconnected from server.
Definition: imap_private.h:104
struct Connection * conn
Definition: imap_private.h:168
+ 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 '*'.

Definition at line 966 of file imap.c.

967 {
968  if (STAILQ_EMPTY(flag_list))
969  return false;
970 
971  struct ListNode *np = NULL;
972  STAILQ_FOREACH(np, flag_list, entries)
973  {
974  if (mutt_str_strcasecmp(np->data, flag) == 0)
975  return true;
976 
977  if (mutt_str_strcmp(np->data, "\\*") == 0)
978  return true;
979  }
980 
981  return false;
982 }
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:35
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define STAILQ_EMPTY(head)
Definition: queue.h:345
A List node for strings.
Definition: list.h:33
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ 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 987 of file imap.c.

988 {
989  const struct Email *ea = *(struct Email const *const *) a;
990  const struct Email *eb = *(struct Email const *const *) b;
991  return imap_edata_get((struct Email *) ea)->uid -
992  imap_edata_get((struct Email *) eb)->uid;
993 }
The envelope/body of an email.
Definition: email.h:37
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
unsigned int uid
32-bit Message UID
Definition: message.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_exec_msgset()

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

Prepare commands for all messages matching conditions.

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

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

Definition at line 1010 of file imap.c.

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

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

◆ imap_check_mailbox()

int 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 values
MUTT_REOPENEDmailbox has been externally modified
MUTT_NEW_MAILnew mail has arrived
0no change
-1error

Definition at line 1190 of file imap.c.

1191 {
1192  if (!m || !m->account)
1193  return -1;
1194 
1195  struct ImapAccountData *adata = imap_adata_get(m);
1196  struct ImapMboxData *mdata = imap_mdata_get(m);
1197 
1198  /* overload keyboard timeout to avoid many mailbox checks in a row.
1199  * Most users don't like having to wait exactly when they press a key. */
1200  int rc = 0;
1201 
1202  /* try IDLE first, unless force is set */
1203  if (!force && C_ImapIdle && (adata->capabilities & IMAP_CAP_IDLE) &&
1204  ((adata->state != IMAP_IDLE) || (mutt_date_epoch() >= adata->lastread + C_ImapKeepalive)))
1205  {
1206  if (imap_cmd_idle(adata) < 0)
1207  return -1;
1208  }
1209  if (adata->state == IMAP_IDLE)
1210  {
1211  while ((rc = mutt_socket_poll(adata->conn, 0)) > 0)
1212  {
1213  if (imap_cmd_step(adata) != IMAP_RES_CONTINUE)
1214  {
1215  mutt_debug(LL_DEBUG1, "Error reading IDLE response\n");
1216  return -1;
1217  }
1218  }
1219  if (rc < 0)
1220  {
1221  mutt_debug(LL_DEBUG1, "Poll failed, disabling IDLE\n");
1222  adata->capabilities &= ~IMAP_CAP_IDLE; // Clear the flag
1223  }
1224  }
1225 
1226  if ((force || ((adata->state != IMAP_IDLE) &&
1227  (mutt_date_epoch() >= adata->lastread + C_Timeout))) &&
1228  (imap_exec(adata, "NOOP", IMAP_CMD_POLL) != IMAP_EXEC_SUCCESS))
1229  {
1230  return -1;
1231  }
1232 
1233  /* We call this even when we haven't run NOOP in case we have pending
1234  * changes to process, since we can reopen here. */
1235  imap_cmd_finish(adata);
1236 
1237  if (mdata->check_status & IMAP_EXPUNGE_PENDING)
1238  rc = MUTT_REOPENED;
1239  else if (mdata->check_status & IMAP_NEWMAIL_PENDING)
1240  rc = MUTT_NEW_MAIL;
1241  else if (mdata->check_status & IMAP_FLAGS_PENDING)
1242  rc = MUTT_FLAGS;
1243 
1245 
1246  return rc;
1247 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: imap_private.h:66
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: imap_private.h:68
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:74
Imap command executed or queued successfully.
Definition: imap_private.h:81
Connection is idle.
Definition: imap_private.h:110
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:190
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
Definition: command.c:1358
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: imap_private.h:220
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:1241
WHERE short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: globals.h:155
Nondestructive flags change (IMAP)
Definition: mx.h:75
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: globals.h:151
#define IMAP_OPEN_NO_FLAGS
No flags are set.
Definition: imap_private.h:63
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1295
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
ImapCapFlags capabilities
Definition: imap_private.h:183
time_t lastread
last time we read a command for the server
Definition: imap_private.h:186
bool C_ImapIdle
Config: (imap) Use the IMAP IDLE extension to check for new mail.
Definition: imap.c:64
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
IMAP-specific Account data -.
Definition: imap_private.h:166
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:130
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
#define IMAP_CAP_IDLE
RFC2177: IDLE.
Definition: imap_private.h:131
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: imap_private.h:67
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
New mail received in Mailbox.
Definition: mx.h:72
Mailbox was reopened.
Definition: mx.h:74
struct Connection * conn
Definition: imap_private.h:168
+ 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 1256 of file imap.c.

1257 {
1258  char *uid_validity_flag = NULL;
1259  char cmd[2048];
1260 
1261  if (!adata || !mdata)
1262  return -1;
1263 
1264  /* Don't issue STATUS on the selected mailbox, it will be NOOPed or
1265  * IDLEd elsewhere.
1266  * adata->mailbox may be NULL for connections other than the current
1267  * mailbox's. */
1268  if (adata->mailbox && (adata->mailbox->mdata == mdata))
1269  {
1270  adata->mailbox->has_new = false;
1271  return mdata->messages;
1272  }
1273 
1274  if (adata->capabilities & IMAP_CAP_IMAP4REV1)
1275  uid_validity_flag = "UIDVALIDITY";
1276  else if (adata->capabilities & IMAP_CAP_STATUS)
1277  uid_validity_flag = "UID-VALIDITY";
1278  else
1279  {
1280  mutt_debug(LL_DEBUG2, "Server doesn't support STATUS\n");
1281  return -1;
1282  }
1283 
1284  snprintf(cmd, sizeof(cmd), "STATUS %s (UIDNEXT %s UNSEEN RECENT MESSAGES)",
1285  mdata->munge_name, uid_validity_flag);
1286 
1287  int rc = imap_exec(adata, cmd, queue ? IMAP_CMD_QUEUE : IMAP_CMD_NO_FLAGS | IMAP_CMD_POLL);
1288  if (rc < 0)
1289  {
1290  mutt_debug(LL_DEBUG1, "Error queueing command\n");
1291  return rc;
1292  }
1293  return mdata->messages;
1294 }
struct Mailbox * mailbox
Definition: imap_private.h:205
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:74
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
Log at debug level 2.
Definition: logging.h:41
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: imap_private.h:121
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:1241
#define IMAP_CAP_STATUS
Server supports STATUS command.
Definition: imap_private.h:122
ImapCapFlags capabilities
Definition: imap_private.h:183
Log at debug level 1.
Definition: logging.h:40
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:216
unsigned int messages
Definition: imap_private.h:228
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mbox_check_stats()

static int imap_mbox_check_stats ( struct Mailbox m,
int  flags 
)
static

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

Definition at line 1299 of file imap.c.

1300 {
1301  return imap_mailbox_status(m, true);
1302 }
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1336
+ 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 1310 of file imap.c.

1311 {
1312  struct Mailbox *m = mx_mbox_find2(path);
1313  if (m)
1314  return imap_mailbox_status(m, queue);
1315 
1316  // FIXME(sileht): Is that case possible ?
1317  struct ImapAccountData *adata = NULL;
1318  struct ImapMboxData *mdata = NULL;
1319 
1320  if (imap_adata_find(path, &adata, &mdata) < 0)
1321  return -1;
1322  int rc = imap_status(adata, mdata, queue);
1323  imap_mdata_free((void *) &mdata);
1324  return rc;
1325 }
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:227
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1256
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1576
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:130
void * mdata
Driver specific data.
Definition: mailbox.h:135
A mailbox.
Definition: mailbox.h:80
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1336
IMAP-specific Account data -.
Definition: imap_private.h:166
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
+ 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 1336 of file imap.c.

1337 {
1338  struct ImapAccountData *adata = imap_adata_get(m);
1339  struct ImapMboxData *mdata = imap_mdata_get(m);
1340  if (!adata || !mdata)
1341  return -1;
1342  return imap_status(adata, mdata, queue);
1343 }
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1256
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
void * mdata
Driver specific data.
Definition: mailbox.h:135
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
IMAP-specific Account data -.
Definition: imap_private.h:166
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_search()

int imap_search ( struct Mailbox m,
const struct PatternList *  pat 
)

Find a matching mailbox.

Parameters
mMailbox
patPattern to match
Return values
0Success
-1Failure

Definition at line 1352 of file imap.c.

1353 {
1354  struct Buffer buf;
1355  struct ImapAccountData *adata = imap_adata_get(m);
1356  for (int i = 0; i < m->msg_count; i++)
1357  {
1358  struct Email *e = m->emails[i];
1359  if (!e)
1360  break;
1361  e->matched = false;
1362  }
1363 
1364  if (do_search(pat, true) == 0)
1365  return 0;
1366 
1367  mutt_buffer_init(&buf);
1368  mutt_buffer_addstr(&buf, "UID SEARCH ");
1369  if (compile_search(m, pat, &buf) < 0)
1370  {
1371  FREE(&buf.data);
1372  return -1;
1373  }
1374  if (imap_exec(adata, buf.data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1375  {
1376  FREE(&buf.data);
1377  return -1;
1378  }
1379 
1380  FREE(&buf.data);
1381  return 0;
1382 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
String manipulation buffer.
Definition: buffer.h:33
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1241
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
static int compile_search(struct Mailbox *m, const struct PatternList *pat, struct Buffer *buf)
Convert NeoMutt pattern to IMAP search.
Definition: imap.c:384
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
IMAP-specific Account data -.
Definition: imap_private.h:166
static int do_search(const struct PatternList *search, bool allpats)
Perform a search of messages.
Definition: imap.c:342
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
bool matched
Search matches this Email.
Definition: email.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

1392 {
1393  struct ImapAccountData *adata = NULL;
1394  struct ImapMboxData *mdata = NULL;
1395  char buf[2048];
1396  char errstr[256];
1397  struct Buffer err, token;
1398 
1399  if (imap_adata_find(path, &adata, &mdata) < 0)
1400  return -1;
1401 
1403  {
1404  char mbox[1024];
1405  mutt_buffer_init(&token);
1406  mutt_buffer_init(&err);
1407  err.data = errstr;
1408  err.dsize = sizeof(errstr);
1409  size_t len = snprintf(mbox, sizeof(mbox), "%smailboxes ", subscribe ? "" : "un");
1410  imap_quote_string(mbox + len, sizeof(mbox) - len, path, true);
1411  if (mutt_parse_rc_line(mbox, &token, &err))
1412  mutt_debug(LL_DEBUG1, "Error adding subscribed mailbox: %s\n", errstr);
1413  FREE(&token.data);
1414  }
1415 
1416  if (subscribe)
1417  mutt_message(_("Subscribing to %s..."), mdata->name);
1418  else
1419  mutt_message(_("Unsubscribing from %s..."), mdata->name);
1420 
1421  snprintf(buf, sizeof(buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mdata->munge_name);
1422 
1423  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1424  {
1425  imap_mdata_free((void *) &mdata);
1426  return -1;
1427  }
1428 
1429  if (subscribe)
1430  mutt_message(_("Subscribed to %s"), mdata->name);
1431  else
1432  mutt_message(_("Unsubscribed from %s"), mdata->name);
1433  imap_mdata_free((void *) &mdata);
1434  return 0;
1435 }
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:959
#define mutt_message(...)
Definition: logging.h:83
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:227
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Imap command executed or queued successfully.
Definition: imap_private.h:81
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:130
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:1241
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:215
WHERE bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: globals.h:222
IMAP-specific Account data -.
Definition: imap_private.h:166
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:216
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:3252
+ 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 1448 of file imap.c.

1449 {
1450  struct ImapAccountData *adata = NULL;
1451  struct ImapMboxData *mdata = NULL;
1452  char tmp[2048];
1453  struct ImapList listresp;
1454  char completion[1024];
1455  int clen;
1456  size_t matchlen = 0;
1457  int completions = 0;
1458  int rc;
1459 
1460  if (imap_adata_find(path, &adata, &mdata) < 0)
1461  {
1462  mutt_str_strfcpy(buf, path, buflen);
1463  return complete_hosts(buf, buflen);
1464  }
1465 
1466  /* fire off command */
1467  snprintf(tmp, sizeof(tmp), "%s \"\" \"%s%%\"",
1468  C_ImapListSubscribed ? "LSUB" : "LIST", mdata->real_name);
1469 
1470  imap_cmd_start(adata, tmp);
1471 
1472  /* and see what the results are */
1473  mutt_str_strfcpy(completion, mdata->name, sizeof(completion));
1474  imap_mdata_free((void *) &mdata);
1475 
1476  adata->cmdresult = &listresp;
1477  do
1478  {
1479  listresp.name = NULL;
1480  rc = imap_cmd_step(adata);
1481 
1482  if ((rc == IMAP_RES_CONTINUE) && listresp.name)
1483  {
1484  /* if the folder isn't selectable, append delimiter to force browse
1485  * to enter it on second tab. */
1486  if (listresp.noselect)
1487  {
1488  clen = strlen(listresp.name);
1489  listresp.name[clen++] = listresp.delim;
1490  listresp.name[clen] = '\0';
1491  }
1492  /* copy in first word */
1493  if (!completions)
1494  {
1495  mutt_str_strfcpy(completion, listresp.name, sizeof(completion));
1496  matchlen = strlen(completion);
1497  completions++;
1498  continue;
1499  }
1500 
1501  matchlen = longest_common_prefix(completion, listresp.name, 0, matchlen);
1502  completions++;
1503  }
1504  } while (rc == IMAP_RES_CONTINUE);
1505  adata->cmdresult = NULL;
1506 
1507  if (completions)
1508  {
1509  /* reformat output */
1510  imap_qualify_path(buf, buflen, &adata->conn_account, completion);
1511  mutt_pretty_mailbox(buf, buflen);
1512  return 0;
1513  }
1514 
1515  return -1;
1516 }
WHERE bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: globals.h:224
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:227
struct ConnAccount conn_account
Definition: imap_private.h:169
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:942
Items in an IMAP browser.
Definition: imap_private.h:144
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:514
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:130
void * mdata
Driver specific data.
Definition: mailbox.h:135
char * name
Definition: imap_private.h:146
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
char * name
Mailbox name.
Definition: imap_private.h:215
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:627
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: imap_private.h:217
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
IMAP-specific Account data -.
Definition: imap_private.h:166
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:493
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
struct ImapList * cmdresult
Definition: imap_private.h:195
+ 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 1526 of file imap.c.

1527 {
1528  char prompt[1024];
1529  int rc = -1;
1530  bool triedcreate = false;
1531  enum QuadOption err_continue = MUTT_NO;
1532 
1533  struct ImapAccountData *adata = imap_adata_get(m);
1534  struct ImapAccountData *dest_adata = NULL;
1535  struct ImapMboxData *dest_mdata = NULL;
1536 
1537  if (imap_adata_find(dest, &dest_adata, &dest_mdata) < 0)
1538  return -1;
1539 
1540  struct Buffer sync_cmd = mutt_buffer_make(0);
1541 
1542  /* check that the save-to folder is in the same account */
1543  if (!mutt_account_match(&(adata->conn->account), &(dest_adata->conn->account)))
1544  {
1545  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1546  goto out;
1547  }
1548 
1549  for (int i = 0; i < m->msg_count; i++)
1550  {
1551  struct Email *e = m->emails[i];
1552  if (!e)
1553  break;
1554  if (e->active && e->changed && e->deleted && !e->purge)
1555  {
1556  rc = imap_sync_message_for_copy(m, e, &sync_cmd, &err_continue);
1557  if (rc < 0)
1558  {
1559  mutt_debug(LL_DEBUG1, "could not sync\n");
1560  goto out;
1561  }
1562  }
1563  }
1564 
1565  /* loop in case of TRYCREATE */
1566  do
1567  {
1568  rc = imap_exec_msgset(m, "UID COPY", dest_mdata->munge_name, MUTT_TRASH, false, false);
1569  if (rc == 0)
1570  {
1571  mutt_debug(LL_DEBUG1, "No messages to trash\n");
1572  rc = -1;
1573  goto out;
1574  }
1575  else if (rc < 0)
1576  {
1577  mutt_debug(LL_DEBUG1, "could not queue copy\n");
1578  goto out;
1579  }
1580  else
1581  {
1582  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1583  rc, dest_mdata->name);
1584  }
1585 
1586  /* let's get it on */
1587  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1588  if (rc == IMAP_EXEC_ERROR)
1589  {
1590  if (triedcreate)
1591  {
1592  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", dest_mdata->name);
1593  break;
1594  }
1595  /* bail out if command failed for reasons other than nonexistent target */
1596  if (!mutt_str_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]", CASE_IGNORE))
1597  break;
1598  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1599  snprintf(prompt, sizeof(prompt), _("Create %s?"), dest_mdata->name);
1600  if (C_Confirmcreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1601  {
1602  mutt_clear_error();
1603  goto out;
1604  }
1605  if (imap_create_mailbox(adata, dest_mdata->name) < 0)
1606  break;
1607  triedcreate = true;
1608  }
1609  } while (rc == IMAP_EXEC_ERROR);
1610 
1611  if (rc != IMAP_EXEC_SUCCESS)
1612  {
1613  imap_error("imap_fast_trash", adata->buf);
1614  goto out;
1615  }
1616 
1617  rc = IMAP_EXEC_SUCCESS;
1618 
1619 out:
1620  mutt_buffer_dealloc(&sync_cmd);
1621  imap_mdata_free((void *) &dest_mdata);
1622 
1623  return ((rc == IMAP_EXEC_SUCCESS) ? 0 : -1);
1624 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
struct ConnAccount account
Definition: connection.h:36
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:227
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
WHERE bool C_Confirmcreate
Config: Confirm before creating a new mailbox.
Definition: globals.h:208
Imap command executed or queued successfully.
Definition: imap_private.h:81
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:130
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, int flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:1010
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
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:1241
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:1088
bool active
Message is not to be removed.
Definition: email.h:59
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:778
char * name
Mailbox name.
Definition: imap_private.h:215
bool mutt_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare account info (host/port/user)
Definition: mutt_account.c:61
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
Ignore case when comparing strings.
Definition: string2.h:68
bool purge
Skip trash folder when deleting.
Definition: email.h:46
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:894
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:575
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
IMAP-specific Account data -.
Definition: imap_private.h:166
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
bool deleted
Email is deleted.
Definition: email.h:45
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:216
Trashed messages.
Definition: mutt.h:112
Log at debug level 3.
Definition: logging.h:42
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
struct Connection * conn
Definition: imap_private.h:168
Imap command failure.
Definition: imap_private.h:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_sync_mailbox()

int 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
0Success
-1Error

Definition at line 1634 of file imap.c.

1635 {
1636  if (!m)
1637  return -1;
1638 
1639  struct Email **emails = NULL;
1640  int oldsort;
1641  int rc;
1642 
1643  struct ImapAccountData *adata = imap_adata_get(m);
1644  struct ImapMboxData *mdata = imap_mdata_get(m);
1645 
1646  if (adata->state < IMAP_SELECTED)
1647  {
1648  mutt_debug(LL_DEBUG2, "no mailbox selected\n");
1649  return -1;
1650  }
1651 
1652  /* This function is only called when the calling code expects the context
1653  * to be changed. */
1654  imap_allow_reopen(m);
1655 
1656  rc = imap_check_mailbox(m, false);
1657  if (rc < 0)
1658  return rc;
1659 
1660  /* if we are expunging anyway, we can do deleted messages very quickly... */
1661  if (expunge && (m->rights & MUTT_ACL_DELETE))
1662  {
1663  rc = imap_exec_msgset(m, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
1664  MUTT_DELETED, true, false);
1665  if (rc < 0)
1666  {
1667  mutt_error(_("Expunge failed"));
1668  return rc;
1669  }
1670 
1671  if (rc > 0)
1672  {
1673  /* mark these messages as unchanged so second pass ignores them. Done
1674  * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
1675  for (int i = 0; i < m->msg_count; i++)
1676  {
1677  struct Email *e = m->emails[i];
1678  if (!e)
1679  break;
1680  if (e->deleted && e->changed)
1681  e->active = false;
1682  }
1683  mutt_message(ngettext("Marking %d message deleted...",
1684  "Marking %d messages deleted...", rc),
1685  rc);
1686  }
1687  }
1688 
1689 #ifdef USE_HCACHE
1690  mdata->hcache = imap_hcache_open(adata, mdata);
1691 #endif
1692 
1693  /* save messages with real (non-flag) changes */
1694  for (int i = 0; i < m->msg_count; i++)
1695  {
1696  struct Email *e = m->emails[i];
1697  if (!e)
1698  break;
1699 
1700  if (e->deleted)
1701  {
1702  imap_cache_del(m, e);
1703 #ifdef USE_HCACHE
1704  imap_hcache_del(mdata, imap_edata_get(e)->uid);
1705 #endif
1706  }
1707 
1708  if (e->active && e->changed)
1709  {
1710 #ifdef USE_HCACHE
1711  imap_hcache_put(mdata, e);
1712 #endif
1713  /* if the message has been rethreaded or attachments have been deleted
1714  * we delete the message and reupload it.
1715  * This works better if we're expunging, of course. */
1716  /* TODO: why the e->env check? */
1717  if ((e->env && e->env->changed) || e->attach_del)
1718  {
1719  /* L10N: The plural is chosen by the last %d, i.e. the total number */
1720  mutt_message(ngettext("Saving changed message... [%d/%d]",
1721  "Saving changed messages... [%d/%d]", m->msg_count),
1722  i + 1, m->msg_count);
1723  bool save_append = m->append;
1724  m->append = true;
1725  mutt_save_message_ctx(e, true, false, false, m);
1726  m->append = save_append;
1727  /* TODO: why the check for h->env? Is this possible? */
1728  if (e->env)
1729  e->env->changed = 0;
1730  }
1731  }
1732  }
1733 
1734 #ifdef USE_HCACHE
1735  imap_hcache_close(mdata);
1736 #endif
1737 
1738  /* presort here to avoid doing 10 resorts in imap_exec_msgset */
1739  oldsort = C_Sort;
1740  if (C_Sort != SORT_ORDER)
1741  {
1742  emails = m->emails;
1743  m->emails = mutt_mem_malloc(m->msg_count * sizeof(struct Email *));
1744  memcpy(m->emails, emails, m->msg_count * sizeof(struct Email *));
1745 
1746  C_Sort = SORT_ORDER;
1747  qsort(m->emails, m->msg_count, sizeof(struct Email *), mutt_get_sort_func(SORT_ORDER));
1748  }
1749 
1750  rc = sync_helper(m, MUTT_ACL_DELETE, MUTT_DELETED, "\\Deleted");
1751  if (rc >= 0)
1752  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_FLAG, "\\Flagged");
1753  if (rc >= 0)
1754  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_OLD, "Old");
1755  if (rc >= 0)
1756  rc |= sync_helper(m, MUTT_ACL_SEEN, MUTT_READ, "\\Seen");
1757  if (rc >= 0)
1758  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
1759 
1760  if (oldsort != C_Sort)
1761  {
1762  C_Sort = oldsort;
1763  FREE(&m->emails);
1764  m->emails = emails;
1765  }
1766 
1767  /* Flush the queued flags if any were changed in sync_helper. */
1768  if (rc > 0)
1769  if (imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1770  rc = -1;
1771 
1772  if (rc < 0)
1773  {
1774  if (close)
1775  {
1776  if (mutt_yesorno(_("Error saving flags. Close anyway?"), MUTT_NO) == MUTT_YES)
1777  {
1778  adata->state = IMAP_AUTHENTICATED;
1779  return 0;
1780  }
1781  }
1782  else
1783  mutt_error(_("Error saving flags"));
1784  return -1;
1785  }
1786 
1787  /* Update local record of server state to reflect the synchronization just
1788  * completed. imap_read_headers always overwrites hcache-origin flags, so
1789  * there is no need to mutate the hcache after flag-only changes. */
1790  for (int i = 0; i < m->msg_count; i++)
1791  {
1792  struct Email *e = m->emails[i];
1793  if (!e)
1794  break;
1795  struct ImapEmailData *edata = imap_edata_get(e);
1796  edata->deleted = e->deleted;
1797  edata->flagged = e->flagged;
1798  edata->old = e->old;
1799  edata->read = e->read;
1800  edata->replied = e->replied;
1801  e->changed = false;
1802  }
1803  m->changed = false;
1804 
1805  /* We must send an EXPUNGE command if we're not closing. */
1806  if (expunge && !close && (m->rights & MUTT_ACL_DELETE))
1807  {
1808  mutt_message(_("Expunging messages from server..."));
1809  /* Set expunge bit so we don't get spurious reopened messages */
1810  mdata->reopen |= IMAP_EXPUNGE_EXPECTED;
1811  if (imap_exec(adata, "EXPUNGE", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1812  {
1813  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1814  imap_error(_("imap_sync_mailbox: EXPUNGE failed"), adata->buf);
1815  return -1;
1816  }
1817  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1818  }
1819 
1820  if (expunge && close)
1821  {
1822  adata->closing = true;
1823  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
1824  adata->state = IMAP_AUTHENTICATED;
1825  }
1826 
1827  if (C_MessageCacheClean)
1828  imap_cache_clean(m);
1829 
1830  return 0;
1831 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int mutt_save_message_ctx(struct Email *e, bool delete_original, bool decode, bool decrypt, struct Mailbox *m)
Save a message to a given mailbox.
Definition: commands.c:987
Deleted messages.
Definition: mutt.h:105
WHERE bool C_MessageCacheClean
Config: (imap/pop) Clean out obsolete entries from the message cache.
Definition: globals.h:243
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:419
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:502
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
Mailbox is selected.
Definition: imap_private.h:107
#define mutt_message(...)
Definition: logging.h:83
static int sync_helper(struct Mailbox *m, AclFlags right, int flag, const char *name)
Sync flag changes to the server.
Definition: imap.c:304
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:219
Flagged messages.
Definition: mutt.h:106
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:520
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:65
Messages that have been replied to.
Definition: mutt.h:99
bool flagged
Definition: message.h:39
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
Imap command executed or queued successfully.
Definition: imap_private.h:81
bool deleted
Definition: message.h:38
header_cache_t * hcache
Definition: imap_private.h:239
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
bool read
Email is read.
Definition: email.h:51
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
Log at debug level 2.
Definition: logging.h:41
bool old
Email is seen, but unread.
Definition: email.h:50
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
struct Envelope * env
Envelope information.
Definition: email.h:89
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, int flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:1010
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:456
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
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:1241
Old messages.
Definition: mutt.h:98
bool active
Message is not to be removed.
Definition: email.h:59
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:778
Messages that have been read.
Definition: mutt.h:100
Connection is authenticated.
Definition: imap_private.h:106
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:112
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1190
IMAP-specific Account data -.
Definition: imap_private.h:166
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: imap_private.h:65
bool flagged
Marked important?
Definition: email.h:43
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:106
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define mutt_error(...)
Definition: logging.h:84
bool replied
Email has been replied to.
Definition: email.h:54
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1138
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
bool read
Definition: message.h:36
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:72
bool changed
Mailbox has been modified.
Definition: mailbox.h:113
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
IMAP-specific Email data -.
Definition: message.h:33
sort_t mutt_get_sort_func(enum SortType method)
Get the sort function for a given sort id.
Definition: sort.c:322
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1759
int imap_cache_clean(struct Mailbox *m)
Delete all the entries in the message cache.
Definition: message.c:1778
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_ac_find()

static struct Account* imap_ac_find ( struct Account a,
const char *  path 
)
static

Find an Account that matches a Mailbox path - Implements MxOps::ac_find()

Definition at line 1836 of file imap.c.

1837 {
1838  if (!a || (a->magic != MUTT_IMAP) || !path)
1839  return NULL;
1840 
1841  struct Url *url = url_parse(path);
1842 
1843  struct ImapAccountData *adata = a->adata;
1844  struct ConnAccount *ac = &adata->conn_account;
1845 
1846  if ((mutt_str_strcasecmp(url->host, ac->host) != 0) ||
1847  (mutt_str_strcasecmp(url->user, ac->user) != 0))
1848  {
1849  a = NULL;
1850  }
1851 
1852  url_free(&url);
1853  return a;
1854 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
struct ConnAccount conn_account
Definition: imap_private.h:169
char user[128]
Definition: connaccount.h:33
char host[128]
Definition: connaccount.h:36
char * user
Username.
Definition: url.h:69
enum MailboxType magic
Type of Mailboxes this Account contains.
Definition: account.h:38
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * host
Host.
Definition: url.h:71
Login details for a remote server.
Definition: connaccount.h:31
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: imap_private.h:166
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ Here is the call graph for this function:

◆ imap_ac_add()

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

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

Definition at line 1859 of file imap.c.

1860 {
1861  if (!a || !m || (m->magic != MUTT_IMAP))
1862  return -1;
1863 
1864  struct ImapAccountData *adata = a->adata;
1865 
1866  if (!adata)
1867  {
1868  struct ConnAccount conn_account;
1869  char mailbox[PATH_MAX];
1870 
1871  if (imap_parse_path(mailbox_path(m), &conn_account, mailbox, sizeof(mailbox)) < 0)
1872  return -1;
1873 
1874  adata = imap_adata_new();
1875  adata->conn_account = conn_account;
1876  adata->conn = mutt_conn_new(&conn_account);
1877  if (!adata->conn)
1878  return -1;
1879 
1881 
1882  if (imap_login(adata) < 0)
1883  return -1;
1884 
1885  a->adata = adata;
1887  }
1888 
1889  if (!m->mdata)
1890  {
1891  struct Url *url = url_parse(mailbox_path(m));
1892  struct ImapMboxData *mdata = imap_mdata_new(adata, url->path);
1893 
1894  /* fixup path and realpath, mainly to replace / by /INBOX */
1895  char buf[1024];
1896  imap_qualify_path(buf, sizeof(buf), &adata->conn_account, mdata->name);
1897  mutt_buffer_strcpy(&m->pathbuf, buf);
1899 
1900  m->mdata = mdata;
1902  url_free(&url);
1903  }
1904  return 0;
1905 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
struct ImapAccountData * imap_adata_new(void)
Allocate and initialise a new ImapAccountData structure.
Definition: util.c:95
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:227
int imap_login(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:1940
struct ConnAccount conn_account
Definition: imap_private.h:169
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:83
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:942
void imap_adata_free(void **ptr)
Release and clear storage in an ImapAccountData structure.
Definition: util.c:69
struct Connection * mutt_conn_new(const struct ConnAccount *account)
Create a new Connection.
Definition: mutt_socket.c:46
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: util.c:166
void(* free_mdata)(void **)
Driver-specific data free function.
Definition: mailbox.h:136
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void * mdata
Driver specific data.
Definition: mailbox.h:135
int imap_parse_path(const char *path, struct ConnAccount *account, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:599
void mutt_account_hook(const char *url)
Perform an account hook.
Definition: hook.c:758
#define PATH_MAX
Definition: mutt.h:50
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:215
Login details for a remote server.
Definition: connaccount.h:31
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: imap_private.h:166
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
struct Buffer pathbuf
Definition: mailbox.h:82
void(* free_adata)(void **)
Callback function to free private data.
Definition: account.h:44
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
struct Connection * conn
Definition: imap_private.h:168
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ 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 1911 of file imap.c.

1912 {
1913  struct ImapAccountData *adata = imap_adata_get(m);
1914  struct ImapMboxData *mdata = imap_mdata_get(m);
1915  const char *condstore = NULL;
1916 #ifdef USE_HCACHE
1918  condstore = " (CONDSTORE)";
1919  else
1920 #endif
1921  condstore = "";
1922 
1923  char buf[PATH_MAX];
1924  snprintf(buf, sizeof(buf), "%s %s%s", m->readonly ? "EXAMINE" : "SELECT",
1925  mdata->munge_name, condstore);
1926 
1927  adata->state = IMAP_SELECTED;
1928 
1929  imap_cmd_start(adata, buf);
1930 }
Mailbox is selected.
Definition: imap_private.h:107
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:118
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define PATH_MAX
Definition: mutt.h:50
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
ImapCapFlags capabilities
Definition: imap_private.h:183
WHERE bool C_ImapCondstore
Config: (imap) Enable the CONDSTORE extension.
Definition: globals.h:223
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: imap_private.h:134
IMAP-specific Account data -.
Definition: imap_private.h:166
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:216
+ 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 1940 of file imap.c.

1941 {
1942  if (!adata)
1943  return -1;
1944 
1945  if (adata->state == IMAP_DISCONNECTED)
1946  {
1947  mutt_buffer_reset(&adata->cmdbuf); // purge outstanding queued commands
1948  imap_open_connection(adata);
1949  }
1950  if (adata->state == IMAP_CONNECTED)
1951  {
1952  if (imap_authenticate(adata) == IMAP_AUTH_SUCCESS)
1953  {
1954  adata->state = IMAP_AUTHENTICATED;
1955  FREE(&adata->capstr);
1956  if (adata->conn->ssf)
1957  mutt_debug(LL_DEBUG2, "Communication encrypted at %d bits\n",
1958  adata->conn->ssf);
1959  }
1960  else
1962  }
1963  if (adata->state == IMAP_AUTHENTICATED)
1964  {
1965  /* capabilities may have changed */
1966  imap_exec(adata, "CAPABILITY", IMAP_CMD_QUEUE);
1967 
1968  /* enable RFC6855, if the server supports that */
1969  if (C_ImapRfc5161 && (adata->capabilities & IMAP_CAP_ENABLE))
1970  imap_exec(adata, "ENABLE UTF8=ACCEPT", IMAP_CMD_QUEUE);
1971 
1972  /* enable QRESYNC. Advertising QRESYNC also means CONDSTORE
1973  * is supported (even if not advertised), so flip that bit. */
1974  if (adata->capabilities & IMAP_CAP_QRESYNC)
1975  {
1976  adata->capabilities |= IMAP_CAP_CONDSTORE;
1978  imap_exec(adata, "ENABLE QRESYNC", IMAP_CMD_QUEUE);
1979  }
1980 
1981  /* get root delimiter, '/' as default */
1982  adata->delim = '/';
1983  imap_exec(adata, "LIST \"\" \"\"", IMAP_CMD_QUEUE);
1984 
1985  /* we may need the root delimiter before we open a mailbox */
1986  imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1987 
1988  /* select the mailbox that used to be open before disconnect */
1989  if (adata->mailbox)
1990  {
1991  imap_mbox_select(adata->mailbox);
1992  }
1993  }
1994 
1995  if (adata->state < IMAP_AUTHENTICATED)
1996  return -1;
1997 
1998  return 0;
1999 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
bool C_ImapRfc5161
Config: (imap) Use the IMAP ENABLE extension to select capabilities.
Definition: imap.c:68
struct ConnAccount account
Definition: connection.h:36
unsigned int ssf
security strength factor, in bits
Definition: connection.h:37
int imap_open_connection(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:853
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
#define IMAP_CAP_ENABLE
RFC5161.
Definition: imap_private.h:133
struct Mailbox * mailbox
Definition: imap_private.h:205
Log at debug level 2.
Definition: logging.h:41
int imap_authenticate(struct ImapAccountData *adata)
Authenticate to an IMAP server.
Definition: auth.c:68
struct Buffer cmdbuf
Definition: imap_private.h:202
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:1241
WHERE bool C_ImapQresync
Config: (imap) Enable the QRESYNC extension.
Definition: globals.h:227
Connection is authenticated.
Definition: imap_private.h:106
ImapCapFlags capabilities
Definition: imap_private.h:183
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1911
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: imap_private.h:134
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
Connected to server.
Definition: imap_private.h:105
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Disconnected from server.
Definition: imap_private.h:104
Authentication successful.
Definition: auth.h:37
#define IMAP_CAP_QRESYNC
RFC7162.
Definition: imap_private.h:135
struct Connection * conn
Definition: imap_private.h:168
void mutt_account_unsetpass(struct ConnAccount *account)
Unset ConnAccount&#39;s password.
Definition: mutt_account.c:332
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mbox_open()

static int imap_mbox_open ( struct Mailbox m)
static

Open a mailbox - Implements MxOps::mbox_open()

Definition at line 2004 of file imap.c.

2005 {
2006  if (!m || !m->account || !m->mdata)
2007  return -1;
2008 
2009  char buf[PATH_MAX];
2010  int count = 0;
2011  int rc;
2012 
2013  struct ImapAccountData *adata = imap_adata_get(m);
2014  struct ImapMboxData *mdata = imap_mdata_get(m);
2015 
2016  adata->mailbox = m;
2017 
2018  /* clear mailbox status */
2019  adata->status = 0;
2020  m->rights = 0;
2021  mdata->new_mail_count = 0;
2022 
2023  mutt_message(_("Selecting %s..."), mdata->name);
2024 
2025  /* pipeline ACL test */
2026  if (adata->capabilities & IMAP_CAP_ACL)
2027  {
2028  snprintf(buf, sizeof(buf), "MYRIGHTS %s", mdata->munge_name);
2029  imap_exec(adata, buf, IMAP_CMD_QUEUE);
2030  }
2031  /* assume we have all rights if ACL is unavailable */
2032  else
2033  {
2036  }
2037 
2038  /* pipeline the postponed count if possible */
2039  struct Mailbox *m_postponed = mx_mbox_find2(C_Postponed);
2040  struct ImapAccountData *postponed_adata = imap_adata_get(m_postponed);
2041  if (postponed_adata &&
2042  mutt_account_match(&postponed_adata->conn_account, &adata->conn_account))
2043  imap_mailbox_status(m_postponed, true);
2044 
2046  imap_exec(adata, "LSUB \"\" \"*\"", IMAP_CMD_QUEUE);
2047 
2048  imap_mbox_select(m);
2049 
2050  do
2051  {
2052  char *pc = NULL;
2053 
2054  rc = imap_cmd_step(adata);
2055  if (rc != IMAP_RES_CONTINUE)
2056  break;
2057 
2058  pc = adata->buf + 2;
2059 
2060  /* Obtain list of available flags here, may be overridden by a
2061  * PERMANENTFLAGS tag in the OK response */
2062  if (mutt_str_startswith(pc, "FLAGS", CASE_IGNORE))
2063  {
2064  /* don't override PERMANENTFLAGS */
2065  if (STAILQ_EMPTY(&mdata->flags))
2066  {
2067  mutt_debug(LL_DEBUG3, "Getting mailbox FLAGS\n");
2068  pc = get_flags(&mdata->flags, pc);
2069  if (!pc)
2070  goto fail;
2071  }
2072  }
2073  /* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */
2074  else if (mutt_str_startswith(pc, "OK [PERMANENTFLAGS", CASE_IGNORE))
2075  {
2076  mutt_debug(LL_DEBUG3, "Getting mailbox PERMANENTFLAGS\n");
2077  /* safe to call on NULL */
2078  mutt_list_free(&mdata->flags);
2079  /* skip "OK [PERMANENT" so syntax is the same as FLAGS */
2080  pc += 13;
2081  pc = get_flags(&(mdata->flags), pc);
2082  if (!pc)
2083  goto fail;
2084  }
2085  /* save UIDVALIDITY for the header cache */
2086  else if (mutt_str_startswith(pc, "OK [UIDVALIDITY", CASE_IGNORE))
2087  {
2088  mutt_debug(LL_DEBUG3, "Getting mailbox UIDVALIDITY\n");
2089  pc += 3;
2090  pc = imap_next_word(pc);
2091  if (mutt_str_atoui(pc, &mdata->uid_validity) < 0)
2092  goto fail;
2093  }
2094  else if (mutt_str_startswith(pc, "OK [UIDNEXT", CASE_IGNORE))
2095  {
2096  mutt_debug(LL_DEBUG3, "Getting mailbox UIDNEXT\n");
2097  pc += 3;
2098  pc = imap_next_word(pc);
2099  if (mutt_str_atoui(pc, &mdata->uid_next) < 0)
2100  goto fail;
2101  }
2102  else if (mutt_str_startswith(pc, "OK [HIGHESTMODSEQ", CASE_IGNORE))
2103  {
2104  mutt_debug(LL_DEBUG3, "Getting mailbox HIGHESTMODSEQ\n");
2105  pc += 3;
2106  pc = imap_next_word(pc);
2107  if (mutt_str_atoull(pc, &mdata->modseq) < 0)
2108  goto fail;
2109  }
2110  else if (mutt_str_startswith(pc, "OK [NOMODSEQ", CASE_IGNORE))
2111  {
2112  mutt_debug(LL_DEBUG3, "Mailbox has NOMODSEQ set\n");
2113  mdata->modseq = 0;
2114  }
2115  else
2116  {
2117  pc = imap_next_word(pc);
2118  if (mutt_str_startswith(pc, "EXISTS", CASE_IGNORE))
2119  {
2120  count = mdata->new_mail_count;
2121  mdata->new_mail_count = 0;
2122  }
2123  }
2124  } while (rc == IMAP_RES_CONTINUE);
2125 
2126  if (rc == IMAP_RES_NO)
2127  {
2128  char *s = imap_next_word(adata->buf); /* skip seq */
2129  s = imap_next_word(s); /* Skip response */
2130  mutt_error("%s", s);
2131  goto fail;
2132  }
2133 
2134  if (rc != IMAP_RES_OK)
2135  goto fail;
2136 
2137  /* check for READ-ONLY notification */
2138  if (mutt_str_startswith(imap_get_qualifier(adata->buf), "[READ-ONLY]", CASE_IGNORE) &&
2139  !(adata->capabilities & IMAP_CAP_ACL))
2140  {
2141  mutt_debug(LL_DEBUG2, "Mailbox is read-only\n");
2142  m->readonly = true;
2143  }
2144 
2145  /* dump the mailbox flags we've found */
2146  if (C_DebugLevel > LL_DEBUG2)
2147  {
2148  if (STAILQ_EMPTY(&mdata->flags))
2149  mutt_debug(LL_DEBUG3, "No folder flags found\n");
2150  else
2151  {
2152  struct ListNode *np = NULL;
2153  struct Buffer flag_buffer;
2154  mutt_buffer_init(&flag_buffer);
2155  mutt_buffer_printf(&flag_buffer, "Mailbox flags: ");
2156  STAILQ_FOREACH(np, &mdata->flags, entries)
2157  {
2158  mutt_buffer_add_printf(&flag_buffer, "[%s] ", np->data);
2159  }
2160  mutt_debug(LL_DEBUG3, "%s\n", flag_buffer.data);
2161  FREE(&flag_buffer.data);
2162  }
2163  }
2164 
2165  if (!((m->rights & MUTT_ACL_DELETE) || (m->rights & MUTT_ACL_SEEN) ||
2166  (m->rights & MUTT_ACL_WRITE) || (m->rights & MUTT_ACL_INSERT)))
2167  {
2168  m->readonly = true;
2169  }
2170 
2171  while (m->email_max < count)
2172  mx_alloc_memory(m);
2173 
2174  m->msg_count = 0;
2175  m->msg_unread = 0;
2176  m->msg_flagged = 0;
2177  m->msg_new = 0;
2178  m->msg_deleted = 0;
2179  m->size = 0;
2180  m->vcount = 0;
2181 
2182  if (count && (imap_read_headers(m, 1, count, true) < 0))
2183  {
2184  mutt_error(_("Error opening mailbox"));
2185  goto fail;
2186  }
2187 
2188  mutt_debug(LL_DEBUG2, "msg_count is %d\n", m->msg_count);
2189  return 0;
2190 
2191 fail:
2192  if (adata->state == IMAP_SELECTED)
2193  adata->state = IMAP_AUTHENTICATED;
2194  return -1;
2195 }
int msg_count
Total number of messages.
Definition: mailbox.h:90
off_t size
Size of the Mailbox.
Definition: mailbox.h:86
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
#define IMAP_CAP_ACL
RFC2086: IMAP4 ACL extension.
Definition: imap_private.h:123
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:95
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
#define MUTT_ACL_READ
Read the mailbox.
Definition: mailbox.h:71
Mailbox is selected.
Definition: imap_private.h:107
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
#define MUTT_ACL_CREATE
Create a mailbox.
Definition: mailbox.h:64
struct ConnAccount conn_account
Definition: imap_private.h:169
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
String manipulation buffer.
Definition: buffer.h:33
#define MUTT_ACL_INSERT
Add/copy into the mailbox (used when editing a message)
Definition: mailbox.h:68
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1166
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Definition: imap_private.h:205
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1576
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:65
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
static char * get_flags(struct ListHead *hflags, char *s)
Make a simple list out of a FLAGS response.
Definition: imap.c:103
int vcount
The number of virtual messages.
Definition: mailbox.h:101
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: imap_private.h:221
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
Log at debug level 2.
Definition: logging.h:41
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:118
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
#define MUTT_ACL_POST
Post (submit messages to the server)
Definition: mailbox.h:70
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
unsigned long long modseq
Definition: imap_private.h:227
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:1241
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:911
short C_DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
int email_max
Number of pointers in emails.
Definition: mailbox.h:99
A mailbox.
Definition: mailbox.h:80
#define PATH_MAX
Definition: mutt.h:50
#define IMAP_RES_NO
<tag> NO ...
Definition: imap_private.h:52
struct ListHead flags
Definition: imap_private.h:224
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
Connection is authenticated.
Definition: imap_private.h:106
char * name
Mailbox name.
Definition: imap_private.h:215
bool mutt_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare account info (host/port/user)
Definition: mutt_account.c:61
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:292
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
Ignore case when comparing strings.
Definition: string2.h:68
WHERE bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: globals.h:222
int mutt_str_atoull(const char *str, unsigned long long *dst)
Convert ASCII string to an unsigned long long.
Definition: string.c:353
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1336
ImapCapFlags capabilities
Definition: imap_private.h:183
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:894
unsigned int uid_validity
Definition: imap_private.h:225
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:55
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1911
IMAP-specific Account data -.
Definition: imap_private.h:166
unsigned int uid_next
Definition: imap_private.h:226
char * data
String.
Definition: list.h:35
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:130
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
int msg_new
Number of new messages.
Definition: mailbox.h:94
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
#define mutt_error(...)
Definition: logging.h:84
int imap_read_headers(struct Mailbox *m, unsigned int msn_begin, unsigned int msn_end, bool initial_download)
Read headers from the server.
Definition: message.c:1274
#define FREE(x)
Definition: memory.h:40
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:72
#define STAILQ_EMPTY(head)
Definition: queue.h:345
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:134
A List node for strings.
Definition: list.h:33
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:216
Log at debug level 3.
Definition: logging.h:42
#define MUTT_ACL_LOOKUP
Lookup mailbox (visible to &#39;list&#39;)
Definition: mailbox.h:69
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:54
+ Here is the call graph for this function:

◆ imap_mbox_open_append()

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

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

Definition at line 2200 of file imap.c.

2201 {
2202  if (!m || !m->account)
2203  return -1;
2204 
2205  /* in APPEND mode, we appear to hijack an existing IMAP connection -
2206  * ctx is brand new and mostly empty */
2207  struct ImapAccountData *adata = imap_adata_get(m);
2208  struct ImapMboxData *mdata = imap_mdata_get(m);
2209 
2210  int rc = imap_mailbox_status(m, false);
2211  if (rc >= 0)
2212  return 0;
2213  if (rc == -1)
2214  return -1;
2215 
2216  char buf[PATH_MAX + 64];
2217  snprintf(buf, sizeof(buf), _("Create %s?"), mdata->name);
2218  if (C_Confirmcreate && (mutt_yesorno(buf, MUTT_YES) != MUTT_YES))
2219  return -1;
2220 
2221  if (imap_create_mailbox(adata, mdata->name) < 0)
2222  return -1;
2223 
2224  return 0;
2225 }
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define _(a)
Definition: message.h:28
WHERE bool C_Confirmcreate
Config: Confirm before creating a new mailbox.
Definition: globals.h:208
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define PATH_MAX
Definition: mutt.h:50
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:215
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1336
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:575
IMAP-specific Account data -.
Definition: imap_private.h:166
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:130
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
+ Here is the call graph for this function:

◆ imap_mbox_check()

static int imap_mbox_check ( struct Mailbox m,
int *  index_hint 
)
static

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

Parameters
mMailbox
index_hintRemember our place in the index
Return values
>0Success, e.g. MUTT_REOPENED
-1Failure

Definition at line 2234 of file imap.c.

2235 {
2236  if (!m)
2237  return -1;
2238 
2239  imap_allow_reopen(m);
2240  int rc = imap_check_mailbox(m, false);
2241  /* NOTE - ctx might have been changed at this point. In particular,
2242  * m could be NULL. Beware. */
2244 
2245  return rc;
2246 }
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1151
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1190
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1138
+ Here is the call graph for this function:

◆ imap_mbox_close()

static int imap_mbox_close ( struct Mailbox m)
static

Close a Mailbox - Implements MxOps::mbox_close()

Definition at line 2251 of file imap.c.

2252 {
2253  if (!m)
2254  return -1;
2255 
2256  struct ImapAccountData *adata = imap_adata_get(m);
2257  struct ImapMboxData *mdata = imap_mdata_get(m);
2258 
2259  /* Check to see if the mailbox is actually open */
2260  if (!adata || !mdata)
2261  return 0;
2262 
2263  /* imap_mbox_open_append() borrows the struct ImapAccountData temporarily,
2264  * just for the connection.
2265  *
2266  * So when these are equal, it means we are actually closing the
2267  * mailbox and should clean up adata. Otherwise, we don't want to
2268  * touch adata - it's still being used. */
2269  if (m == adata->mailbox)
2270  {
2271  if ((adata->status != IMAP_FATAL) && (adata->state >= IMAP_SELECTED))
2272  {
2273  /* mx_mbox_close won't sync if there are no deleted messages
2274  * and the mailbox is unchanged, so we may have to close here */
2275  if (m->msg_deleted == 0)
2276  {
2277  adata->closing = true;
2278  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
2279  }
2280  adata->state = IMAP_AUTHENTICATED;
2281  }
2282 
2283  adata->mailbox = NULL;
2285  }
2286 
2287  return 0;
2288 }
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:95
Mailbox is selected.
Definition: imap_private.h:107
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:172
struct Mailbox * mailbox
Definition: imap_private.h:205
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:1241
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:173
Connection is authenticated.
Definition: imap_private.h:106
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
IMAP-specific Account data -.
Definition: imap_private.h:166
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:73
Unrecoverable error occurred.
Definition: imap_private.h:94
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:214
+ Here is the call graph for this function:

◆ imap_msg_open_new()

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

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

Definition at line 2293 of file imap.c.

2294 {
2295  int rc = -1;
2296 
2297  struct Buffer *tmp = mutt_buffer_pool_get();
2298  mutt_buffer_mktemp(tmp);
2299 
2300  msg->fp = mutt_file_fopen(mutt_b2s(tmp), "w");
2301  if (!msg->fp)
2302  {
2303  mutt_perror(mutt_b2s(tmp));
2304  goto cleanup;
2305  }
2306 
2307  msg->path = mutt_buffer_strdup(tmp);
2308  rc = 0;
2309 
2310 cleanup:
2312  return rc;
2313 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:78
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
#define mutt_b2s(buf)
Definition: buffer.h:41
FILE * fp
pointer to the message data
Definition: mx.h:83
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
char * path
path to temp file
Definition: mx.h:84
+ 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 2318 of file imap.c.

2319 {
2320  struct ImapMboxData *mdata = imap_mdata_get(m);
2321  if (!mdata)
2322  return -1;
2323 
2324  char *new_tag = NULL;
2325  char *checker = NULL;
2326 
2327  /* Check for \* flags capability */
2328  if (!imap_has_flag(&mdata->flags, NULL))
2329  {
2330  mutt_error(_("IMAP server doesn't support custom flags"));
2331  return -1;
2332  }
2333 
2334  *buf = '\0';
2335  if (tags)
2336  mutt_str_strfcpy(buf, tags, buflen);
2337 
2338  if (mutt_get_field("Tags: ", buf, buflen, 0) != 0)
2339  return -1;
2340 
2341  /* each keyword must be atom defined by rfc822 as:
2342  *
2343  * atom = 1*<any CHAR except specials, SPACE and CTLs>
2344  * CHAR = ( 0.-127. )
2345  * specials = "(" / ")" / "<" / ">" / "@"
2346  * / "," / ";" / ":" / "\" / <">
2347  * / "." / "[" / "]"
2348  * SPACE = ( 32. )
2349  * CTLS = ( 0.-31., 127.)
2350  *
2351  * And must be separated by one space.
2352  */
2353 
2354  new_tag = buf;
2355  checker = buf;
2356  SKIPWS(checker);
2357  while (*checker != '\0')
2358  {
2359  if ((*checker < 32) || (*checker >= 127) || // We allow space because it's the separator
2360  (*checker == 40) || // (
2361  (*checker == 41) || // )
2362  (*checker == 60) || // <
2363  (*checker == 62) || // >
2364  (*checker == 64) || // @
2365  (*checker == 44) || // ,
2366  (*checker == 59) || // ;
2367  (*checker == 58) || // :
2368  (*checker == 92) || // backslash
2369  (*checker == 34) || // "
2370  (*checker == 46) || // .
2371  (*checker == 91) || // [
2372  (*checker == 93)) // ]
2373  {
2374  mutt_error(_("Invalid IMAP flags"));
2375  return 0;
2376  }
2377 
2378  /* Skip duplicate space */
2379  while ((checker[0] == ' ') && (checker[1] == ' '))
2380  checker++;
2381 
2382  /* copy char to new_tag and go the next one */
2383  *new_tag++ = *checker++;
2384  }
2385  *new_tag = '\0';
2386  new_tag = buf; /* rewind */
2387  mutt_str_remove_trailing_ws(new_tag);
2388 
2389  if (mutt_str_strcmp(tags, buf) == 0)
2390  return 0;
2391  return 1;
2392 }
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:246
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:966
#define SKIPWS(ch)
Definition: string2.h:47
void * mdata
Driver specific data.
Definition: mailbox.h:135
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:734
struct ListHead flags
Definition: imap_private.h:224
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
IMAP-specific Mailbox data -.
Definition: imap_private.h:213
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ 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 2407 of file imap.c.

2408 {
2409  if (!m)
2410  return -1;
2411 
2412  char uid[11];
2413 
2414  struct ImapAccountData *adata = imap_adata_get(m);
2415 
2416  if (*buf == '\0')
2417  buf = NULL;
2418 
2419  if (!(adata->mailbox->rights & MUTT_ACL_WRITE))
2420  return 0;
2421 
2422  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
2423 
2424  /* Remove old custom flags */
2425  if (imap_edata_get(e)->flags_remote)
2426  {
2427  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2428  mutt_buffer_addstr(&cmd, "UID STORE ");
2429  mutt_buffer_addstr(&cmd, uid);
2430  mutt_buffer_addstr(&cmd, " -FLAGS.SILENT (");
2431  mutt_buffer_addstr(&cmd, imap_edata_get(e)->flags_remote);
2432  mutt_buffer_addstr(&cmd, ")");
2433 
2434  /* Should we return here, or we are fine and we could
2435  * continue to add new flags */
2436  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2437  mutt_buffer_dealloc(&cmd);
2438  if (rc != IMAP_EXEC_SUCCESS)
2439  {
2440  return -1;
2441  }
2442  }
2443 
2444  /* Add new custom flags */
2445  if (buf)
2446  {
2447  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2448  mutt_buffer_addstr(&cmd, "UID STORE ");
2449  mutt_buffer_addstr(&cmd, uid);
2450  mutt_buffer_addstr(&cmd, " +FLAGS.SILENT (");
2451  mutt_buffer_addstr(&cmd, buf);
2452  mutt_buffer_addstr(&cmd, ")");
2453 
2454  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2455  mutt_buffer_dealloc(&cmd);
2456  if (rc != IMAP_EXEC_SUCCESS)
2457  {
2458  mutt_debug(LL_DEBUG1, "fail to add new flags\n");
2459  return -1;
2460  }
2461  }
2462 
2463  /* We are good sync them */
2464  mutt_debug(LL_DEBUG1, "NEW TAGS: %s\n", buf);
2465  driver_tags_replace(&e->tags, buf);
2466  FREE(&imap_edata_get(e)->flags_remote);
2468  return 0;
2469 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:100
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
struct Mailbox * mailbox
Definition: imap_private.h:205
Imap command executed or queued successfully.
Definition: imap_private.h:81
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:73
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1241
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * flags_remote
Definition: message.h:48
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:115
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:120
IMAP-specific Account data -.
Definition: imap_private.h:166
char * driver_tags_get_with_hidden(struct TagList *list)
Get tags with hiddens.
Definition: tags.c:155
Log at debug level 1.
Definition: logging.h:40
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:71
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool driver_tags_replace(struct TagList *head, char *tags)
Replace all tags.
Definition: tags.c:183
+ 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 2474 of file imap.c.

2475 {
2476  if (!path)
2477  return MUTT_UNKNOWN;
2478 
2479  if (mutt_str_startswith(path, "imap://", CASE_IGNORE))
2480  return MUTT_IMAP;
2481 
2482  if (mutt_str_startswith(path, "imaps://", CASE_IGNORE))
2483  return MUTT_IMAP;
2484 
2485  return MUTT_UNKNOWN;
2486 }
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:46
Ignore case when comparing strings.
Definition: string2.h:68
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
+ 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 2491 of file imap.c.

2492 {
2493  if (!buf)
2494  return -1;
2495 
2496  struct Url *url = url_parse(buf);
2497  if (!url)
2498  return 0;
2499 
2500  char tmp[PATH_MAX];
2501  char tmp2[PATH_MAX];
2502 
2503  imap_fix_path('\0', url->path, tmp, sizeof(tmp));
2504  url->path = tmp;
2505  url_tostring(url, tmp2, sizeof(tmp2), 0);
2506  mutt_str_strfcpy(buf, tmp2, buflen);
2507  url_free(&url);
2508 
2509  return 0;
2510 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
int url_tostring(struct Url *u, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:399
#define PATH_MAX
Definition: mutt.h:50
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:797
char * path
Path.
Definition: url.h:73
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ 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 2520 of file imap.c.

2521 {
2523  return imap_path_canon(buf->data, PATH_MAX);
2524 }
#define PATH_MAX
Definition: mutt.h:50
char * data
Pointer to data.
Definition: buffer.h:35
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: imap.c:2491
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
+ 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 2529 of file imap.c.

2530 {
2531  if (!buf || !folder)
2532  return -1;
2533 
2534  imap_pretty_mailbox(buf, buflen, folder);
2535  return 0;
2536 }
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:706
+ 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 2541 of file imap.c.

2542 {
2543  char tmp[PATH_MAX] = { 0 };
2544 
2545  imap_get_parent_path(buf, tmp, sizeof(tmp));
2546  mutt_str_strfcpy(buf, tmp, buflen);
2547  return 0;
2548 }
void imap_get_parent_path(const char *path, char *buf, size_t buflen)
Get the path of the parent folder.
Definition: util.c:303
#define PATH_MAX
Definition: mutt.h:50
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
+ Here is the call graph for this function:

Variable Documentation

◆ C_ImapIdle

bool C_ImapIdle

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

Definition at line 64 of file imap.c.

◆ C_ImapRfc5161

bool C_ImapRfc5161

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

Definition at line 68 of file imap.c.

◆ MxImapOps

struct MxOps MxImapOps
Initial value:
= {
.magic = MUTT_IMAP,
.name = "imap",
.ac_find = imap_ac_find,
.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,
}
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2474
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:2318
static int imap_msg_open_new(struct Mailbox *m, struct Message *msg, struct Email *e)
Open a new message in a Mailbox - Implements MxOps::msg_open_new()
Definition: imap.c:2293
static int imap_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
Definition: imap.c:2541
static int imap_mbox_open(struct Mailbox *m)
Open a mailbox - Implements MxOps::mbox_open()
Definition: imap.c:2004
int imap_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit()
Definition: message.c:2073
int imap_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close()
Definition: message.c:2087
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:2095
static struct Account * imap_ac_find(struct Account *a, const char *path)
Find an Account that matches a Mailbox path - Implements MxOps::ac_find()
Definition: imap.c:1836
static int imap_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
Definition: imap.c:1859
int 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:1867
static int imap_mbox_check_stats(struct Mailbox *m, int flags)
Check the Mailbox statistics - Implements MxOps::mbox_check_stats()
Definition: imap.c:1299
static int imap_mbox_check(struct Mailbox *m, int *index_hint)
Check for new mail - Implements MxOps::mbox_check()
Definition: imap.c:2234
static int imap_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close()
Definition: imap.c:2251
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:2407
static int imap_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
Definition: imap.c:2529
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: imap.c:2491
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
static int imap_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append()
Definition: imap.c:2200

IMAP Mailbox - Implements MxOps.

Definition at line 2554 of file imap.c.