NeoMutt  2020-03-20-65-g141838
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/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "lib.h"
#include "auth.h"
#include "commands.h"
#include "globals.h"
#include "hook.h"
#include "init.h"
#include "message.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_ImapDeflate
 Config: (imap) Compress network traffic. More...
 
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 79 of file imap.c.

80 {
81  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
82  {
83  imap_error("check_capabilities", adata->buf);
84  return -1;
85  }
86 
87  if (!((adata->capabilities & IMAP_CAP_IMAP4) || (adata->capabilities & IMAP_CAP_IMAP4REV1)))
88  {
89  mutt_error(
90  _("This IMAP server is ancient. NeoMutt does not work with it."));
91  return -1;
92  }
93 
94  return 0;
95 }
#define _(a)
Definition: message.h:28
Imap command executed or queued successfully.
Definition: imap_private.h:82
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: imap_private.h:122
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:805
ImapCapFlags capabilities
Definition: imap_private.h:184
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#define IMAP_CAP_IMAP4
Server supports IMAP4.
Definition: imap_private.h:121
+ 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 106 of file imap.c.

107 {
108  /* sanity-check string */
109  const size_t plen = mutt_str_startswith(s, "FLAGS", CASE_IGNORE);
110  if (plen == 0)
111  {
112  mutt_debug(LL_DEBUG1, "not a FLAGS response: %s\n", s);
113  return NULL;
114  }
115  s += plen;
116  SKIPWS(s);
117  if (*s != '(')
118  {
119  mutt_debug(LL_DEBUG1, "bogus FLAGS response: %s\n", s);
120  return NULL;
121  }
122 
123  /* update caller's flags handle */
124  while (*s && (*s != ')'))
125  {
126  s++;
127  SKIPWS(s);
128  const char *flag_word = s;
129  while (*s && (*s != ')') && !IS_SPACE(*s))
130  s++;
131  const char ctmp = *s;
132  *s = '\0';
133  if (*flag_word)
134  mutt_list_insert_tail(hflags, mutt_str_strdup(flag_word));
135  *s = ctmp;
136  }
137 
138  /* note bad flags response */
139  if (*s != ')')
140  {
141  mutt_debug(LL_DEBUG1, "Unterminated FLAGS response: %s\n", s);
142  mutt_list_free(hflags);
143 
144  return NULL;
145  }
146 
147  s++;
148 
149  return s;
150 }
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 161 of file imap.c.

163 {
164  if (m->rights & aclflag)
165  if (flag && imap_has_flag(&imap_mdata_get(m)->flags, str))
166  mutt_str_strcat(flags, flsize, str);
167 }
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:970
struct ListHead flags
Definition: imap_private.h:227
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
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 182 of file imap.c.

184 {
185  int count = 0; /* number of messages in message set */
186  unsigned int setstart = 0; /* start of current message range */
187  int n;
188  bool started = false;
189 
190  struct ImapAccountData *adata = imap_adata_get(m);
191  if (!adata || (adata->mailbox != m))
192  return -1;
193 
194  for (n = *pos; (n < m->msg_count) && (mutt_buffer_len(buf) < IMAP_MAX_CMDLEN); n++)
195  {
196  struct Email *e = m->emails[n];
197  if (!e)
198  break;
199  bool match = false; /* whether current message matches flag condition */
200  /* don't include pending expunged messages.
201  *
202  * TODO: can we unset active in cmd_parse_expunge() and
203  * cmd_parse_vanished() instead of checking for index != INT_MAX. */
204  if (e->active && (e->index != INT_MAX))
205  {
206  switch (flag)
207  {
208  case MUTT_DELETED:
209  if (e->deleted != imap_edata_get(e)->deleted)
210  match = invert ^ e->deleted;
211  break;
212  case MUTT_FLAG:
213  if (e->flagged != imap_edata_get(e)->flagged)
214  match = invert ^ e->flagged;
215  break;
216  case MUTT_OLD:
217  if (e->old != imap_edata_get(e)->old)
218  match = invert ^ e->old;
219  break;
220  case MUTT_READ:
221  if (e->read != imap_edata_get(e)->read)
222  match = invert ^ e->read;
223  break;
224  case MUTT_REPLIED:
225  if (e->replied != imap_edata_get(e)->replied)
226  match = invert ^ e->replied;
227  break;
228  case MUTT_TAG:
229  if (e->tagged)
230  match = true;
231  break;
232  case MUTT_TRASH:
233  if (e->deleted && !e->purge)
234  match = true;
235  break;
236  }
237  }
238 
239  if (match && (!changed || e->changed))
240  {
241  count++;
242  if (setstart == 0)
243  {
244  setstart = imap_edata_get(e)->uid;
245  if (started)
246  {
247  mutt_buffer_add_printf(buf, ",%u", imap_edata_get(e)->uid);
248  }
249  else
250  {
251  mutt_buffer_add_printf(buf, "%u", imap_edata_get(e)->uid);
252  started = true;
253  }
254  }
255  /* tie up if the last message also matches */
256  else if (n == (m->msg_count - 1))
257  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(e)->uid);
258  }
259  /* End current set if message doesn't match or we've reached the end
260  * of the mailbox via inactive messages following the last match. */
261  else if (setstart && (e->active || (n == adata->mailbox->msg_count - 1)))
262  {
263  if (imap_edata_get(m->emails[n - 1])->uid > setstart)
264  mutt_buffer_add_printf(buf, ":%u", imap_edata_get(m->emails[n - 1])->uid);
265  setstart = 0;
266  }
267  }
268 
269  *pos = n;
270 
271  return count;
272 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
Deleted messages.
Definition: mutt.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
if(!test_colorize_)
Definition: acutest.h:484
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:99
Flagged messages.
Definition: mutt.h:100
struct Mailbox * mailbox
Definition: imap_private.h:206
bool changed
Email has been edited.
Definition: email.h:48
Messages that have been replied to.
Definition: mutt.h:93
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:61
Old messages.
Definition: mutt.h:92
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:101
Messages that have been read.
Definition: mutt.h:94
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
bool purge
Skip trash folder when deleting.
Definition: email.h:46
IMAP-specific Account data -.
Definition: imap_private.h:168
int n
Definition: acutest.h:477
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:106
+ 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 282 of file imap.c.

283 {
284  struct ImapEmailData *edata = e->edata;
285 
286  if (e->read != edata->read)
287  return true;
288  if (e->old != edata->old)
289  return true;
290  if (e->flagged != edata->flagged)
291  return true;
292  if (e->replied != edata->replied)
293  return true;
294 
295  return false;
296 }
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 307 of file imap.c.

308 {
309  int count = 0;
310  int rc;
311  char buf[1024];
312 
313  if (!m)
314  return -1;
315 
316  if ((m->rights & right) == 0)
317  return 0;
318 
319  if ((right == MUTT_ACL_WRITE) && !imap_has_flag(&imap_mdata_get(m)->flags, name))
320  return 0;
321 
322  snprintf(buf, sizeof(buf), "+FLAGS.SILENT (%s)", name);
323  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, false);
324  if (rc < 0)
325  return rc;
326  count += rc;
327 
328  buf[0] = '-';
329  rc = imap_exec_msgset(m, "UID STORE", buf, flag, true, true);
330  if (rc < 0)
331  return rc;
332  count += rc;
333 
334  return count;
335 }
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:970
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:1019
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
+ 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 345 of file imap.c.

346 {
347  int rc = 0;
348  const struct Pattern *pat = NULL;
349 
350  SLIST_FOREACH(pat, search, entries)
351  {
352  switch (pat->op)
353  {
354  case MUTT_PAT_BODY:
355  case MUTT_PAT_HEADER:
356  case MUTT_PAT_WHOLE_MSG:
357  if (pat->string_match)
358  rc++;
359  break;
361  rc++;
362  break;
363  default:
364  if (pat->child && do_search(pat->child, true))
365  rc++;
366  }
367 
368  if (!allpats)
369  break;
370  }
371 
372  return rc;
373 }
struct PatternList * child
Arguments to logical operation.
Definition: pattern.h:64
Pattern matches email&#39;s header.
Definition: pattern.h:126
A simple (non-regex) pattern.
Definition: pattern.h:50
bool string_match
Check a string for a match.
Definition: pattern.h:55
Server-side pattern matches.
Definition: pattern.h:145
short op
Operation, e.g. MUTT_PAT_SCORE.
Definition: pattern.h:52
Pattern matches email&#39;s body.
Definition: pattern.h:125
static int do_search(const struct PatternList *search, bool allpats)
Perform a search of messages.
Definition: imap.c:345
#define SLIST_FOREACH(var, head, field)
Definition: queue.h:230
Pattern matches raw email text.
Definition: pattern.h:128
+ 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 387 of file imap.c.

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

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

518 {
519  // struct Connection *conn = NULL;
520  int rc = -1;
521  size_t matchlen;
522 
523  matchlen = mutt_str_strlen(buf);
524  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
525  struct MailboxNode *np = NULL;
526  STAILQ_FOREACH(np, &ml, entries)
527  {
529  continue;
530 
531  if (rc)
532  {
533  mutt_str_strfcpy(buf, mailbox_path(np->mailbox), buflen);
534  rc = 0;
535  }
536  else
537  longest_common_prefix(buf, mailbox_path(np->mailbox), matchlen, buflen);
538  }
540 
541 #if 0
542  TAILQ_FOREACH(conn, mutt_socket_head(), entries)
543  {
544  struct Url url = { 0 };
545  char urlstr[1024];
546 
547  if (conn->account.type != MUTT_ACCT_TYPE_IMAP)
548  continue;
549 
550  mutt_account_tourl(&conn->account, &url);
551  /* FIXME: how to handle multiple users on the same host? */
552  url.user = NULL;
553  url.path = NULL;
554  url_tostring(&url, urlstr, sizeof(urlstr), 0);
555  if (mutt_str_strncmp(buf, urlstr, matchlen) == 0)
556  {
557  if (rc)
558  {
559  mutt_str_strfcpy(buf, urlstr, buflen);
560  rc = 0;
561  }
562  else
563  longest_common_prefix(buf, urlstr, matchlen, buflen);
564  }
565  }
566 #endif
567 
568  return rc;
569 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
#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:45
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:689
Container for Accounts, Notifications.
Definition: neomutt.h:35
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
char * user
Username.
Definition: url.h:69
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
Imap Account.
Definition: mutt_account.h:37
char * path
Path.
Definition: url.h:73
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:496
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:665
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:416
List of Mailboxes.
Definition: mailbox.h:145
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ 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 578 of file imap.c.

579 {
580  char buf[2048], mbox[1024];
581 
582  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), mailbox);
583  snprintf(buf, sizeof(buf), "CREATE %s", mbox);
584 
585  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
586  {
587  mutt_error(_("CREATE failed: %s"), imap_cmd_trailer(adata));
588  return -1;
589  }
590 
591  return 0;
592 }
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:1060
#define _(a)
Definition: message.h:28
const char * imap_cmd_trailer(struct ImapAccountData *adata)
Extra information after tagged command response if any.
Definition: command.c:1232
Imap command executed or queued successfully.
Definition: imap_private.h:82
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define mutt_error(...)
Definition: logging.h:84
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
+ 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 604 of file imap.c.

605 {
606  if (imap_path_status(path, false) >= 0)
607  return 0;
608  return -1;
609 }
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1319
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 619 of file imap.c.

620 {
621  char oldmbox[1024];
622  char newmbox[1024];
623  int rc = 0;
624 
625  imap_munge_mbox_name(adata->unicode, oldmbox, sizeof(oldmbox), oldname);
626  imap_munge_mbox_name(adata->unicode, newmbox, sizeof(newmbox), newname);
627 
628  struct Buffer *buf = mutt_buffer_pool_get();
629  mutt_buffer_printf(buf, "RENAME %s %s", oldmbox, newmbox);
630 
632  rc = -1;
633 
635 
636  return rc;
637 }
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:1060
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:82
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define mutt_b2s(buf)
Definition: buffer.h:41
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
+ 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 646 of file imap.c.

647 {
648  char buf[PATH_MAX + 7];
649  char mbox[PATH_MAX];
650  struct Url *url = url_parse(path);
651 
652  struct ImapAccountData *adata = imap_adata_get(m);
653  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), url->path);
654  url_free(&url);
655  snprintf(buf, sizeof(buf), "DELETE %s", mbox);
657  return -1;
658 
659  return 0;
660 }
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:1060
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
Imap command executed or queued successfully.
Definition: imap_private.h:82
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: imap_private.h:168
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ 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 666 of file imap.c.

667 {
668  /* we set status here to let imap_handle_untagged know we _expect_ to
669  * receive a bye response (so it doesn't freak out and close the conn) */
670  if (adata->state == IMAP_DISCONNECTED)
671  {
672  return;
673  }
674 
675  adata->status = IMAP_BYE;
676  imap_cmd_start(adata, "LOGOUT");
677  if ((C_ImapPollTimeout <= 0) || (mutt_socket_poll(adata->conn, C_ImapPollTimeout) != 0))
678  {
679  while (imap_cmd_step(adata) == IMAP_RES_CONTINUE)
680  ;
681  }
682  mutt_socket_close(adata->conn);
683  adata->state = IMAP_DISCONNECTED;
684 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
WHERE short C_ImapPollTimeout
Config: (imap) Maximum time to wait for a server response.
Definition: globals.h:157
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:173
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1086
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:174
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:56
Logged out from server.
Definition: imap_private.h:96
Disconnected from server.
Definition: imap_private.h:105
struct Connection * conn
Definition: imap_private.h:170
+ 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 691 of file imap.c.

692 {
693  struct Account *np = NULL;
694  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
695  {
696  if (np->type != MUTT_IMAP)
697  continue;
698 
699  struct ImapAccountData *adata = np->adata;
700  if (!adata)
701  continue;
702 
703  struct Connection *conn = adata->conn;
704  if (!conn || (conn->fd < 0))
705  continue;
706 
707  mutt_message(_("Closing connection to %s..."), conn->account.host);
708  imap_logout(np->adata);
710  }
711 }
struct ConnAccount account
Account details: username, password, etc.
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:666
#define _(a)
Definition: message.h:28
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:35
char host[128]
Server to login to.
Definition: connaccount.h:53
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
int fd
Socket file descriptor.
Definition: connection.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: imap_private.h:168
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Connection * conn
Definition: imap_private.h:170
+ 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 727 of file imap.c.

729 {
730  char c;
731  bool r = false;
732  struct Buffer buf = { 0 }; // Do not allocate, maybe it won't be used
733 
735  mutt_buffer_alloc(&buf, bytes + 10);
736 
737  mutt_debug(LL_DEBUG2, "reading %ld bytes\n", bytes);
738 
739  for (unsigned long pos = 0; pos < bytes; pos++)
740  {
741  if (mutt_socket_readchar(adata->conn, &c) != 1)
742  {
743  mutt_debug(LL_DEBUG1, "error during read, %ld bytes read\n", pos);
744  adata->status = IMAP_FATAL;
745 
746  mutt_buffer_dealloc(&buf);
747  return -1;
748  }
749 
750  if (r && (c != '\n'))
751  fputc('\r', fp);
752 
753  if (c == '\r')
754  {
755  r = true;
756  continue;
757  }
758  else
759  r = false;
760 
761  fputc(c, fp);
762 
763  if (pbar && !(pos % 1024))
764  mutt_progress_update(pbar, pos, -1);
766  mutt_buffer_addch(&buf, c);
767  }
768 
770  {
771  mutt_debug(IMAP_LOG_LTRL, "\n%s", buf.data);
772  mutt_buffer_dealloc(&buf);
773  }
774  return 0;
775 }
#define IMAP_LOG_LTRL
Definition: imap_private.h:49
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:174
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:95
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:170
+ 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 785 of file imap.c.

786 {
787  struct ImapAccountData *adata = imap_adata_get(m);
788  struct ImapMboxData *mdata = imap_mdata_get(m);
789  if (!adata || !mdata)
790  return;
791 
792  struct Email *e = NULL;
793 
794 #ifdef USE_HCACHE
795  mdata->hcache = imap_hcache_open(adata, mdata);
796 #endif
797 
798  for (int i = 0; i < m->msg_count; i++)
799  {
800  e = m->emails[i];
801  if (!e)
802  break;
803 
804  if (e->index == INT_MAX)
805  {
806  mutt_debug(LL_DEBUG2, "Expunging message UID %u\n", imap_edata_get(e)->uid);
807 
808  e->deleted = true;
809 
810  imap_cache_del(m, e);
811 #ifdef USE_HCACHE
812  imap_hcache_del(mdata, imap_edata_get(e)->uid);
813 #endif
814 
815  mutt_hash_int_delete(mdata->uid_hash, imap_edata_get(e)->uid, e);
816 
817  imap_edata_free((void **) &e->edata);
818  }
819  else
820  {
821  e->index = i;
822  /* NeoMutt has several places where it turns off e->active as a
823  * hack. For example to avoid FLAG updates, or to exclude from
824  * imap_exec_msgset.
825  *
826  * Unfortunately, when a reopen is allowed and the IMAP_EXPUNGE_PENDING
827  * flag becomes set (e.g. a flag update to a modified header),
828  * this function will be called by imap_cmd_finish().
829  *
830  * The ctx_update_tables() will free and remove these "inactive" headers,
831  * despite that an EXPUNGE was not received for them.
832  * This would result in memory leaks and segfaults due to dangling
833  * pointers in the msn_index and uid_hash.
834  *
835  * So this is another hack to work around the hacks. We don't want to
836  * remove the messages, so make sure active is on. */
837  e->active = true;
838  }
839  }
840 
841 #ifdef USE_HCACHE
842  imap_hcache_close(mdata);
843 #endif
844 
847 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:444
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
Update internal tables.
Definition: mailbox.h:173
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:99
void imap_edata_free(void **ptr)
free ImapHeader structure
Definition: message.c:73
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:540
header_cache_t * hcache
Definition: imap_private.h:242
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
Log at debug level 2.
Definition: logging.h:41
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:481
void * mdata
Driver specific data.
Definition: mailbox.h:136
Email list needs resorting.
Definition: mailbox.h:172
bool active
Message is not to be removed.
Definition: email.h:59
struct Hash * uid_hash
Definition: imap_private.h:236
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
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:169
+ 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 855 of file imap.c.

856 {
857  if (mutt_socket_open(adata->conn) < 0)
858  return -1;
859 
860  adata->state = IMAP_CONNECTED;
861 
862  if (imap_cmd_step(adata) != IMAP_RES_OK)
863  {
864  imap_close_connection(adata);
865  return -1;
866  }
867 
868  if (mutt_str_startswith(adata->buf, "* OK", CASE_IGNORE))
869  {
870  if (!mutt_str_startswith(adata->buf, "* OK [CAPABILITY", CASE_IGNORE) &&
871  check_capabilities(adata))
872  {
873  goto bail;
874  }
875 #ifdef USE_SSL
876  /* Attempt STARTTLS if available and desired. */
877  if (!adata->conn->ssf && (C_SslForceTls || (adata->capabilities & IMAP_CAP_STARTTLS)))
878  {
879  enum QuadOption ans;
880 
881  if (C_SslForceTls)
882  ans = MUTT_YES;
883  else if ((ans = query_quadoption(C_SslStarttls,
884  _("Secure connection with TLS?"))) == MUTT_ABORT)
885  {
886  goto err_close_conn;
887  }
888  if (ans == MUTT_YES)
889  {
890  enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_NO_FLAGS);
891  if (rc == IMAP_EXEC_FATAL)
892  goto bail;
893  if (rc != IMAP_EXEC_ERROR)
894  {
895  if (mutt_ssl_starttls(adata->conn))
896  {
897  mutt_error(_("Could not negotiate TLS connection"));
898  goto err_close_conn;
899  }
900  else
901  {
902  /* RFC2595 demands we recheck CAPABILITY after TLS completes. */
903  if (imap_exec(adata, "CAPABILITY", IMAP_CMD_NO_FLAGS))
904  goto bail;
905  }
906  }
907  }
908  }
909 
910  if (C_SslForceTls && !adata->conn->ssf)
911  {
912  mutt_error(_("Encrypted connection unavailable"));
913  goto err_close_conn;
914  }
915 #endif
916  }
917  else if (mutt_str_startswith(adata->buf, "* PREAUTH", CASE_IGNORE))
918  {
919  adata->state = IMAP_AUTHENTICATED;
920  if (check_capabilities(adata) != 0)
921  goto bail;
922  FREE(&adata->capstr);
923  }
924  else
925  {
926  imap_error("imap_open_connection()", adata->buf);
927  goto bail;
928  }
929 
930  return 0;
931 
932 #ifdef USE_SSL
933 err_close_conn:
934  imap_close_connection(adata);
935 #endif
936 bail:
937  FREE(&adata->capstr);
938  return -1;
939 }
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
unsigned int ssf
Security strength factor, in bits.
Definition: connection.h:37
ImapExecResult
imap_exec return code
Definition: imap_private.h:80
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:1099
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:173
#define _(a)
Definition: message.h:28
void imap_close_connection(struct ImapAccountData *adata)
Close an IMAP connection.
Definition: imap.c:945
WHERE bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: globals.h:231
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:74
#define IMAP_CAP_STARTTLS
RFC2595: STARTTLS.
Definition: imap_private.h:130
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:805
Connection is authenticated.
Definition: imap_private.h:107
Imap connection failure.
Definition: imap_private.h:84
Ignore case when comparing strings.
Definition: string2.h:68
ImapCapFlags capabilities
Definition: imap_private.h:184
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:72
#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:79
Connected to server.
Definition: imap_private.h:106
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1136
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:187
struct Connection * conn
Definition: imap_private.h:170
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:55
Imap command failure.
Definition: imap_private.h:83
+ 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 945 of file imap.c.

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

◆ imap_has_flag()

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

Does the flag exist in the list.

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

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

Definition at line 970 of file imap.c.

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

◆ compare_uid()

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

Compare two Emails by UID - Implements sort_t.

Definition at line 996 of file imap.c.

997 {
998  const struct Email *ea = *(struct Email const *const *) a;
999  const struct Email *eb = *(struct Email const *const *) b;
1000  return imap_edata_get((struct Email *) ea)->uid -
1001  imap_edata_get((struct Email *) eb)->uid;
1002 }
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:99
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 1019 of file imap.c.

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

1099 {
1100  struct ImapAccountData *adata = imap_adata_get(m);
1101  if (!adata || (adata->mailbox != m))
1102  return -1;
1103 
1104  char flags[1024];
1105  char *tags = NULL;
1106  char uid[11];
1107 
1108  if (!compare_flags_for_copy(e))
1109  {
1110  if (e->deleted == imap_edata_get(e)->deleted)
1111  e->changed = false;
1112  return 0;
1113  }
1114 
1115  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
1116  mutt_buffer_reset(cmd);
1117  mutt_buffer_addstr(cmd, "UID STORE ");
1118  mutt_buffer_addstr(cmd, uid);
1119 
1120  flags[0] = '\0';
1121 
1122  set_flag(m, MUTT_ACL_SEEN, e->read, "\\Seen ", flags, sizeof(flags));
1123  set_flag(m, MUTT_ACL_WRITE, e->old, "Old ", flags, sizeof(flags));
1124  set_flag(m, MUTT_ACL_WRITE, e->flagged, "\\Flagged ", flags, sizeof(flags));
1125  set_flag(m, MUTT_ACL_WRITE, e->replied, "\\Answered ", flags, sizeof(flags));
1126  set_flag(m, MUTT_ACL_DELETE, imap_edata_get(e)->deleted, "\\Deleted ", flags,
1127  sizeof(flags));
1128 
1129  if (m->rights & MUTT_ACL_WRITE)
1130  {
1131  /* restore system flags */
1132  if (imap_edata_get(e)->flags_system)
1133  mutt_str_strcat(flags, sizeof(flags), imap_edata_get(e)->flags_system);
1134  /* set custom flags */
1135  tags = driver_tags_get_with_hidden(&e->tags);
1136  if (tags)
1137  {
1138  mutt_str_strcat(flags, sizeof(flags), tags);
1139  FREE(&tags);
1140  }
1141  }
1142 
1144 
1145  /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
1146  * explicitly revoke all system flags (if we have permission) */
1147  if (!*flags)
1148  {
1149  set_flag(m, MUTT_ACL_SEEN, 1, "\\Seen ", flags, sizeof(flags));
1150  set_flag(m, MUTT_ACL_WRITE, 1, "Old ", flags, sizeof(flags));
1151  set_flag(m, MUTT_ACL_WRITE, 1, "\\Flagged ", flags, sizeof(flags));
1152  set_flag(m, MUTT_ACL_WRITE, 1, "\\Answered ", flags, sizeof(flags));
1153  set_flag(m, MUTT_ACL_DELETE, !imap_edata_get(e)->deleted, "\\Deleted ",
1154  flags, sizeof(flags));
1155 
1156  /* erase custom flags */
1157  if ((m->rights & MUTT_ACL_WRITE) && imap_edata_get(e)->flags_remote)
1158  mutt_str_strcat(flags, sizeof(flags), imap_edata_get(e)->flags_remote);
1159 
1161 
1162  mutt_buffer_addstr(cmd, " -FLAGS.SILENT (");
1163  }
1164  else
1165  mutt_buffer_addstr(cmd, " FLAGS.SILENT (");
1166 
1167  mutt_buffer_addstr(cmd, flags);
1168  mutt_buffer_addstr(cmd, ")");
1169 
1170  /* after all this it's still possible to have no flags, if you
1171  * have no ACL rights */
1172  if (*flags && (imap_exec(adata, cmd->data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS) &&
1173  err_continue && (*err_continue != MUTT_YES))
1174  {
1175  *err_continue = imap_continue("imap_sync_message: STORE failed", adata->buf);
1176  if (*err_continue != MUTT_YES)
1177  return -1;
1178  }
1179 
1180  /* server have now the updated flags */
1181  FREE(&imap_edata_get(e)->flags_remote);
1183 
1184  if (e->deleted == imap_edata_get(e)->deleted)
1185  e->changed = false;
1186 
1187  return 0;
1188 }
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:99
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Mailbox * mailbox
Definition: imap_private.h:206
bool changed
Email has been edited.
Definition: email.h:48
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
Imap command executed or queued successfully.
Definition: imap_private.h:82
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * flags_remote
Definition: message.h:48
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:757
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
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:168
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:282
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:72
#define FREE(x)
Definition: memory.h:40
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:73
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:794
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:161
+ 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 1199 of file imap.c.

1200 {
1201  if (!m || !m->account)
1202  return -1;
1203 
1204  struct ImapAccountData *adata = imap_adata_get(m);
1205  struct ImapMboxData *mdata = imap_mdata_get(m);
1206 
1207  /* overload keyboard timeout to avoid many mailbox checks in a row.
1208  * Most users don't like having to wait exactly when they press a key. */
1209  int rc = 0;
1210 
1211  /* try IDLE first, unless force is set */
1212  if (!force && C_ImapIdle && (adata->capabilities & IMAP_CAP_IDLE) &&
1213  ((adata->state != IMAP_IDLE) || (mutt_date_epoch() >= adata->lastread + C_ImapKeepalive)))
1214  {
1215  if (imap_cmd_idle(adata) < 0)
1216  return -1;
1217  }
1218  if (adata->state == IMAP_IDLE)
1219  {
1220  while ((rc = mutt_socket_poll(adata->conn, 0)) > 0)
1221  {
1222  if (imap_cmd_step(adata) != IMAP_RES_CONTINUE)
1223  {
1224  mutt_debug(LL_DEBUG1, "Error reading IDLE response\n");
1225  return -1;
1226  }
1227  }
1228  if (rc < 0)
1229  {
1230  mutt_debug(LL_DEBUG1, "Poll failed, disabling IDLE\n");
1231  adata->capabilities &= ~IMAP_CAP_IDLE; // Clear the flag
1232  }
1233  }
1234 
1235  if ((force || ((adata->state != IMAP_IDLE) &&
1236  (mutt_date_epoch() >= adata->lastread + C_Timeout))) &&
1237  (imap_exec(adata, "NOOP", IMAP_CMD_POLL) != IMAP_EXEC_SUCCESS))
1238  {
1239  return -1;
1240  }
1241 
1242  /* We call this even when we haven't run NOOP in case we have pending
1243  * changes to process, since we can reopen here. */
1244  imap_cmd_finish(adata);
1245 
1246  if (mdata->check_status & IMAP_EXPUNGE_PENDING)
1247  rc = MUTT_REOPENED;
1248  else if (mdata->check_status & IMAP_NEWMAIL_PENDING)
1249  rc = MUTT_NEW_MAIL;
1250  else if (mdata->check_status & IMAP_FLAGS_PENDING)
1251  rc = MUTT_FLAGS;
1252 
1254 
1255  return rc;
1256 }
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:1100
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: imap_private.h:67
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:173
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: imap_private.h:69
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:75
Imap command executed or queued successfully.
Definition: imap_private.h:82
Connection is idle.
Definition: imap_private.h:111
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
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:1387
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: imap_private.h:223
void * mdata
Driver specific data.
Definition: mailbox.h:136
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
WHERE short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: globals.h:156
Nondestructive flags change (IMAP)
Definition: mx.h:77
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:152
#define IMAP_OPEN_NO_FLAGS
No flags are set.
Definition: imap_private.h:64
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1324
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
ImapCapFlags capabilities
Definition: imap_private.h:184
time_t lastread
last time we read a command for the server
Definition: imap_private.h:187
bool C_ImapIdle
Config: (imap) Use the IMAP IDLE extension to check for new mail.
Definition: imap.c:70
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:56
IMAP-specific Account data -.
Definition: imap_private.h:168
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
#define IMAP_CAP_IDLE
RFC2177: IDLE.
Definition: imap_private.h:132
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: imap_private.h:68
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
New mail received in Mailbox.
Definition: mx.h:74
Mailbox was reopened.
Definition: mx.h:76
struct Connection * conn
Definition: imap_private.h:170
+ 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 1265 of file imap.c.

1266 {
1267  char *uidvalidity_flag = NULL;
1268  char cmd[2048];
1269 
1270  if (!adata || !mdata)
1271  return -1;
1272 
1273  /* Don't issue STATUS on the selected mailbox, it will be NOOPed or
1274  * IDLEd elsewhere.
1275  * adata->mailbox may be NULL for connections other than the current
1276  * mailbox's. */
1277  if (adata->mailbox && (adata->mailbox->mdata == mdata))
1278  {
1279  adata->mailbox->has_new = false;
1280  return mdata->messages;
1281  }
1282 
1283  if (adata->capabilities & IMAP_CAP_IMAP4REV1)
1284  uidvalidity_flag = "UIDVALIDITY";
1285  else if (adata->capabilities & IMAP_CAP_STATUS)
1286  uidvalidity_flag = "UID-VALIDITY";
1287  else
1288  {
1289  mutt_debug(LL_DEBUG2, "Server doesn't support STATUS\n");
1290  return -1;
1291  }
1292 
1293  snprintf(cmd, sizeof(cmd), "STATUS %s (UIDNEXT %s UNSEEN RECENT MESSAGES)",
1294  mdata->munge_name, uidvalidity_flag);
1295 
1296  int rc = imap_exec(adata, cmd, queue ? IMAP_CMD_QUEUE : IMAP_CMD_NO_FLAGS | IMAP_CMD_POLL);
1297  if (rc < 0)
1298  {
1299  mutt_debug(LL_DEBUG1, "Error queueing command\n");
1300  return rc;
1301  }
1302  return mdata->messages;
1303 }
struct Mailbox * mailbox
Definition: imap_private.h:206
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: imap_private.h:75
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
Log at debug level 2.
Definition: logging.h:41
#define IMAP_CAP_IMAP4REV1
Server supports IMAP4rev1.
Definition: imap_private.h:122
void * mdata
Driver specific data.
Definition: mailbox.h:136
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
#define IMAP_CAP_STATUS
Server supports STATUS command.
Definition: imap_private.h:123
ImapCapFlags capabilities
Definition: imap_private.h:184
Log at debug level 1.
Definition: logging.h:40
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:74
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:219
unsigned int messages
Definition: imap_private.h:231
+ 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 1308 of file imap.c.

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

1320 {
1321  struct Mailbox *m = mx_mbox_find2(path);
1322  if (m)
1323  return imap_mailbox_status(m, queue);
1324 
1325  // FIXME(sileht): Is that case possible ?
1326  struct ImapAccountData *adata = NULL;
1327  struct ImapMboxData *mdata = NULL;
1328 
1329  if (imap_adata_find(path, &adata, &mdata) < 0)
1330  return -1;
1331  int rc = imap_status(adata, mdata, queue);
1332  imap_mdata_free((void *) &mdata);
1333  return rc;
1334 }
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:233
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1265
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1628
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:135
void * mdata
Driver specific data.
Definition: mailbox.h:136
A mailbox.
Definition: mailbox.h:81
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:1345
IMAP-specific Account data -.
Definition: imap_private.h:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
+ 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 1345 of file imap.c.

1346 {
1347  struct ImapAccountData *adata = imap_adata_get(m);
1348  struct ImapMboxData *mdata = imap_mdata_get(m);
1349  if (!adata || !mdata)
1350  return -1;
1351  return imap_status(adata, mdata, queue);
1352 }
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1265
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
+ 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 1361 of file imap.c.

1362 {
1363  struct Buffer buf;
1364  struct ImapAccountData *adata = imap_adata_get(m);
1365  for (int i = 0; i < m->msg_count; i++)
1366  {
1367  struct Email *e = m->emails[i];
1368  if (!e)
1369  break;
1370  e->matched = false;
1371  }
1372 
1373  if (do_search(pat, true) == 0)
1374  return 0;
1375 
1376  mutt_buffer_init(&buf);
1377  mutt_buffer_addstr(&buf, "UID SEARCH ");
1378  if (compile_search(m, pat, &buf) < 0)
1379  {
1380  FREE(&buf.data);
1381  return -1;
1382  }
1383  if (imap_exec(adata, buf.data, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1384  {
1385  FREE(&buf.data);
1386  return -1;
1387  }
1388 
1389  FREE(&buf.data);
1390  return 0;
1391 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
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:82
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
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:387
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
IMAP-specific Account data -.
Definition: imap_private.h:168
static int do_search(const struct PatternList *search, bool allpats)
Perform a search of messages.
Definition: imap.c:345
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#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 1400 of file imap.c.

1401 {
1402  struct ImapAccountData *adata = NULL;
1403  struct ImapMboxData *mdata = NULL;
1404  char buf[2048];
1405  char errstr[256];
1406  struct Buffer err, token;
1407 
1408  if (imap_adata_find(path, &adata, &mdata) < 0)
1409  return -1;
1410 
1412  {
1413  char mbox[1024];
1414  mutt_buffer_init(&token);
1415  mutt_buffer_init(&err);
1416  err.data = errstr;
1417  err.dsize = sizeof(errstr);
1418  size_t len = snprintf(mbox, sizeof(mbox), "%smailboxes ", subscribe ? "" : "un");
1419  imap_quote_string(mbox + len, sizeof(mbox) - len, path, true);
1420  if (mutt_parse_rc_line(mbox, &token, &err))
1421  mutt_debug(LL_DEBUG1, "Error adding subscribed mailbox: %s\n", errstr);
1422  FREE(&token.data);
1423  }
1424 
1425  if (subscribe)
1426  mutt_message(_("Subscribing to %s..."), mdata->name);
1427  else
1428  mutt_message(_("Unsubscribing from %s..."), mdata->name);
1429 
1430  snprintf(buf, sizeof(buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mdata->munge_name);
1431 
1432  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1433  {
1434  imap_mdata_free((void *) &mdata);
1435  return -1;
1436  }
1437 
1438  if (subscribe)
1439  mutt_message(_("Subscribed to %s"), mdata->name);
1440  else
1441  mutt_message(_("Unsubscribed from %s"), mdata->name);
1442  imap_mdata_free((void *) &mdata);
1443  return 0;
1444 }
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:986
#define mutt_message(...)
Definition: logging.h:83
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:233
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Imap command executed or queued successfully.
Definition: imap_private.h:82
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:135
void * mdata
Driver specific data.
Definition: mailbox.h:136
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:218
WHERE bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: globals.h:219
IMAP-specific Account data -.
Definition: imap_private.h:168
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#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:219
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:991
+ 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 1457 of file imap.c.

1458 {
1459  struct ImapAccountData *adata = NULL;
1460  struct ImapMboxData *mdata = NULL;
1461  char tmp[2048];
1462  struct ImapList listresp = { 0 };
1463  char completion[1024];
1464  int clen;
1465  size_t matchlen = 0;
1466  int completions = 0;
1467  int rc;
1468 
1469  if (imap_adata_find(path, &adata, &mdata) < 0)
1470  {
1471  mutt_str_strfcpy(buf, path, buflen);
1472  return complete_hosts(buf, buflen);
1473  }
1474 
1475  /* fire off command */
1476  snprintf(tmp, sizeof(tmp), "%s \"\" \"%s%%\"",
1477  C_ImapListSubscribed ? "LSUB" : "LIST", mdata->real_name);
1478 
1479  imap_cmd_start(adata, tmp);
1480 
1481  /* and see what the results are */
1482  mutt_str_strfcpy(completion, mdata->name, sizeof(completion));
1483  imap_mdata_free((void *) &mdata);
1484 
1485  adata->cmdresult = &listresp;
1486  do
1487  {
1488  listresp.name = NULL;
1489  rc = imap_cmd_step(adata);
1490 
1491  if ((rc == IMAP_RES_CONTINUE) && listresp.name)
1492  {
1493  /* if the folder isn't selectable, append delimiter to force browse
1494  * to enter it on second tab. */
1495  if (listresp.noselect)
1496  {
1497  clen = strlen(listresp.name);
1498  listresp.name[clen++] = listresp.delim;
1499  listresp.name[clen] = '\0';
1500  }
1501  /* copy in first word */
1502  if (!completions)
1503  {
1504  mutt_str_strfcpy(completion, listresp.name, sizeof(completion));
1505  matchlen = strlen(completion);
1506  completions++;
1507  continue;
1508  }
1509 
1510  matchlen = longest_common_prefix(completion, listresp.name, 0, matchlen);
1511  completions++;
1512  }
1513  } while (rc == IMAP_RES_CONTINUE);
1514  adata->cmdresult = NULL;
1515 
1516  if (completions)
1517  {
1518  /* reformat output */
1519  imap_qualify_path(buf, buflen, &adata->conn->account, completion);
1520  mutt_pretty_mailbox(buf, buflen);
1521  return 0;
1522  }
1523 
1524  return -1;
1525 }
WHERE bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: globals.h:221
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:233
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:969
Items in an IMAP browser.
Definition: imap_private.h:146
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1086
char delim
Definition: imap_private.h:149
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:517
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:135
void * mdata
Driver specific data.
Definition: mailbox.h:136
char * name
Definition: imap_private.h:148
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:773
char * name
Mailbox name.
Definition: imap_private.h:218
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:613
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: imap_private.h:220
#define IMAP_RES_CONTINUE
* ...
Definition: imap_private.h:56
IMAP-specific Account data -.
Definition: imap_private.h: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:496
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
struct ImapList * cmdresult
Definition: imap_private.h:196
bool noselect
Definition: imap_private.h:150
struct Connection * conn
Definition: imap_private.h:170
+ 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 1535 of file imap.c.

1536 {
1537  char prompt[1024];
1538  int rc = -1;
1539  bool triedcreate = false;
1540  enum QuadOption err_continue = MUTT_NO;
1541 
1542  struct ImapAccountData *adata = imap_adata_get(m);
1543  struct ImapAccountData *dest_adata = NULL;
1544  struct ImapMboxData *dest_mdata = NULL;
1545 
1546  if (imap_adata_find(dest, &dest_adata, &dest_mdata) < 0)
1547  return -1;
1548 
1549  struct Buffer sync_cmd = mutt_buffer_make(0);
1550 
1551  /* check that the save-to folder is in the same account */
1552  if (!imap_account_match(&(adata->conn->account), &(dest_adata->conn->account)))
1553  {
1554  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1555  goto out;
1556  }
1557 
1558  for (int i = 0; i < m->msg_count; i++)
1559  {
1560  struct Email *e = m->emails[i];
1561  if (!e)
1562  break;
1563  if (e->active && e->changed && e->deleted && !e->purge)
1564  {
1565  rc = imap_sync_message_for_copy(m, e, &sync_cmd, &err_continue);
1566  if (rc < 0)
1567  {
1568  mutt_debug(LL_DEBUG1, "could not sync\n");
1569  goto out;
1570  }
1571  }
1572  }
1573 
1574  /* loop in case of TRYCREATE */
1575  do
1576  {
1577  rc = imap_exec_msgset(m, "UID COPY", dest_mdata->munge_name, MUTT_TRASH, false, false);
1578  if (rc == 0)
1579  {
1580  mutt_debug(LL_DEBUG1, "No messages to trash\n");
1581  rc = -1;
1582  goto out;
1583  }
1584  else if (rc < 0)
1585  {
1586  mutt_debug(LL_DEBUG1, "could not queue copy\n");
1587  goto out;
1588  }
1589  else
1590  {
1591  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1592  rc, dest_mdata->name);
1593  }
1594 
1595  /* let's get it on */
1596  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1597  if (rc == IMAP_EXEC_ERROR)
1598  {
1599  if (triedcreate)
1600  {
1601  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", dest_mdata->name);
1602  break;
1603  }
1604  /* bail out if command failed for reasons other than nonexistent target */
1605  if (!mutt_str_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]", CASE_IGNORE))
1606  break;
1607  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1608  snprintf(prompt, sizeof(prompt), _("Create %s?"), dest_mdata->name);
1609  if (C_Confirmcreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1610  {
1611  mutt_clear_error();
1612  goto out;
1613  }
1614  if (imap_create_mailbox(adata, dest_mdata->name) < 0)
1615  break;
1616  triedcreate = true;
1617  }
1618  } while (rc == IMAP_EXEC_ERROR);
1619 
1620  if (rc != IMAP_EXEC_SUCCESS)
1621  {
1622  imap_error("imap_fast_trash", adata->buf);
1623  goto out;
1624  }
1625 
1626  rc = IMAP_EXEC_SUCCESS;
1627 
1628 out:
1629  mutt_buffer_dealloc(&sync_cmd);
1630  imap_mdata_free((void *) &dest_mdata);
1631 
1632  return ((rc == IMAP_EXEC_SUCCESS) ? 0 : -1);
1633 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
struct ConnAccount account
Account details: username, password, etc.
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:233
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:210
Imap command executed or queued successfully.
Definition: imap_private.h:82
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1193
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:135
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:1019
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:1270
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:1097
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:805
char * name
Mailbox name.
Definition: imap_private.h:218
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
Ignore case when comparing strings.
Definition: string2.h:68
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:921
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:578
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:168
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
bool deleted
Email is deleted.
Definition: email.h:45
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:219
Trashed messages.
Definition: mutt.h:106
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:170
Imap command failure.
Definition: imap_private.h:83
+ 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
MUTT_REOPENEDmailbox has been externally modified
MUTT_NEW_MAILnew mail has arrived
0Success
-1Error
Note
The flag retvals come from a call to imap_check_mailbox()

Definition at line 1647 of file imap.c.

1648 {
1649  if (!m)
1650  return -1;
1651 
1652  struct Email **emails = NULL;
1653  int oldsort;
1654  int rc;
1655  int check;
1656 
1657  struct ImapAccountData *adata = imap_adata_get(m);
1658  struct ImapMboxData *mdata = imap_mdata_get(m);
1659 
1660  if (adata->state < IMAP_SELECTED)
1661  {
1662  mutt_debug(LL_DEBUG2, "no mailbox selected\n");
1663  return -1;
1664  }
1665 
1666  /* This function is only called when the calling code expects the context
1667  * to be changed. */
1668  imap_allow_reopen(m);
1669 
1670  check = imap_check_mailbox(m, false);
1671  if (check < 0)
1672  return check;
1673 
1674  /* if we are expunging anyway, we can do deleted messages very quickly... */
1675  if (expunge && (m->rights & MUTT_ACL_DELETE))
1676  {
1677  rc = imap_exec_msgset(m, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
1678  MUTT_DELETED, true, false);
1679  if (rc < 0)
1680  {
1681  mutt_error(_("Expunge failed"));
1682  return rc;
1683  }
1684 
1685  if (rc > 0)
1686  {
1687  /* mark these messages as unchanged so second pass ignores them. Done
1688  * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
1689  for (int i = 0; i < m->msg_count; i++)
1690  {
1691  struct Email *e = m->emails[i];
1692  if (!e)
1693  break;
1694  if (e->deleted && e->changed)
1695  e->active = false;
1696  }
1697  mutt_message(ngettext("Marking %d message deleted...",
1698  "Marking %d messages deleted...", rc),
1699  rc);
1700  }
1701  }
1702 
1703 #ifdef USE_HCACHE
1704  mdata->hcache = imap_hcache_open(adata, mdata);
1705 #endif
1706 
1707  /* save messages with real (non-flag) changes */
1708  for (int i = 0; i < m->msg_count; i++)
1709  {
1710  struct Email *e = m->emails[i];
1711  if (!e)
1712  break;
1713 
1714  if (e->deleted)
1715  {
1716  imap_cache_del(m, e);
1717 #ifdef USE_HCACHE
1718  imap_hcache_del(mdata, imap_edata_get(e)->uid);
1719 #endif
1720  }
1721 
1722  if (e->active && e->changed)
1723  {
1724 #ifdef USE_HCACHE
1725  imap_hcache_put(mdata, e);
1726 #endif
1727  /* if the message has been rethreaded or attachments have been deleted
1728  * we delete the message and reupload it.
1729  * This works better if we're expunging, of course. */
1730  /* TODO: why the e->env check? */
1731  if ((e->env && e->env->changed) || e->attach_del)
1732  {
1733  /* L10N: The plural is chosen by the last %d, i.e. the total number */
1734  mutt_message(ngettext("Saving changed message... [%d/%d]",
1735  "Saving changed messages... [%d/%d]", m->msg_count),
1736  i + 1, m->msg_count);
1737  bool save_append = m->append;
1738  m->append = true;
1739  mutt_save_message_ctx(e, true, false, false, m);
1740  m->append = save_append;
1741  /* TODO: why the check for h->env? Is this possible? */
1742  if (e->env)
1743  e->env->changed = 0;
1744  }
1745  }
1746  }
1747 
1748 #ifdef USE_HCACHE
1749  imap_hcache_close(mdata);
1750 #endif
1751 
1752  /* presort here to avoid doing 10 resorts in imap_exec_msgset */
1753  oldsort = C_Sort;
1754  if (C_Sort != SORT_ORDER)
1755  {
1756  emails = m->emails;
1757  m->emails = mutt_mem_malloc(m->msg_count * sizeof(struct Email *));
1758  memcpy(m->emails, emails, m->msg_count * sizeof(struct Email *));
1759 
1760  C_Sort = SORT_ORDER;
1761  qsort(m->emails, m->msg_count, sizeof(struct Email *), mutt_get_sort_func(SORT_ORDER));
1762  }
1763 
1764  rc = sync_helper(m, MUTT_ACL_DELETE, MUTT_DELETED, "\\Deleted");
1765  if (rc >= 0)
1766  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_FLAG, "\\Flagged");
1767  if (rc >= 0)
1768  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_OLD, "Old");
1769  if (rc >= 0)
1770  rc |= sync_helper(m, MUTT_ACL_SEEN, MUTT_READ, "\\Seen");
1771  if (rc >= 0)
1772  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
1773 
1774  if (oldsort != C_Sort)
1775  {
1776  C_Sort = oldsort;
1777  FREE(&m->emails);
1778  m->emails = emails;
1779  }
1780 
1781  /* Flush the queued flags if any were changed in sync_helper. */
1782  if (rc > 0)
1783  if (imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1784  rc = -1;
1785 
1786  if (rc < 0)
1787  {
1788  if (close)
1789  {
1790  if (mutt_yesorno(_("Error saving flags. Close anyway?"), MUTT_NO) == MUTT_YES)
1791  {
1792  adata->state = IMAP_AUTHENTICATED;
1793  return 0;
1794  }
1795  }
1796  else
1797  mutt_error(_("Error saving flags"));
1798  return -1;
1799  }
1800 
1801  /* Update local record of server state to reflect the synchronization just
1802  * completed. imap_read_headers always overwrites hcache-origin flags, so
1803  * there is no need to mutate the hcache after flag-only changes. */
1804  for (int i = 0; i < m->msg_count; i++)
1805  {
1806  struct Email *e = m->emails[i];
1807  if (!e)
1808  break;
1809  struct ImapEmailData *edata = imap_edata_get(e);
1810  edata->deleted = e->deleted;
1811  edata->flagged = e->flagged;
1812  edata->old = e->old;
1813  edata->read = e->read;
1814  edata->replied = e->replied;
1815  e->changed = false;
1816  }
1817  m->changed = false;
1818 
1819  /* We must send an EXPUNGE command if we're not closing. */
1820  if (expunge && !close && (m->rights & MUTT_ACL_DELETE))
1821  {
1822  mutt_message(_("Expunging messages from server..."));
1823  /* Set expunge bit so we don't get spurious reopened messages */
1824  mdata->reopen |= IMAP_EXPUNGE_EXPECTED;
1825  if (imap_exec(adata, "EXPUNGE", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1826  {
1827  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1828  imap_error(_("imap_sync_mailbox: EXPUNGE failed"), adata->buf);
1829  return -1;
1830  }
1831  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1832  }
1833 
1834  if (expunge && close)
1835  {
1836  adata->closing = true;
1837  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
1838  adata->state = IMAP_AUTHENTICATED;
1839  }
1840 
1841  if (C_MessageCacheClean)
1842  imap_cache_clean(m);
1843 
1844  return check;
1845 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
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:988
Deleted messages.
Definition: mutt.h:99
WHERE bool C_MessageCacheClean
Config: (imap/pop) Clean out obsolete entries from the message cache.
Definition: globals.h:240
header_cache_t * imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:444
int msg_count
Total number of messages.
Definition: mailbox.h:91
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:522
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:99
Mailbox is selected.
Definition: imap_private.h:108
#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:307
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:173
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: imap_private.h:222
Flagged messages.
Definition: mutt.h:100
#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:540
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
Messages that have been replied to.
Definition: mutt.h:93
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:82
bool deleted
Definition: message.h:38
header_cache_t * hcache
Definition: imap_private.h:242
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
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:378
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:1019
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:481
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
Old messages.
Definition: mutt.h:92
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:805
Messages that have been read.
Definition: mutt.h:94
Connection is authenticated.
Definition: imap_private.h:107
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1199
IMAP-specific Account data -.
Definition: imap_private.h:168
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: imap_private.h:66
bool flagged
Marked important?
Definition: email.h:43
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
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:74
#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:1165
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: imap_private.h:72
#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:73
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
IMAP-specific Email data -.
Definition: message.h:33
sort_t mutt_get_sort_func(enum SortType method)
Get the sort function for a given sort id.
Definition: sort.c:324
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 1850 of file imap.c.

1851 {
1852  if (!a || (a->type != MUTT_IMAP) || !path)
1853  return NULL;
1854 
1855  struct Url *url = url_parse(path);
1856 
1857  struct ImapAccountData *adata = a->adata;
1858  struct ConnAccount *cac = &adata->conn->account;
1859 
1860  if (mutt_str_strcasecmp(url->host, cac->host) != 0)
1861  a = NULL;
1862  else if (url->user && (mutt_str_strcasecmp(url->user, cac->user) != 0))
1863  a = NULL;
1864 
1865  url_free(&url);
1866  return a;
1867 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
char user[128]
Username.
Definition: connaccount.h:55
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
char host[128]
Server to login to.
Definition: connaccount.h:53
char * user
Username.
Definition: url.h:69
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:51
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: imap_private.h:168
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Connection * conn
Definition: imap_private.h:170
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ 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 1872 of file imap.c.

1873 {
1874  if (!a || !m || (m->type != MUTT_IMAP))
1875  return -1;
1876 
1877  struct ImapAccountData *adata = a->adata;
1878 
1879  if (!adata)
1880  {
1881  struct ConnAccount cac = { { 0 } };
1882  char mailbox[PATH_MAX];
1883 
1884  if (imap_parse_path(mailbox_path(m), &cac, mailbox, sizeof(mailbox)) < 0)
1885  return -1;
1886 
1887  adata = imap_adata_new(a);
1888  adata->conn = mutt_conn_new(&cac);
1889  if (!adata->conn)
1890  {
1891  imap_adata_free((void **) &adata);
1892  return -1;
1893  }
1894 
1896 
1897  if (imap_login(adata) < 0)
1898  {
1899  imap_adata_free((void **) &adata);
1900  return -1;
1901  }
1902 
1903  a->adata = adata;
1905  }
1906 
1907  if (!m->mdata)
1908  {
1909  struct Url *url = url_parse(mailbox_path(m));
1910  struct ImapMboxData *mdata = imap_mdata_new(adata, url->path);
1911 
1912  /* fixup path and realpath, mainly to replace / by /INBOX */
1913  char buf[1024];
1914  imap_qualify_path(buf, sizeof(buf), &adata->conn->account, mdata->name);
1915  mutt_buffer_strcpy(&m->pathbuf, buf);
1917 
1918  m->mdata = mdata;
1920  url_free(&url);
1921  }
1922  return 0;
1923 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
struct ImapAccountData * imap_adata_new(struct Account *a)
Allocate and initialise a new ImapAccountData structure.
Definition: util.c:98
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:233
int imap_login(struct ImapAccountData *adata)
Open an IMAP connection.
Definition: imap.c:1961
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:624
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:969
void imap_adata_free(void **ptr)
Release and clear storage in an ImapAccountData structure.
Definition: util.c:72
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: util.c:171
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct Connection * mutt_conn_new(const struct ConnAccount *cac)
Create a new Connection.
Definition: mutt_socket.c:46
void(* free_adata)(void **ptr)
Callback function to free private data.
Definition: account.h:44
void mutt_account_hook(const char *url)
Perform an account hook.
Definition: hook.c:764
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:218
Login details for a remote server.
Definition: connaccount.h:51
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:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
struct Buffer pathbuf
Definition: mailbox.h:83
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
void(* free_mdata)(void **ptr)
Driver-specific data free function.
Definition: mailbox.h:137
struct Connection * conn
Definition: imap_private.h:170
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ 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 1929 of file imap.c.

1930 {
1931  struct ImapAccountData *adata = imap_adata_get(m);
1932  struct ImapMboxData *mdata = imap_mdata_get(m);
1933  if (!adata || !mdata)
1934  return;
1935 
1936  const char *condstore = NULL;
1937 #ifdef USE_HCACHE
1939  condstore = " (CONDSTORE)";
1940  else
1941 #endif
1942  condstore = "";
1943 
1944  char buf[PATH_MAX];
1945  snprintf(buf, sizeof(buf), "%s %s%s", m->readonly ? "EXAMINE" : "SELECT",
1946  mdata->munge_name, condstore);
1947 
1948  adata->state = IMAP_SELECTED;
1949 
1950  imap_cmd_start(adata, buf);
1951 }
Mailbox is selected.
Definition: imap_private.h:108
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:173
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1086
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
ImapCapFlags capabilities
Definition: imap_private.h:184
WHERE bool C_ImapCondstore
Config: (imap) Enable the CONDSTORE extension.
Definition: globals.h:220
#define IMAP_CAP_CONDSTORE
RFC7162.
Definition: imap_private.h:135
IMAP-specific Account data -.
Definition: imap_private.h:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:219
+ 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 1961 of file imap.c.

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

2039 {
2040  if (!m || !m->account || !m->mdata)
2041  return -1;
2042 
2043  char buf[PATH_MAX];
2044  int count = 0;
2045  int rc;
2046 
2047  struct ImapAccountData *adata = imap_adata_get(m);
2048  struct ImapMboxData *mdata = imap_mdata_get(m);
2049 
2050  mutt_debug(LL_DEBUG3, "opening %s, saving %s\n", m->pathbuf.data,
2051  (adata->mailbox ? adata->mailbox->pathbuf.data : "(none)"));
2052  adata->prev_mailbox = adata->mailbox;
2053  adata->mailbox = m;
2054 
2055  /* clear mailbox status */
2056  adata->status = 0;
2057  m->rights = 0;
2058  mdata->new_mail_count = 0;
2059 
2060  mutt_message(_("Selecting %s..."), mdata->name);
2061 
2062  /* pipeline ACL test */
2063  if (adata->capabilities & IMAP_CAP_ACL)
2064  {
2065  snprintf(buf, sizeof(buf), "MYRIGHTS %s", mdata->munge_name);
2066  imap_exec(adata, buf, IMAP_CMD_QUEUE);
2067  }
2068  /* assume we have all rights if ACL is unavailable */
2069  else
2070  {
2073  }
2074 
2075  /* pipeline the postponed count if possible */
2076  struct Mailbox *m_postponed = mx_mbox_find2(C_Postponed);
2077  struct ImapAccountData *postponed_adata = imap_adata_get(m_postponed);
2078  if (postponed_adata &&
2079  imap_account_match(&postponed_adata->conn->account, &adata->conn->account))
2080  {
2081  imap_mailbox_status(m_postponed, true);
2082  }
2083 
2085  imap_exec(adata, "LSUB \"\" \"*\"", IMAP_CMD_QUEUE);
2086 
2087  imap_mbox_select(m);
2088 
2089  do
2090  {
2091  char *pc = NULL;
2092 
2093  rc = imap_cmd_step(adata);
2094  if (rc != IMAP_RES_CONTINUE)
2095  break;
2096 
2097  pc = adata->buf + 2;
2098 
2099  /* Obtain list of available flags here, may be overridden by a
2100  * PERMANENTFLAGS tag in the OK response */
2101  if (mutt_str_startswith(pc, "FLAGS", CASE_IGNORE))
2102  {
2103  /* don't override PERMANENTFLAGS */
2104  if (STAILQ_EMPTY(&mdata->flags))
2105  {
2106  mutt_debug(LL_DEBUG3, "Getting mailbox FLAGS\n");
2107  pc = get_flags(&mdata->flags, pc);
2108  if (!pc)
2109  goto fail;
2110  }
2111  }
2112  /* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */
2113  else if (mutt_str_startswith(pc, "OK [PERMANENTFLAGS", CASE_IGNORE))
2114  {
2115  mutt_debug(LL_DEBUG3, "Getting mailbox PERMANENTFLAGS\n");
2116  /* safe to call on NULL */
2117  mutt_list_free(&mdata->flags);
2118  /* skip "OK [PERMANENT" so syntax is the same as FLAGS */
2119  pc += 13;
2120  pc = get_flags(&(mdata->flags), pc);
2121  if (!pc)
2122  goto fail;
2123  }
2124  /* save UIDVALIDITY for the header cache */
2125  else if (mutt_str_startswith(pc, "OK [UIDVALIDITY", CASE_IGNORE))
2126  {
2127  mutt_debug(LL_DEBUG3, "Getting mailbox UIDVALIDITY\n");
2128  pc += 3;
2129  pc = imap_next_word(pc);
2130  if (mutt_str_atoui(pc, &mdata->uidvalidity) < 0)
2131  goto fail;
2132  }
2133  else if (mutt_str_startswith(pc, "OK [UIDNEXT", CASE_IGNORE))
2134  {
2135  mutt_debug(LL_DEBUG3, "Getting mailbox UIDNEXT\n");
2136  pc += 3;
2137  pc = imap_next_word(pc);
2138  if (mutt_str_atoui(pc, &mdata->uid_next) < 0)
2139  goto fail;
2140  }
2141  else if (mutt_str_startswith(pc, "OK [HIGHESTMODSEQ", CASE_IGNORE))
2142  {
2143  mutt_debug(LL_DEBUG3, "Getting mailbox HIGHESTMODSEQ\n");
2144  pc += 3;
2145  pc = imap_next_word(pc);
2146  if (mutt_str_atoull(pc, &mdata->modseq) < 0)
2147  goto fail;
2148  }
2149  else if (mutt_str_startswith(pc, "OK [NOMODSEQ", CASE_IGNORE))
2150  {
2151  mutt_debug(LL_DEBUG3, "Mailbox has NOMODSEQ set\n");
2152  mdata->modseq = 0;
2153  }
2154  else
2155  {
2156  pc = imap_next_word(pc);
2157  if (mutt_str_startswith(pc, "EXISTS", CASE_IGNORE))
2158  {
2159  count = mdata->new_mail_count;
2160  mdata->new_mail_count = 0;
2161  }
2162  }
2163  } while (rc == IMAP_RES_CONTINUE);
2164 
2165  if (rc == IMAP_RES_NO)
2166  {
2167  char *s = imap_next_word(adata->buf); /* skip seq */
2168  s = imap_next_word(s); /* Skip response */
2169  mutt_error("%s", s);
2170  goto fail;
2171  }
2172 
2173  if (rc != IMAP_RES_OK)
2174  goto fail;
2175 
2176  /* check for READ-ONLY notification */
2177  if (mutt_str_startswith(imap_get_qualifier(adata->buf), "[READ-ONLY]", CASE_IGNORE) &&
2178  !(adata->capabilities & IMAP_CAP_ACL))
2179  {
2180  mutt_debug(LL_DEBUG2, "Mailbox is read-only\n");
2181  m->readonly = true;
2182  }
2183 
2184  /* dump the mailbox flags we've found */
2185  if (C_DebugLevel > LL_DEBUG2)
2186  {
2187  if (STAILQ_EMPTY(&mdata->flags))
2188  mutt_debug(LL_DEBUG3, "No folder flags found\n");
2189  else
2190  {
2191  struct ListNode *np = NULL;
2192  struct Buffer flag_buffer;
2193  mutt_buffer_init(&flag_buffer);
2194  mutt_buffer_printf(&flag_buffer, "Mailbox flags: ");
2195  STAILQ_FOREACH(np, &mdata->flags, entries)
2196  {
2197  mutt_buffer_add_printf(&flag_buffer, "[%s] ", np->data);
2198  }
2199  mutt_debug(LL_DEBUG3, "%s\n", flag_buffer.data);
2200  FREE(&flag_buffer.data);
2201  }
2202  }
2203 
2204  if (!((m->rights & MUTT_ACL_DELETE) || (m->rights & MUTT_ACL_SEEN) ||
2205  (m->rights & MUTT_ACL_WRITE) || (m->rights & MUTT_ACL_INSERT)))
2206  {
2207  m->readonly = true;
2208  }
2209 
2210  while (m->email_max < count)
2211  mx_alloc_memory(m);
2212 
2213  m->msg_count = 0;
2214  m->msg_unread = 0;
2215  m->msg_flagged = 0;
2216  m->msg_new = 0;
2217  m->msg_deleted = 0;
2218  m->size = 0;
2219  m->vcount = 0;
2220 
2221  if (count && (imap_read_headers(m, 1, count, true) < 0))
2222  {
2223  mutt_error(_("Error opening mailbox"));
2224  goto fail;
2225  }
2226 
2227  mutt_debug(LL_DEBUG2, "msg_count is %d\n", m->msg_count);
2228  return 0;
2229 
2230 fail:
2231  if (adata->state == IMAP_SELECTED)
2232  adata->state = IMAP_AUTHENTICATED;
2233  return -1;
2234 }
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1100
#define IMAP_CAP_ACL
RFC2086: IMAP4 ACL extension.
Definition: imap_private.h:124
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
#define MUTT_ACL_READ
Read the mailbox.
Definition: mailbox.h:72
Mailbox is selected.
Definition: imap_private.h:108
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
#define MUTT_ACL_CREATE
Create a mailbox.
Definition: mailbox.h:65
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:173
String manipulation buffer.
Definition: buffer.h:33
#define MUTT_ACL_INSERT
Add/copy into the mailbox (used when editing a message)
Definition: mailbox.h:69
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1197
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Definition: imap_private.h:206
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:1628
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
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:106
int vcount
The number of virtual messages.
Definition: mailbox.h:102
unsigned int new_mail_count
Set when EXISTS notifies of new mail.
Definition: imap_private.h:224
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
Log at debug level 2.
Definition: logging.h:41
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1193
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
struct Mailbox * prev_mailbox
Definition: imap_private.h:207
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:71
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
unsigned long long modseq
Definition: imap_private.h:230
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:938
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:100
unsigned int uidvalidity
Definition: imap_private.h:228
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:44
#define IMAP_RES_NO
<tag> NO ...
Definition: imap_private.h:53
struct ListHead flags
Definition: imap_private.h:227
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:174
char * data
Pointer to data.
Definition: buffer.h:35
Connection is authenticated.
Definition: imap_private.h:107
char * name
Mailbox name.
Definition: imap_private.h:218
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:292
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
Ignore case when comparing strings.
Definition: string2.h:68
WHERE bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: globals.h:219
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:1345
ImapCapFlags capabilities
Definition: imap_private.h:184
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
#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:921
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:56
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1929
IMAP-specific Account data -.
Definition: imap_private.h:168
unsigned int uid_next
Definition: imap_private.h:229
char * data
String.
Definition: list.h:35
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
int msg_new
Number of new messages.
Definition: mailbox.h:95
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:74
#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:1272
#define FREE(x)
Definition: memory.h:40
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:73
#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:135
struct Buffer pathbuf
Definition: mailbox.h:83
A List node for strings.
Definition: list.h:33
char * munge_name
Munged version of the mailbox name.
Definition: imap_private.h:219
Log at debug level 3.
Definition: logging.h:42
#define MUTT_ACL_LOOKUP
Lookup mailbox (visible to &#39;list&#39;)
Definition: mailbox.h:70
struct Connection * conn
Definition: imap_private.h:170
#define IMAP_RES_OK
<tag> OK ...
Definition: imap_private.h:55
+ 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 2239 of file imap.c.

2240 {
2241  if (!m || !m->account)
2242  return -1;
2243 
2244  /* in APPEND mode, we appear to hijack an existing IMAP connection -
2245  * ctx is brand new and mostly empty */
2246  struct ImapAccountData *adata = imap_adata_get(m);
2247  struct ImapMboxData *mdata = imap_mdata_get(m);
2248 
2249  int rc = imap_mailbox_status(m, false);
2250  if (rc >= 0)
2251  return 0;
2252  if (rc == -1)
2253  return -1;
2254 
2255  char buf[PATH_MAX + 64];
2256  snprintf(buf, sizeof(buf), _("Create %s?"), mdata->name);
2257  if (C_Confirmcreate && (mutt_yesorno(buf, MUTT_YES) != MUTT_YES))
2258  return -1;
2259 
2260  if (imap_create_mailbox(adata, mdata->name) < 0)
2261  return -1;
2262 
2263  return 0;
2264 }
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:210
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: imap_private.h:218
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1345
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:578
IMAP-specific Account data -.
Definition: imap_private.h:168
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
+ 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 2273 of file imap.c.

2274 {
2275  if (!m)
2276  return -1;
2277 
2278  imap_allow_reopen(m);
2279  int rc = imap_check_mailbox(m, false);
2280  /* NOTE - ctx might have been changed at this point. In particular,
2281  * m could be NULL. Beware. */
2283 
2284  return rc;
2285 }
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1178
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1199
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1165
+ 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 2290 of file imap.c.

2291 {
2292  if (!m)
2293  return -1;
2294 
2295  struct ImapAccountData *adata = imap_adata_get(m);
2296  struct ImapMboxData *mdata = imap_mdata_get(m);
2297 
2298  /* Check to see if the mailbox is actually open */
2299  if (!adata || !mdata)
2300  return 0;
2301 
2302  /* imap_mbox_open_append() borrows the struct ImapAccountData temporarily,
2303  * just for the connection.
2304  *
2305  * So when these are equal, it means we are actually closing the
2306  * mailbox and should clean up adata. Otherwise, we don't want to
2307  * touch adata - it's still being used. */
2308  if (m == adata->mailbox)
2309  {
2310  if ((adata->status != IMAP_FATAL) && (adata->state >= IMAP_SELECTED))
2311  {
2312  /* mx_mbox_close won't sync if there are no deleted messages
2313  * and the mailbox is unchanged, so we may have to close here */
2314  if (m->msg_deleted == 0)
2315  {
2316  adata->closing = true;
2317  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
2318  }
2319  adata->state = IMAP_AUTHENTICATED;
2320  }
2321 
2322  mutt_debug(LL_DEBUG3, "closing %s, restoring %s\n", m->pathbuf.data,
2323  (adata->prev_mailbox ? adata->prev_mailbox->pathbuf.data : "(none)"));
2324  adata->mailbox = adata->prev_mailbox;
2327  }
2328 
2329  return 0;
2330 }
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
Mailbox is selected.
Definition: imap_private.h:108
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: imap_private.h:173
struct Mailbox * mailbox
Definition: imap_private.h:206
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
struct Mailbox * prev_mailbox
Definition: imap_private.h:207
void * mdata
Driver specific data.
Definition: mailbox.h:136
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned char status
ImapFlags, e.g. IMAP_FATAL.
Definition: imap_private.h:174
char * data
Pointer to data.
Definition: buffer.h:35
Connection is authenticated.
Definition: imap_private.h:107
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
static void imap_mbox_select(struct Mailbox *m)
Select a Mailbox.
Definition: imap.c:1929
IMAP-specific Account data -.
Definition: imap_private.h:168
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: imap_private.h:74
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Buffer pathbuf
Definition: mailbox.h:83
Unrecoverable error occurred.
Definition: imap_private.h:95
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:220
Log at debug level 3.
Definition: logging.h:42
+ 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 2335 of file imap.c.

2336 {
2337  int rc = -1;
2338 
2339  struct Buffer *tmp = mutt_buffer_pool_get();
2340  mutt_buffer_mktemp(tmp);
2341 
2342  msg->fp = mutt_file_fopen(mutt_b2s(tmp), "w");
2343  if (!msg->fp)
2344  {
2345  mutt_perror(mutt_b2s(tmp));
2346  goto cleanup;
2347  }
2348 
2349  msg->path = mutt_buffer_strdup(tmp);
2350  rc = 0;
2351 
2352 cleanup:
2354  return rc;
2355 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
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:85
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
char * path
path to temp file
Definition: mx.h:86
+ 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 2360 of file imap.c.

2361 {
2362  struct ImapMboxData *mdata = imap_mdata_get(m);
2363  if (!mdata)
2364  return -1;
2365 
2366  char *new_tag = NULL;
2367  char *checker = NULL;
2368 
2369  /* Check for \* flags capability */
2370  if (!imap_has_flag(&mdata->flags, NULL))
2371  {
2372  mutt_error(_("IMAP server doesn't support custom flags"));
2373  return -1;
2374  }
2375 
2376  *buf = '\0';
2377  if (tags)
2378  mutt_str_strfcpy(buf, tags, buflen);
2379 
2380  if (mutt_get_field("Tags: ", buf, buflen, MUTT_COMP_NO_FLAGS) != 0)
2381  return -1;
2382 
2383  /* each keyword must be atom defined by rfc822 as:
2384  *
2385  * atom = 1*<any CHAR except specials, SPACE and CTLs>
2386  * CHAR = ( 0.-127. )
2387  * specials = "(" / ")" / "<" / ">" / "@"
2388  * / "," / ";" / ":" / "\" / <">
2389  * / "." / "[" / "]"
2390  * SPACE = ( 32. )
2391  * CTLS = ( 0.-31., 127.)
2392  *
2393  * And must be separated by one space.
2394  */
2395 
2396  new_tag = buf;
2397  checker = buf;
2398  SKIPWS(checker);
2399  while (*checker != '\0')
2400  {
2401  if ((*checker < 32) || (*checker >= 127) || // We allow space because it's the separator
2402  (*checker == 40) || // (
2403  (*checker == 41) || // )
2404  (*checker == 60) || // <
2405  (*checker == 62) || // >
2406  (*checker == 64) || // @
2407  (*checker == 44) || // ,
2408  (*checker == 59) || // ;
2409  (*checker == 58) || // :
2410  (*checker == 92) || // backslash
2411  (*checker == 34) || // "
2412  (*checker == 46) || // .
2413  (*checker == 91) || // [
2414  (*checker == 93)) // ]
2415  {
2416  mutt_error(_("Invalid IMAP flags"));
2417  return 0;
2418  }
2419 
2420  /* Skip duplicate space */
2421  while ((checker[0] == ' ') && (checker[1] == ' '))
2422  checker++;
2423 
2424  /* copy char to new_tag and go the next one */
2425  *new_tag++ = *checker++;
2426  }
2427  *new_tag = '\0';
2428  new_tag = buf; /* rewind */
2429  mutt_str_remove_trailing_ws(new_tag);
2430 
2431  if (mutt_str_strcmp(tags, buf) == 0)
2432  return 0;
2433  return 1;
2434 }
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:252
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
bool imap_has_flag(struct ListHead *flag_list, const char *flag)
Does the flag exist in the list.
Definition: imap.c:970
#define SKIPWS(ch)
Definition: string2.h:47
void * mdata
Driver specific data.
Definition: mailbox.h:136
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:757
struct ListHead flags
Definition: imap_private.h:227
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
IMAP-specific Mailbox data -.
Definition: imap_private.h:216
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:

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

2450 {
2451  if (!m)
2452  return -1;
2453 
2454  char uid[11];
2455 
2456  struct ImapAccountData *adata = imap_adata_get(m);
2457 
2458  if (*buf == '\0')
2459  buf = NULL;
2460 
2461  if (!(adata->mailbox->rights & MUTT_ACL_WRITE))
2462  return 0;
2463 
2464  snprintf(uid, sizeof(uid), "%u", imap_edata_get(e)->uid);
2465 
2466  /* Remove old custom flags */
2467  if (imap_edata_get(e)->flags_remote)
2468  {
2469  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2470  mutt_buffer_addstr(&cmd, "UID STORE ");
2471  mutt_buffer_addstr(&cmd, uid);
2472  mutt_buffer_addstr(&cmd, " -FLAGS.SILENT (");
2473  mutt_buffer_addstr(&cmd, imap_edata_get(e)->flags_remote);
2474  mutt_buffer_addstr(&cmd, ")");
2475 
2476  /* Should we return here, or we are fine and we could
2477  * continue to add new flags */
2478  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2479  mutt_buffer_dealloc(&cmd);
2480  if (rc != IMAP_EXEC_SUCCESS)
2481  {
2482  return -1;
2483  }
2484  }
2485 
2486  /* Add new custom flags */
2487  if (buf)
2488  {
2489  struct Buffer cmd = mutt_buffer_make(128); // just a guess
2490  mutt_buffer_addstr(&cmd, "UID STORE ");
2491  mutt_buffer_addstr(&cmd, uid);
2492  mutt_buffer_addstr(&cmd, " +FLAGS.SILENT (");
2493  mutt_buffer_addstr(&cmd, buf);
2494  mutt_buffer_addstr(&cmd, ")");
2495 
2496  int rc = imap_exec(adata, cmd.data, IMAP_CMD_NO_FLAGS);
2497  mutt_buffer_dealloc(&cmd);
2498  if (rc != IMAP_EXEC_SUCCESS)
2499  {
2500  mutt_debug(LL_DEBUG1, "fail to add new flags\n");
2501  return -1;
2502  }
2503  }
2504 
2505  /* We are good sync them */
2506  mutt_debug(LL_DEBUG1, "NEW TAGS: %s\n", buf);
2507  driver_tags_replace(&e->tags, buf);
2508  FREE(&imap_edata_get(e)->flags_remote);
2510  return 0;
2511 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:99
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:206
Imap command executed or queued successfully.
Definition: imap_private.h:82
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:74
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1270
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * flags_remote
Definition: message.h:48
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * data
Pointer to data.
Definition: buffer.h:35
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:120
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
IMAP-specific Account data -.
Definition: imap_private.h:168
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:72
#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 2516 of file imap.c.

2517 {
2518  if (!path)
2519  return MUTT_UNKNOWN;
2520 
2521  if (mutt_str_startswith(path, "imap://", CASE_IGNORE))
2522  return MUTT_IMAP;
2523 
2524  if (mutt_str_startswith(path, "imaps://", CASE_IGNORE))
2525  return MUTT_IMAP;
2526 
2527  return MUTT_UNKNOWN;
2528 }
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
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:53
+ 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 2533 of file imap.c.

2534 {
2535  if (!buf)
2536  return -1;
2537 
2538  struct Url *url = url_parse(buf);
2539  if (!url)
2540  return 0;
2541 
2542  char tmp[PATH_MAX];
2543  char tmp2[PATH_MAX];
2544 
2545  imap_fix_path('\0', url->path, tmp, sizeof(tmp));
2546  url->path = tmp;
2547  url_tostring(url, tmp2, sizeof(tmp2), 0);
2548  mutt_str_strfcpy(buf, tmp2, buflen);
2549  url_free(&url);
2550 
2551  return 0;
2552 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
#define PATH_MAX
Definition: mutt.h:44
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:824
char * path
Path.
Definition: url.h:73
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:416
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ 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 2562 of file imap.c.

2563 {
2565  return imap_path_canon(buf->data, PATH_MAX);
2566 }
#define PATH_MAX
Definition: mutt.h:44
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:2533
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 2571 of file imap.c.

2572 {
2573  if (!buf || !folder)
2574  return -1;
2575 
2576  imap_pretty_mailbox(buf, buflen, folder);
2577  return 0;
2578 }
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:732
+ 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 2583 of file imap.c.

2584 {
2585  char tmp[PATH_MAX] = { 0 };
2586 
2587  imap_get_parent_path(buf, tmp, sizeof(tmp));
2588  mutt_str_strfcpy(buf, tmp, buflen);
2589  return 0;
2590 }
void imap_get_parent_path(const char *path, char *buf, size_t buflen)
Get the path of the parent folder.
Definition: util.c:307
#define PATH_MAX
Definition: mutt.h:44
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
+ Here is the call graph for this function:

Variable Documentation

◆ C_ImapDeflate

bool C_ImapDeflate

Config: (imap) Compress network traffic.

Definition at line 64 of file imap.c.

◆ C_ImapIdle

bool C_ImapIdle

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

Definition at line 70 of file imap.c.

◆ C_ImapRfc5161

bool C_ImapRfc5161

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

Definition at line 71 of file imap.c.

◆ MxImapOps

struct MxOps MxImapOps
Initial value:
= {
.type = MUTT_IMAP,
.name = "imap",
.is_local = false,
.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:2516
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:2360
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:2335
static int imap_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
Definition: imap.c:2583
static int imap_mbox_open(struct Mailbox *m)
Open a mailbox - Implements MxOps::mbox_open()
Definition: imap.c:2038
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:1850
static int imap_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
Definition: imap.c:1872
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:1308
static int imap_mbox_check(struct Mailbox *m, int *index_hint)
Check for new mail - Implements MxOps::mbox_check()
Definition: imap.c:2273
static int imap_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close()
Definition: imap.c:2290
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:2449
static int imap_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
Definition: imap.c:2571
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: imap.c:2533
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
static int imap_mbox_open_append(struct Mailbox *m, OpenMailboxFlags flags)
Open a Mailbox for appending - Implements MxOps::mbox_open_append()
Definition: imap.c:2239

IMAP Mailbox - Implements MxOps.

Definition at line 2596 of file imap.c.