NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference

IMAP network mailbox. More...

#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <sys/types.h>
#include "core/lib.h"
#include "mx.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void imap_init (void)
 Setup feature commands. More...
 
int imap_access (const char *path)
 Check permissions on an IMAP mailbox with a new connection. More...
 
int imap_check_mailbox (struct Mailbox *m, bool force)
 use the NOOP or IDLE command to poll for new mail More...
 
int imap_delete_mailbox (struct Mailbox *m, char *path)
 Delete a mailbox. More...
 
int imap_sync_mailbox (struct Mailbox *m, bool expunge, bool close)
 Sync all the changes to the server. More...
 
int imap_path_status (const char *path, bool queue)
 Refresh the number of total and new messages. More...
 
int imap_mailbox_status (struct Mailbox *m, bool queue)
 Refresh the number of total and new messages. More...
 
int imap_subscribe (char *path, bool subscribe)
 Subscribe to a mailbox. More...
 
int imap_complete (char *buf, size_t buflen, const char *path)
 Try to complete an IMAP folder path. More...
 
int imap_fast_trash (struct Mailbox *m, char *dest)
 Use server COPY command to copy deleted messages to trash. More...
 
enum 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...
 
void imap_notify_delete_email (struct Mailbox *m, struct Email *e)
 Inform IMAP that an Email has been deleted. More...
 
int imap_browse (const char *path, struct BrowserState *state)
 IMAP hook into the folder browser. More...
 
int imap_mailbox_create (const char *folder)
 Create a new IMAP mailbox. More...
 
int imap_mailbox_rename (const char *path)
 Rename a mailbox. More...
 
bool config_init_imap (struct ConfigSet *cs)
 Register imap config variables - Implements module_init_config_t. More...
 
int imap_copy_messages (struct Mailbox *m, struct EmailList *el, const char *dest, bool delete_original)
 Server COPY messages to another folder. More...
 
void imap_logout_all (void)
 close all open connections More...
 
int imap_expand_path (struct Buffer *buf)
 Buffer wrapper around imap_path_canon() More...
 
int imap_parse_path (const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
 Parse an IMAP mailbox name into ConnAccount, name. More...
 
void imap_pretty_mailbox (char *path, size_t pathlen, const char *folder)
 Prettify an IMAP mailbox name. More...
 
int imap_mxcmp (const char *mx1, const char *mx2)
 Compare mailbox names, giving priority to INBOX. More...
 
int imap_wait_keepalive (pid_t pid)
 Wait for a process to change state. More...
 
void imap_keepalive (void)
 poll the current folder to keep the connection alive More...
 
void imap_get_parent_path (const char *path, char *buf, size_t buflen)
 Get the path of the parent folder. More...
 
void imap_clean_path (char *path, size_t plen)
 Cleans an IMAP path using imap_fix_path. More...
 
bool imap_search (struct Mailbox *m, const struct PatternList *pat)
 Find messages in mailbox matching a pattern. More...
 

Variables

short C_ImapKeepalive
 Config: (imap) Time to wait before polling an open IMAP connection. More...
 
bool C_ImapListSubscribed
 Config: (imap) When browsing a mailbox, only display subscribed folders. More...
 
bool C_ImapPassive
 Config: (imap) Reuse an existing IMAP connection to check for new mail. More...
 
bool C_ImapPeek
 Config: (imap) Don't mark messages as read when fetching them from the server. More...
 
struct MxOps MxImapOps
 IMAP Mailbox - Implements MxOps. More...
 

Detailed Description

IMAP network mailbox.

Authors
  • Michael R. Elkins
  • 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 lib.h.

Function Documentation

◆ imap_init()

void imap_init ( void  )

Setup feature commands.

Definition at line 79 of file imap.c.

80 {
82 }
#define COMMANDS_REGISTER(cmds)
Definition: mutt_commands.h:77
static const struct Command imap_commands[]
Definition: imap.c:69
+ 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 467 of file imap.c.

468 {
469  if (imap_path_status(path, false) >= 0)
470  return 0;
471  return -1;
472 }
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1211
+ 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 1091 of file imap.c.

1092 {
1093  if (!m || !m->account)
1094  return -1;
1095 
1096  struct ImapAccountData *adata = imap_adata_get(m);
1097  struct ImapMboxData *mdata = imap_mdata_get(m);
1098 
1099  /* overload keyboard timeout to avoid many mailbox checks in a row.
1100  * Most users don't like having to wait exactly when they press a key. */
1101  int rc = 0;
1102 
1103  /* try IDLE first, unless force is set */
1104  if (!force && C_ImapIdle && (adata->capabilities & IMAP_CAP_IDLE) &&
1105  ((adata->state != IMAP_IDLE) || (mutt_date_epoch() >= adata->lastread + C_ImapKeepalive)))
1106  {
1107  if (imap_cmd_idle(adata) < 0)
1108  return -1;
1109  }
1110  if (adata->state == IMAP_IDLE)
1111  {
1112  while ((rc = mutt_socket_poll(adata->conn, 0)) > 0)
1113  {
1114  if (imap_cmd_step(adata) != IMAP_RES_CONTINUE)
1115  {
1116  mutt_debug(LL_DEBUG1, "Error reading IDLE response\n");
1117  return -1;
1118  }
1119  }
1120  if (rc < 0)
1121  {
1122  mutt_debug(LL_DEBUG1, "Poll failed, disabling IDLE\n");
1123  adata->capabilities &= ~IMAP_CAP_IDLE; // Clear the flag
1124  }
1125  }
1126 
1127  if ((force || ((adata->state != IMAP_IDLE) &&
1128  (mutt_date_epoch() >= adata->lastread + C_Timeout))) &&
1129  (imap_exec(adata, "NOOP", IMAP_CMD_POLL) != IMAP_EXEC_SUCCESS))
1130  {
1131  return -1;
1132  }
1133 
1134  /* We call this even when we haven't run NOOP in case we have pending
1135  * changes to process, since we can reopen here. */
1136  imap_cmd_finish(adata);
1137 
1138  if (mdata->check_status & IMAP_EXPUNGE_PENDING)
1139  rc = MUTT_REOPENED;
1140  else if (mdata->check_status & IMAP_NEWMAIL_PENDING)
1141  rc = MUTT_NEW_MAIL;
1142  else if (mdata->check_status & IMAP_FLAGS_PENDING)
1143  rc = MUTT_FLAGS;
1144 
1146 
1147  return rc;
1148 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: mutt_globals.h:115
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: private.h:70
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:76
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
Imap command executed or queued successfully.
Definition: private.h:84
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
Definition: command.c:1373
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: private.h:224
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:1242
Nondestructive flags change (IMAP)
Definition: mx.h:76
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1306
ImapCapFlags capabilities
Definition: private.h:186
#define IMAP_OPEN_NO_FLAGS
No flags are set.
Definition: private.h:65
time_t lastread
last time we read a command for the server
Definition: private.h:189
Connection is idle.
Definition: private.h:113
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
IMAP-specific Account data -.
Definition: private.h:170
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
Log at debug level 1.
Definition: logging.h:40
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:69
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
New mail received in Mailbox.
Definition: mx.h:73
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
Mailbox was reopened.
Definition: mx.h:75
bool C_ImapIdle
Config: (imap) Use the IMAP IDLE extension to check for new mail.
Definition: config.c:48
#define IMAP_CAP_IDLE
RFC2177: IDLE.
Definition: private.h:134
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: private.h:68
struct Connection * conn
Definition: private.h:172
+ 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 509 of file imap.c.

510 {
511  char buf[PATH_MAX + 7];
512  char mbox[PATH_MAX];
513  struct Url *url = url_parse(path);
514 
515  struct ImapAccountData *adata = imap_adata_get(m);
516  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), url->path);
517  url_free(&url);
518  snprintf(buf, sizeof(buf), "DELETE %s", mbox);
520  return -1;
521 
522  return 0;
523 }
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:1045
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
Imap command executed or queued successfully.
Definition: private.h:84
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1242
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
char * path
Path.
Definition: url.h:73
IMAP-specific Account data -.
Definition: private.h:170
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ 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 1506 of file imap.c.

1507 {
1508  if (!m)
1509  return -1;
1510 
1511  struct Email **emails = NULL;
1512  int oldsort;
1513  int rc;
1514  int check;
1515 
1516  struct ImapAccountData *adata = imap_adata_get(m);
1517  struct ImapMboxData *mdata = imap_mdata_get(m);
1518 
1519  if (adata->state < IMAP_SELECTED)
1520  {
1521  mutt_debug(LL_DEBUG2, "no mailbox selected\n");
1522  return -1;
1523  }
1524 
1525  /* This function is only called when the calling code expects the context
1526  * to be changed. */
1527  imap_allow_reopen(m);
1528 
1529  check = imap_check_mailbox(m, false);
1530  if (check < 0)
1531  return check;
1532 
1533  /* if we are expunging anyway, we can do deleted messages very quickly... */
1534  if (expunge && (m->rights & MUTT_ACL_DELETE))
1535  {
1536  rc = imap_exec_msgset(m, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
1537  MUTT_DELETED, true, false);
1538  if (rc < 0)
1539  {
1540  mutt_error(_("Expunge failed"));
1541  return rc;
1542  }
1543 
1544  if (rc > 0)
1545  {
1546  /* mark these messages as unchanged so second pass ignores them. Done
1547  * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
1548  for (int i = 0; i < m->msg_count; i++)
1549  {
1550  struct Email *e = m->emails[i];
1551  if (!e)
1552  break;
1553  if (e->deleted && e->changed)
1554  e->active = false;
1555  }
1556  if (m->verbose)
1557  {
1558  mutt_message(ngettext("Marking %d message deleted...",
1559  "Marking %d messages deleted...", rc),
1560  rc);
1561  }
1562  }
1563  }
1564 
1565 #ifdef USE_HCACHE
1566  imap_hcache_open(adata, mdata);
1567 #endif
1568 
1569  /* save messages with real (non-flag) changes */
1570  for (int i = 0; i < m->msg_count; i++)
1571  {
1572  struct Email *e = m->emails[i];
1573  if (!e)
1574  break;
1575 
1576  if (e->deleted)
1577  {
1578  imap_cache_del(m, e);
1579 #ifdef USE_HCACHE
1580  imap_hcache_del(mdata, imap_edata_get(e)->uid);
1581 #endif
1582  }
1583 
1584  if (e->active && e->changed)
1585  {
1586 #ifdef USE_HCACHE
1587  imap_hcache_put(mdata, e);
1588 #endif
1589  /* if the message has been rethreaded or attachments have been deleted
1590  * we delete the message and reupload it.
1591  * This works better if we're expunging, of course. */
1592  /* TODO: why the e->env check? */
1593  if ((e->env && e->env->changed) || e->attach_del)
1594  {
1595  /* L10N: The plural is chosen by the last %d, i.e. the total number */
1596  if (m->verbose)
1597  {
1598  mutt_message(ngettext("Saving changed message... [%d/%d]",
1599  "Saving changed messages... [%d/%d]", m->msg_count),
1600  i + 1, m->msg_count);
1601  }
1602  bool save_append = m->append;
1603  m->append = true;
1604  mutt_save_message_ctx(e, true, false, false, m);
1605  m->append = save_append;
1606  /* TODO: why the check for e->env? Is this possible? */
1607  if (e->env)
1608  e->env->changed = 0;
1609  }
1610  }
1611  }
1612 
1613 #ifdef USE_HCACHE
1614  imap_hcache_close(mdata);
1615 #endif
1616 
1617  /* presort here to avoid doing 10 resorts in imap_exec_msgset */
1618  oldsort = C_Sort;
1619  if (C_Sort != SORT_ORDER)
1620  {
1621  emails = m->emails;
1622  m->emails = mutt_mem_malloc(m->msg_count * sizeof(struct Email *));
1623  memcpy(m->emails, emails, m->msg_count * sizeof(struct Email *));
1624 
1625  C_Sort = SORT_ORDER;
1626  qsort(m->emails, m->msg_count, sizeof(struct Email *), mutt_get_sort_func(SORT_ORDER));
1627  }
1628 
1629  rc = sync_helper(m, MUTT_ACL_DELETE, MUTT_DELETED, "\\Deleted");
1630  if (rc >= 0)
1631  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_FLAG, "\\Flagged");
1632  if (rc >= 0)
1633  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_OLD, "Old");
1634  if (rc >= 0)
1635  rc |= sync_helper(m, MUTT_ACL_SEEN, MUTT_READ, "\\Seen");
1636  if (rc >= 0)
1637  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
1638 
1639  if (oldsort != C_Sort)
1640  {
1641  C_Sort = oldsort;
1642  FREE(&m->emails);
1643  m->emails = emails;
1644  }
1645 
1646  /* Flush the queued flags if any were changed in sync_helper. */
1647  if (rc > 0)
1648  if (imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1649  rc = -1;
1650 
1651  if (rc < 0)
1652  {
1653  if (close)
1654  {
1655  if (mutt_yesorno(_("Error saving flags. Close anyway?"), MUTT_NO) == MUTT_YES)
1656  {
1657  adata->state = IMAP_AUTHENTICATED;
1658  return 0;
1659  }
1660  }
1661  else
1662  mutt_error(_("Error saving flags"));
1663  return -1;
1664  }
1665 
1666  /* Update local record of server state to reflect the synchronization just
1667  * completed. imap_read_headers always overwrites hcache-origin flags, so
1668  * there is no need to mutate the hcache after flag-only changes. */
1669  for (int i = 0; i < m->msg_count; i++)
1670  {
1671  struct Email *e = m->emails[i];
1672  if (!e)
1673  break;
1674  struct ImapEmailData *edata = imap_edata_get(e);
1675  edata->deleted = e->deleted;
1676  edata->flagged = e->flagged;
1677  edata->old = e->old;
1678  edata->read = e->read;
1679  edata->replied = e->replied;
1680  e->changed = false;
1681  }
1682  m->changed = false;
1683 
1684  /* We must send an EXPUNGE command if we're not closing. */
1685  if (expunge && !close && (m->rights & MUTT_ACL_DELETE))
1686  {
1687  if (m->verbose)
1688  mutt_message(_("Expunging messages from server..."));
1689  /* Set expunge bit so we don't get spurious reopened messages */
1690  mdata->reopen |= IMAP_EXPUNGE_EXPECTED;
1691  if (imap_exec(adata, "EXPUNGE", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1692  {
1693  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1694  imap_error(_("imap_sync_mailbox: EXPUNGE failed"), adata->buf);
1695  return -1;
1696  }
1697  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1698  }
1699 
1700  if (expunge && close)
1701  {
1702  adata->closing = true;
1703  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
1704  adata->state = IMAP_AUTHENTICATED;
1705  }
1706 
1707  if (C_MessageCacheClean)
1708  imap_cache_clean(m);
1709 
1710  return check;
1711 }
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:998
Deleted messages.
Definition: mutt.h:101
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
int msg_count
Total number of messages.
Definition: mailbox.h:91
The envelope/body of an email.
Definition: email.h:37
bool C_MessageCacheClean
Config: (imap/pop) Clean out obsolete entries from the message cache.
Definition: bcache.c:44
Connection is authenticated.
Definition: private.h:109
#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:318
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:516
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:534
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:223
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1732
Flagged messages.
Definition: mutt.h:102
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
Messages that have been replied to.
Definition: mutt.h:95
Imap command executed or queued successfully.
Definition: private.h:84
bool flagged
Definition: message.h:39
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
bool deleted
Definition: message.h:38
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:379
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
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:50
struct Envelope * env
Envelope information.
Definition: email.h:90
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:911
Mailbox is selected.
Definition: private.h:110
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:60
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:1242
Old messages.
Definition: mutt.h:94
bool closing
If true, we are waiting for CLOSE completion.
Definition: private.h:174
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
bool active
Message is not to be removed.
Definition: email.h:59
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
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: private.h:67
Messages that have been read.
Definition: mutt.h:96
bool replied
Definition: message.h:40
bool old
Definition: message.h:37
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
bool verbose
Display status messages?
Definition: mailbox.h:118
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1150
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
int imap_cache_clean(struct Mailbox *m)
Delete all the entries in the message cache.
Definition: message.c:1751
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1091
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
bool flagged
Marked important?
Definition: email.h:43
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
#define mutt_error(...)
Definition: logging.h:84
bool replied
Email has been replied to.
Definition: email.h:54
#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
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
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
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
+ Here is the call graph for this function:
+ Here is the caller 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 1211 of file imap.c.

1212 {
1213  struct Mailbox *m = mx_mbox_find2(path);
1214 
1215  const bool is_temp = !m;
1216  if (is_temp)
1217  {
1218  m = mx_path_resolve(path);
1219  if (!mx_mbox_ac_link(m))
1220  {
1221  mailbox_free(&m);
1222  return 0;
1223  }
1224  }
1225 
1226  int rc = imap_mailbox_status(m, queue);
1227 
1228  if (is_temp)
1229  {
1230  mx_ac_remove(m);
1231  }
1232 
1233  return rc;
1234 }
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1654
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:63
A mailbox.
Definition: mailbox.h:81
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1245
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
bool mx_mbox_ac_link(struct Mailbox *m)
Link a Mailbox to an existing or new Account.
Definition: mx.c:266
int mx_ac_remove(struct Mailbox *m)
Remove a Mailbox from an Account and delete Account if empty.
Definition: mx.c:1784
+ 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 1245 of file imap.c.

1246 {
1247  struct ImapAccountData *adata = imap_adata_get(m);
1248  struct ImapMboxData *mdata = imap_mdata_get(m);
1249  if (!adata || !mdata)
1250  return -1;
1251  return imap_status(adata, mdata, queue);
1252 }
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1157
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

1262 {
1263  struct ImapAccountData *adata = NULL;
1264  struct ImapMboxData *mdata = NULL;
1265  char buf[2048];
1266  struct Buffer err;
1267 
1268  if (imap_adata_find(path, &adata, &mdata) < 0)
1269  return -1;
1270 
1271  if (subscribe)
1272  mutt_message(_("Subscribing to %s..."), mdata->name);
1273  else
1274  mutt_message(_("Unsubscribing from %s..."), mdata->name);
1275 
1276  snprintf(buf, sizeof(buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mdata->munge_name);
1277 
1278  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1279  {
1280  imap_mdata_free((void *) &mdata);
1281  return -1;
1282  }
1283 
1285  {
1286  char mbox[1024];
1287  mutt_buffer_init(&err);
1288  err.dsize = 256;
1289  err.data = mutt_mem_malloc(err.dsize);
1290  size_t len = snprintf(mbox, sizeof(mbox), "%smailboxes ", subscribe ? "" : "un");
1291  imap_quote_string(mbox + len, sizeof(mbox) - len, path, true);
1292  if (mutt_parse_rc_line(mbox, &err))
1293  mutt_debug(LL_DEBUG1, "Error adding subscribed mailbox: %s\n", err.data);
1294  FREE(&err.data);
1295  }
1296 
1297  if (subscribe)
1298  mutt_message(_("Subscribed to %s"), mdata->name);
1299  else
1300  mutt_message(_("Unsubscribed from %s"), mdata->name);
1301  imap_mdata_free((void *) &mdata);
1302  return 0;
1303 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
#define mutt_message(...)
Definition: logging.h:83
String manipulation buffer.
Definition: buffer.h:33
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1039
#define _(a)
Definition: message.h:28
Imap command executed or queued successfully.
Definition: private.h:84
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
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:1242
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 * name
Mailbox name.
Definition: private.h:219
bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: config.c:40
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
IMAP-specific Account data -.
Definition: private.h:170
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: private.h:217
#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: private.h:220
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:971
+ 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 1316 of file imap.c.

1317 {
1318  struct ImapAccountData *adata = NULL;
1319  struct ImapMboxData *mdata = NULL;
1320  char tmp[2048];
1321  struct ImapList listresp = { 0 };
1322  char completion[1024];
1323  int clen;
1324  size_t matchlen = 0;
1325  int completions = 0;
1326  int rc;
1327 
1328  if (imap_adata_find(path, &adata, &mdata) < 0)
1329  {
1330  mutt_str_copy(buf, path, buflen);
1331  return complete_hosts(buf, buflen);
1332  }
1333 
1334  /* fire off command */
1335  snprintf(tmp, sizeof(tmp), "%s \"\" \"%s%%\"",
1336  C_ImapListSubscribed ? "LSUB" : "LIST", mdata->real_name);
1337 
1338  imap_cmd_start(adata, tmp);
1339 
1340  /* and see what the results are */
1341  mutt_str_copy(completion, mdata->name, sizeof(completion));
1342  imap_mdata_free((void *) &mdata);
1343 
1344  adata->cmdresult = &listresp;
1345  do
1346  {
1347  listresp.name = NULL;
1348  rc = imap_cmd_step(adata);
1349 
1350  if ((rc == IMAP_RES_CONTINUE) && listresp.name)
1351  {
1352  /* if the folder isn't selectable, append delimiter to force browse
1353  * to enter it on second tab. */
1354  if (listresp.noselect)
1355  {
1356  clen = strlen(listresp.name);
1357  listresp.name[clen++] = listresp.delim;
1358  listresp.name[clen] = '\0';
1359  }
1360  /* copy in first word */
1361  if (!completions)
1362  {
1363  mutt_str_copy(completion, listresp.name, sizeof(completion));
1364  matchlen = strlen(completion);
1365  completions++;
1366  continue;
1367  }
1368 
1369  matchlen = longest_common_prefix(completion, listresp.name, 0, matchlen);
1370  completions++;
1371  }
1372  } while (rc == IMAP_RES_CONTINUE);
1373  adata->cmdresult = NULL;
1374 
1375  if (completions)
1376  {
1377  /* reformat output */
1378  imap_qualify_path(buf, buflen, &adata->conn->account, completion);
1379  mutt_pretty_mailbox(buf, buflen);
1380  return 0;
1381  }
1382 
1383  return -1;
1384 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:522
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
Items in an IMAP browser.
Definition: private.h:148
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
char delim
Definition: private.h:151
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: config.c:50
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:379
void * mdata
Driver specific data.
Definition: mailbox.h:136
char * name
Definition: private.h:150
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:219
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:221
IMAP-specific Account data -.
Definition: private.h:170
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:358
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
IMAP-specific Mailbox data -.
Definition: private.h:217
struct ImapList * cmdresult
Definition: private.h:197
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
bool noselect
Definition: private.h:152
struct Connection * conn
Definition: private.h:172
+ 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 1394 of file imap.c.

1395 {
1396  char prompt[1024];
1397  int rc = -1;
1398  bool triedcreate = false;
1399  enum QuadOption err_continue = MUTT_NO;
1400 
1401  struct ImapAccountData *adata = imap_adata_get(m);
1402  struct ImapAccountData *dest_adata = NULL;
1403  struct ImapMboxData *dest_mdata = NULL;
1404 
1405  if (imap_adata_find(dest, &dest_adata, &dest_mdata) < 0)
1406  return -1;
1407 
1408  struct Buffer sync_cmd = mutt_buffer_make(0);
1409 
1410  /* check that the save-to folder is in the same account */
1411  if (!imap_account_match(&(adata->conn->account), &(dest_adata->conn->account)))
1412  {
1413  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1414  goto out;
1415  }
1416 
1417  for (int i = 0; i < m->msg_count; i++)
1418  {
1419  struct Email *e = m->emails[i];
1420  if (!e)
1421  break;
1422  if (e->active && e->changed && e->deleted && !e->purge)
1423  {
1424  rc = imap_sync_message_for_copy(m, e, &sync_cmd, &err_continue);
1425  if (rc < 0)
1426  {
1427  mutt_debug(LL_DEBUG1, "could not sync\n");
1428  goto out;
1429  }
1430  }
1431  }
1432 
1433  /* loop in case of TRYCREATE */
1434  do
1435  {
1436  rc = imap_exec_msgset(m, "UID COPY", dest_mdata->munge_name, MUTT_TRASH, false, false);
1437  if (rc == 0)
1438  {
1439  mutt_debug(LL_DEBUG1, "No messages to trash\n");
1440  rc = -1;
1441  goto out;
1442  }
1443  else if (rc < 0)
1444  {
1445  mutt_debug(LL_DEBUG1, "could not queue copy\n");
1446  goto out;
1447  }
1448  else if (m->verbose)
1449  {
1450  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1451  rc, dest_mdata->name);
1452  }
1453 
1454  /* let's get it on */
1455  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1456  if (rc == IMAP_EXEC_ERROR)
1457  {
1458  if (triedcreate)
1459  {
1460  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", dest_mdata->name);
1461  break;
1462  }
1463  /* bail out if command failed for reasons other than nonexistent target */
1464  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1465  break;
1466  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1467  snprintf(prompt, sizeof(prompt), _("Create %s?"), dest_mdata->name);
1468  if (C_Confirmcreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1469  {
1470  mutt_clear_error();
1471  goto out;
1472  }
1473  if (imap_create_mailbox(adata, dest_mdata->name) < 0)
1474  break;
1475  triedcreate = true;
1476  }
1477  } while (rc == IMAP_EXEC_ERROR);
1478 
1479  if (rc != IMAP_EXEC_SUCCESS)
1480  {
1481  imap_error("imap_fast_trash", adata->buf);
1482  goto out;
1483  }
1484 
1485  rc = IMAP_EXEC_SUCCESS;
1486 
1487 out:
1488  mutt_buffer_dealloc(&sync_cmd);
1489  imap_mdata_free((void *) &dest_mdata);
1490 
1491  return ((rc == IMAP_EXEC_SUCCESS) ? 0 : -1);
1492 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
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:203
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
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
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
Imap command executed or queued successfully.
Definition: private.h:84
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
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:911
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:1242
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:989
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
bool active
Message is not to be removed.
Definition: email.h:59
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:219
bool verbose
Display status messages?
Definition: mailbox.h:118
bool purge
Skip trash folder when deleting.
Definition: email.h:46
WHERE bool C_Confirmcreate
Config: Confirm before creating a new mailbox.
Definition: mutt_globals.h:142
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:441
Imap command failure.
Definition: private.h:85
IMAP-specific Account data -.
Definition: private.h:170
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:906
Log at debug level 1.
Definition: logging.h:40
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
bool deleted
Email is deleted.
Definition: email.h:45
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * munge_name
Munged version of the mailbox name.
Definition: private.h:220
Trashed messages.
Definition: mutt.h:108
Log at debug level 3.
Definition: logging.h:42
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Connection * conn
Definition: private.h:172
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

2368 {
2369  if (mutt_istr_startswith(path, "imap://"))
2370  return MUTT_IMAP;
2371 
2372  if (mutt_istr_startswith(path, "imaps://"))
2373  return MUTT_IMAP;
2374 
2375  return MUTT_UNKNOWN;
2376 }
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
&#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 2381 of file imap.c.

2382 {
2383  struct Url *url = url_parse(buf);
2384  if (!url)
2385  return 0;
2386 
2387  char tmp[PATH_MAX];
2388  char tmp2[PATH_MAX];
2389 
2390  imap_fix_path('\0', url->path, tmp, sizeof(tmp));
2391  url->path = tmp;
2392  url_tostring(url, tmp2, sizeof(tmp2), 0);
2393  mutt_str_copy(buf, tmp2, buflen);
2394  url_free(&url);
2395 
2396  return 0;
2397 }
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:123
#define PATH_MAX
Definition: mutt.h:44
char * path
Path.
Definition: url.h:73
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:418
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_notify_delete_email()

void imap_notify_delete_email ( struct Mailbox m,
struct Email e 
)

Inform IMAP that an Email has been deleted.

Parameters
mMailbox
eEmail

Definition at line 645 of file imap.c.

646 {
647  struct ImapMboxData *mdata = imap_mdata_get(m);
648  struct ImapEmailData *edata = imap_edata_get(e);
649 
650  if (!mdata || !edata)
651  return;
652 
653  imap_msn_remove(&mdata->msn, edata->msn - 1);
654  edata->msn = 0;
655 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
unsigned int msn
Message Sequence Number.
Definition: message.h:45
void imap_msn_remove(struct MSN *msn, size_t idx)
Remove an entry from the cache.
Definition: msn.c:113
void * mdata
Driver specific data.
Definition: mailbox.h:136
IMAP-specific Mailbox data -.
Definition: private.h:217
void * edata
Driver-specific data.
Definition: email.h:111
IMAP-specific Email data -.
Definition: message.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_browse()

int imap_browse ( const char *  path,
struct BrowserState state 
)

IMAP hook into the folder browser.

Parameters
pathCurrent folder
stateBrowserState to populate
Return values
0Success
-1Failure

Fill out browser_state, given a current folder to browse

Definition at line 179 of file browse.c.

180 {
181  struct ImapAccountData *adata = NULL;
182  struct ImapList list = { 0 };
183  struct ConnAccount cac = { { 0 } };
184  char buf[PATH_MAX + 16];
185  char mbox[PATH_MAX];
186  char munged_mbox[PATH_MAX];
187  const char *list_cmd = NULL;
188  int len;
189  int n;
190  char ctmp;
191  bool showparents = false;
192  bool save_lsub;
193 
194  if (imap_parse_path(path, &cac, buf, sizeof(buf)))
195  {
196  mutt_error(_("%s is an invalid IMAP path"), path);
197  return -1;
198  }
199 
200  save_lsub = C_ImapCheckSubscribed;
201  C_ImapCheckSubscribed = false;
202 
203  // Pick first mailbox connected to the same server
204  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
206  struct MailboxNode *np = NULL;
207  STAILQ_FOREACH(np, &ml, entries)
208  {
209  adata = imap_adata_get(np->mailbox);
210  // Pick first mailbox connected on the same server
211  if (imap_account_match(&adata->conn->account, &cac))
212  break;
213  adata = NULL;
214  }
216  if (!adata)
217  goto fail;
218 
220  {
221  /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
222  * The newer LIST extensions are designed for this. */
224  list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
225  else
226  list_cmd = "LSUB";
227  }
228  else
229  {
230  list_cmd = "LIST";
231  }
232 
233  mutt_message(_("Getting folder list..."));
234 
235  /* skip check for parents when at the root */
236  if (buf[0] == '\0')
237  {
238  mbox[0] = '\0';
239  n = 0;
240  }
241  else
242  {
243  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
244  n = mutt_str_len(mbox);
245  }
246 
247  if (n)
248  {
249  int rc;
250  mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
251 
252  /* if our target exists and has inferiors, enter it if we
253  * aren't already going to */
254  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
255  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
257  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
258  imap_cmd_start(adata, buf);
259  adata->cmdresult = &list;
260  do
261  {
262  list.name = 0;
263  rc = imap_cmd_step(adata);
264  if ((rc == IMAP_RES_CONTINUE) && list.name)
265  {
266  if (!list.noinferiors && list.name[0] &&
267  (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
268  {
269  mbox[n++] = list.delim;
270  mbox[n] = '\0';
271  }
272  }
273  } while (rc == IMAP_RES_CONTINUE);
274  adata->cmdresult = NULL;
275 
276  /* if we're descending a folder, mark it as current in browser_state */
277  if (mbox[n - 1] == list.delim)
278  {
279  showparents = true;
280  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
281  state->folder = mutt_str_dup(buf);
282  n--;
283  }
284 
285  /* Find superiors to list
286  * Note: UW-IMAP servers return folder + delimiter when asked to list
287  * folder + delimiter. Cyrus servers don't. So we ask for folder,
288  * and tack on delimiter ourselves.
289  * Further note: UW-IMAP servers return nothing when asked for
290  * NAMESPACES without delimiters at the end. Argh! */
291  for (n--; n >= 0 && mbox[n] != list.delim; n--)
292  ; // do nothing
293 
294  if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
295  {
296  /* forget the check, it is too delicate (see above). Have we ever
297  * had the parent not exist? */
298  ctmp = mbox[n];
299  mbox[n] = '\0';
300 
301  if (showparents)
302  {
303  mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
304  add_folder(list.delim, mbox, true, false, state, true);
305  }
306 
307  /* if our target isn't a folder, we are in our superior */
308  if (!state->folder)
309  {
310  /* store folder with delimiter */
311  mbox[n++] = ctmp;
312  ctmp = mbox[n];
313  mbox[n] = '\0';
314  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
315  state->folder = mutt_str_dup(buf);
316  }
317  mbox[n] = ctmp;
318  }
319  /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
320  else
321  {
322  char relpath[2];
323  /* folder may be "/" */
324  snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
325  if (showparents)
326  add_folder(adata->delim, relpath, true, false, state, true);
327  if (!state->folder)
328  {
329  imap_qualify_path(buf, sizeof(buf), &cac, relpath);
330  state->folder = mutt_str_dup(buf);
331  }
332  }
333  }
334 
335  /* no namespace, no folder: set folder to host only */
336  if (!state->folder)
337  {
338  imap_qualify_path(buf, sizeof(buf), &cac, NULL);
339  state->folder = mutt_str_dup(buf);
340  }
341 
342  mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
343  snprintf(buf, sizeof(buf), "%s%%", mbox);
344  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
345  mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
346  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
348  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
349  if (browse_add_list_result(adata, buf, state, false))
350  goto fail;
351 
352  if (ARRAY_EMPTY(&state->entry))
353  {
354  // L10N: (%s) is the name / path of the folder we were trying to browse
355  mutt_error(_("No such folder: %s"), path);
356  goto fail;
357  }
358 
360 
361  if (save_lsub)
362  C_ImapCheckSubscribed = true;
363 
364  return 0;
365 
366 fail:
367  if (save_lsub)
368  C_ImapCheckSubscribed = true;
369  return -1;
370 }
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1071
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_message(...)
Definition: logging.h:83
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:618
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1045
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
struct BrowserStateEntry entry
Definition: browser.h:97
Items in an IMAP browser.
Definition: private.h:148
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1057
char delim
Definition: private.h:151
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:100
bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: config.c:50
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:689
#define PATH_MAX
Definition: mutt.h:44
char * name
Definition: private.h:150
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: config.c:40
ImapCapFlags capabilities
Definition: private.h:186
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition: private.h:139
Login details for a remote server.
Definition: connaccount.h:51
bool noinferiors
Definition: private.h:153
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
#define mutt_error(...)
Definition: logging.h:84
static int browse_add_list_result(struct ImapAccountData *adata, const char *cmd, struct BrowserState *state, bool isparent)
Add entries to the folder browser.
Definition: browse.c:139
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct ImapList * cmdresult
Definition: private.h:197
List of Mailboxes.
Definition: mailbox.h:152
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
static void add_folder(char delim, char *folder, bool noselect, bool noinferiors, struct BrowserState *state, bool isparent)
Format and add an IMAP folder to the browser.
Definition: browse.c:60
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
Log at debug level 3.
Definition: logging.h:42
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
struct Connection * conn
Definition: private.h:172
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mailbox_create()

int imap_mailbox_create ( const char *  path)

Create a new IMAP mailbox.

Parameters
pathMailbox to create
Return values
0Success
-1Failure

Prompt for a new mailbox name, and try to create it

Definition at line 380 of file browse.c.

381 {
382  struct ImapAccountData *adata = NULL;
383  struct ImapMboxData *mdata = NULL;
384  char name[1024];
385  short n;
386 
387  if (imap_adata_find(path, &adata, &mdata) < 0)
388  {
389  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
390  goto err;
391  }
392 
393  /* append a delimiter if necessary */
394  mutt_str_copy(name, mdata->real_name, sizeof(name));
395  n = mutt_str_len(name);
396  if (n && (n < sizeof(name) - 1) && (name[n - 1] != adata->delim))
397  {
398  name[n++] = adata->delim;
399  name[n] = '\0';
400  }
401 
402  if (mutt_get_field(_("Create mailbox: "), name, sizeof(name), MUTT_FILE) < 0)
403  goto err;
404 
405  if (mutt_str_len(name) == 0)
406  {
407  mutt_error(_("Mailbox must have a name"));
408  goto err;
409  }
410 
411  if (imap_create_mailbox(adata, name) < 0)
412  goto err;
413 
414  imap_mdata_free((void *) &mdata);
415  mutt_message(_("Mailbox created"));
416  mutt_sleep(0);
417  return 0;
418 
419 err:
420  imap_mdata_free((void *) &mdata);
421  return -1;
422 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:219
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:441
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:221
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
IMAP-specific Account data -.
Definition: private.h:170
Log at debug level 1.
Definition: logging.h:40
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
IMAP-specific Mailbox data -.
Definition: private.h:217
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mailbox_rename()

int imap_mailbox_rename ( const char *  path)

Rename a mailbox.

Parameters
pathMailbox to rename
Return values
0Success
-1Failure

The user will be prompted for a new name.

Definition at line 432 of file browse.c.

433 {
434  struct ImapAccountData *adata = NULL;
435  struct ImapMboxData *mdata = NULL;
436  char buf[PATH_MAX];
437  char newname[PATH_MAX];
438 
439  if (imap_adata_find(path, &adata, &mdata) < 0)
440  {
441  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
442  return -1;
443  }
444 
445  if (mdata->real_name[0] == '\0')
446  {
447  mutt_error(_("Can't rename root folder"));
448  goto err;
449  }
450 
451  snprintf(buf, sizeof(buf), _("Rename mailbox %s to: "), mdata->name);
452  mutt_str_copy(newname, mdata->name, sizeof(newname));
453 
454  if (mutt_get_field(buf, newname, sizeof(newname), MUTT_FILE) < 0)
455  goto err;
456 
457  if (mutt_str_len(newname) == 0)
458  {
459  mutt_error(_("Mailbox must have a name"));
460  goto err;
461  }
462 
463  imap_fix_path(adata->delim, newname, buf, sizeof(buf));
464 
465  if (imap_rename_mailbox(adata, mdata->name, buf) < 0)
466  {
467  mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
468  goto err;
469  }
470 
471  mutt_message(_("Mailbox renamed"));
472  mutt_sleep(0);
473  return 0;
474 
475 err:
476  imap_mdata_free((void *) &mdata);
477  return -1;
478 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
#define mutt_message(...)
Definition: logging.h:83
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition: imap.c:482
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
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: private.h:219
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:221
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
IMAP-specific Account data -.
Definition: private.h:170
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:906
Log at debug level 1.
Definition: logging.h:40
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
#define mutt_error(...)
Definition: logging.h:84
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ config_init_imap()

bool config_init_imap ( struct ConfigSet cs)

Register imap config variables - Implements module_init_config_t.

Definition at line 165 of file config.c.

166 {
167  return cs_register_variables(cs, ImapVars, 0);
168 }
struct ConfigDef ImapVars[]
Definition: config.c:91
bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], int flags)
Register a set of config items.
Definition: set.c:286
+ Here is the call graph for this function:

◆ imap_copy_messages()

int imap_copy_messages ( struct Mailbox m,
struct EmailList *  el,
const char *  dest,
bool  delete_original 
)

Server COPY messages to another folder.

Parameters
mMailbox
elList of Emails to copy
destDestination folder
delete_originalDelete the original?
Return values
-1Error
0Success
1Non-fatal error - try fetch/append

Definition at line 1560 of file message.c.

1561 {
1562  if (!m || !el || !dest)
1563  return -1;
1564 
1565  struct Buffer cmd, sync_cmd;
1566  char buf[PATH_MAX];
1567  char mbox[PATH_MAX];
1568  char mmbox[PATH_MAX];
1569  char prompt[PATH_MAX + 64];
1570  int rc;
1571  struct ConnAccount cac = { { 0 } };
1572  enum QuadOption err_continue = MUTT_NO;
1573  int triedcreate = 0;
1574  struct EmailNode *en = STAILQ_FIRST(el);
1575  bool single = !STAILQ_NEXT(en, entries);
1576  struct ImapAccountData *adata = imap_adata_get(m);
1577 
1578  if (single && en->email->attach_del)
1579  {
1580  mutt_debug(LL_DEBUG3, "#1 Message contains attachments to be deleted\n");
1581  return 1;
1582  }
1583 
1584  if (imap_parse_path(dest, &cac, buf, sizeof(buf)))
1585  {
1586  mutt_debug(LL_DEBUG1, "bad destination %s\n", dest);
1587  return -1;
1588  }
1589 
1590  /* check that the save-to folder is in the same account */
1591  if (!imap_account_match(&adata->conn->account, &cac))
1592  {
1593  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1594  return 1;
1595  }
1596 
1597  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
1598  if (*mbox == '\0')
1599  mutt_str_copy(mbox, "INBOX", sizeof(mbox));
1600  imap_munge_mbox_name(adata->unicode, mmbox, sizeof(mmbox), mbox);
1601 
1602  /* loop in case of TRYCREATE */
1603  do
1604  {
1605  mutt_buffer_init(&sync_cmd);
1606  mutt_buffer_init(&cmd);
1607 
1608  if (!single) /* copy tagged messages */
1609  {
1610  /* if any messages have attachments to delete, fall through to FETCH
1611  * and APPEND. TODO: Copy what we can with COPY, fall through for the
1612  * remainder. */
1613  STAILQ_FOREACH(en, el, entries)
1614  {
1615  if (en->email->attach_del)
1616  {
1618  "#2 Message contains attachments to be deleted\n");
1619  return 1;
1620  }
1621 
1622  if (en->email->active && en->email->changed)
1623  {
1624  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1625  if (rc < 0)
1626  {
1627  mutt_debug(LL_DEBUG1, "#1 could not sync\n");
1628  goto out;
1629  }
1630  }
1631  }
1632 
1633  rc = imap_exec_msgset(m, "UID COPY", mmbox, MUTT_TAG, false, false);
1634  if (rc == 0)
1635  {
1636  mutt_debug(LL_DEBUG1, "No messages tagged\n");
1637  rc = -1;
1638  goto out;
1639  }
1640  else if (rc < 0)
1641  {
1642  mutt_debug(LL_DEBUG1, "#1 could not queue copy\n");
1643  goto out;
1644  }
1645  else
1646  {
1647  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1648  rc, mbox);
1649  }
1650  }
1651  else
1652  {
1653  mutt_message(_("Copying message %d to %s..."), en->email->index + 1, mbox);
1654  mutt_buffer_add_printf(&cmd, "UID COPY %u %s", imap_edata_get(en->email)->uid, mmbox);
1655 
1656  if (en->email->active && en->email->changed)
1657  {
1658  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1659  if (rc < 0)
1660  {
1661  mutt_debug(LL_DEBUG1, "#2 could not sync\n");
1662  goto out;
1663  }
1664  }
1665  rc = imap_exec(adata, cmd.data, IMAP_CMD_QUEUE);
1666  if (rc != IMAP_EXEC_SUCCESS)
1667  {
1668  mutt_debug(LL_DEBUG1, "#2 could not queue copy\n");
1669  goto out;
1670  }
1671  }
1672 
1673  /* let's get it on */
1674  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1675  if (rc == IMAP_EXEC_ERROR)
1676  {
1677  if (triedcreate)
1678  {
1679  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", mbox);
1680  break;
1681  }
1682  /* bail out if command failed for reasons other than nonexistent target */
1683  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1684  break;
1685  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1686  snprintf(prompt, sizeof(prompt), _("Create %s?"), mbox);
1687  if (C_Confirmcreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1688  {
1689  mutt_clear_error();
1690  goto out;
1691  }
1692  if (imap_create_mailbox(adata, mbox) < 0)
1693  break;
1694  triedcreate = 1;
1695  }
1696  } while (rc == IMAP_EXEC_ERROR);
1697 
1698  if (rc != 0)
1699  {
1700  imap_error("imap_copy_messages", adata->buf);
1701  goto out;
1702  }
1703 
1704  /* cleanup */
1705  if (delete_original)
1706  {
1707  STAILQ_FOREACH(en, el, entries)
1708  {
1709  mutt_set_flag(m, en->email, MUTT_DELETE, true);
1710  mutt_set_flag(m, en->email, MUTT_PURGE, true);
1711  if (C_DeleteUntag)
1712  mutt_set_flag(m, en->email, MUTT_TAG, false);
1713  }
1714  }
1715 
1716  rc = 0;
1717 
1718 out:
1719  FREE(&cmd.data);
1720  FREE(&sync_cmd.data);
1721 
1722  return (rc < 0) ? -1 : rc;
1723 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:203
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: mutt_globals.h:145
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define mutt_message(...)
Definition: logging.h:83
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:618
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1045
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
Messages to be purged (bypass trash)
Definition: mutt.h:100
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
Imap command executed or queued successfully.
Definition: private.h:84
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
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:911
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
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:1242
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:989
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
bool active
Message is not to be removed.
Definition: email.h:59
unsigned int uid
32-bit Message UID
Definition: message.h:44
Messages to be deleted.
Definition: mutt.h:98
#define PATH_MAX
Definition: mutt.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Tagged messages.
Definition: mutt.h:103
WHERE bool C_Confirmcreate
Config: Confirm before creating a new mailbox.
Definition: mutt_globals.h:142
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:441
Login details for a remote server.
Definition: connaccount.h:51
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
Imap command failure.
Definition: private.h:85
IMAP-specific Account data -.
Definition: private.h:170
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:906
Log at debug level 1.
Definition: logging.h:40
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
char * buf
Definition: private.h:190
struct Email * email
Email in the list.
Definition: email.h:127
int index
The absolute (unsorted) message number.
Definition: email.h:86
#define FREE(x)
Definition: memory.h:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
List of Emails.
Definition: email.h:125
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
#define STAILQ_FIRST(head)
Definition: queue.h:347
Log at debug level 3.
Definition: logging.h:42
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:193
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Connection * conn
Definition: private.h:172
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

555 {
556  struct Account *np = NULL;
557  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
558  {
559  if (np->type != MUTT_IMAP)
560  continue;
561 
562  struct ImapAccountData *adata = np->adata;
563  if (!adata)
564  continue;
565 
566  struct Connection *conn = adata->conn;
567  if (!conn || (conn->fd < 0))
568  continue;
569 
570  mutt_message(_("Closing connection to %s..."), conn->account.host);
571  imap_logout(np->adata);
573  }
574 }
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:40
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:529
#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:36
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: private.h:170
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Connection * conn
Definition: private.h:172
+ 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 2407 of file imap.c.

2408 {
2410  return imap_path_canon(buf->data, PATH_MAX);
2411 }
#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:2381
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_parse_path()

int imap_parse_path ( const char *  path,
struct ConnAccount cac,
char *  mailbox,
size_t  mailboxlen 
)

Parse an IMAP mailbox name into ConnAccount, name.

Parameters
pathMailbox path to parse
cacAccount credentials
mailboxBuffer for mailbox name
mailboxlenLength of buffer
Return values
0Success
-1Failure

Given an IMAP mailbox name, return host, port and a path IMAP servers will recognize.

Definition at line 618 of file util.c.

619 {
620  static unsigned short ImapPort = 0;
621  static unsigned short ImapsPort = 0;
622 
623  if (ImapPort == 0)
624  {
625  struct servent *service = getservbyname("imap", "tcp");
626  if (service)
627  ImapPort = ntohs(service->s_port);
628  else
629  ImapPort = IMAP_PORT;
630  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
631  }
632 
633  if (ImapsPort == 0)
634  {
635  struct servent *service = getservbyname("imaps", "tcp");
636  if (service)
637  ImapsPort = ntohs(service->s_port);
638  else
639  ImapsPort = IMAP_SSL_PORT;
640  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
641  }
642 
643  /* Defaults */
644  cac->port = ImapPort;
645  cac->type = MUTT_ACCT_TYPE_IMAP;
646  cac->service = "imap";
647  cac->get_field = imap_get_field;
648 
649  struct Url *url = url_parse(path);
650  if (!url)
651  return -1;
652 
653  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
654  {
655  url_free(&url);
656  return -1;
657  }
658 
659  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
660  {
661  url_free(&url);
662  return -1;
663  }
664 
665  if (url->scheme == U_IMAPS)
666  cac->flags |= MUTT_ACCT_SSL;
667 
668  mutt_str_copy(mailbox, url->path, mailboxlen);
669 
670  url_free(&url);
671 
672  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
673  cac->port = ImapsPort;
674 
675  return 0;
676 }
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:46
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:45
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:68
Url is imaps://.
Definition: url.h:39
Url is imap://.
Definition: url.h:38
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:342
char host[128]
Server to login to.
Definition: connaccount.h:53
unsigned short port
Port to connect to.
Definition: connaccount.h:57
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:42
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
Imap Account.
Definition: mutt_account.h:37
char * path
Path.
Definition: url.h:73
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_pretty_mailbox()

void imap_pretty_mailbox ( char *  path,
size_t  pathlen,
const char *  folder 
)

Prettify an IMAP mailbox name.

Parameters
pathMailbox name to be tidied
pathlenLength of path
folderPath to use for '+' abbreviations

Called by mutt_pretty_mailbox() to make IMAP paths look nice.

Definition at line 725 of file util.c.

726 {
727  struct ConnAccount cac_target = { { 0 } };
728  struct ConnAccount cac_home = { { 0 } };
729  struct Url url = { 0 };
730  char *delim = NULL;
731  int tlen;
732  int hlen = 0;
733  bool home_match = false;
734  char target_mailbox[1024];
735  char home_mailbox[1024];
736 
737  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
738  return;
739 
740  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
741  goto fallback;
742 
743  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
744  goto fallback;
745 
746  tlen = mutt_str_len(target_mailbox);
747  hlen = mutt_str_len(home_mailbox);
748 
749  /* check whether we can do '+' substitution */
750  if (tlen && imap_account_match(&cac_home, &cac_target) &&
751  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
752  {
753  if (hlen == 0)
754  home_match = true;
755  else if (C_ImapDelimChars)
756  {
757  for (delim = C_ImapDelimChars; *delim != '\0'; delim++)
758  if (target_mailbox[hlen] == *delim)
759  home_match = true;
760  }
761  }
762 
763  /* do the '+' substitution */
764  if (home_match)
765  {
766  *path++ = '+';
767  /* copy remaining path, skipping delimiter */
768  if (hlen == 0)
769  hlen = -1;
770  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
771  path[tlen - hlen - 1] = '\0';
772  return;
773  }
774 
775 fallback:
776  mutt_account_tourl(&cac_target, &url);
777  url.path = target_mailbox;
778  url_tostring(&url, path, pathlen, 0);
779 }
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2367
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:618
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:45
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
Login details for a remote server.
Definition: connaccount.h:51
char * path
Path.
Definition: url.h:73
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:418
&#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_mxcmp()

int imap_mxcmp ( const char *  mx1,
const char *  mx2 
)

Compare mailbox names, giving priority to INBOX.

Parameters
mx1First mailbox name
mx2Second mailbox name
Return values
<0First mailbox precedes Second mailbox
0Mailboxes are the same
>0Second mailbox precedes First mailbox

Like a normal sort function except that "INBOX" will be sorted to the beginning of the list.

Definition at line 689 of file util.c.

690 {
691  char *b1 = NULL;
692  char *b2 = NULL;
693  int rc;
694 
695  if (!mx1 || (*mx1 == '\0'))
696  mx1 = "INBOX";
697  if (!mx2 || (*mx2 == '\0'))
698  mx2 = "INBOX";
699  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
700  {
701  return 0;
702  }
703 
704  b1 = mutt_mem_malloc(strlen(mx1) + 1);
705  b2 = mutt_mem_malloc(strlen(mx2) + 1);
706 
707  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
708  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
709 
710  rc = mutt_str_cmp(b1, b2);
711  FREE(&b1);
712  FREE(&b2);
713 
714  return rc;
715 }
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:567
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_wait_keepalive()

int imap_wait_keepalive ( pid_t  pid)

Wait for a process to change state.

Parameters
pidProcess ID to listen to
Return values
num'wstatus' from waitpid()

Definition at line 1102 of file util.c.

1103 {
1104  struct sigaction oldalrm;
1105  struct sigaction act;
1106  sigset_t oldmask;
1107  int rc;
1108 
1109  bool imap_passive = C_ImapPassive;
1110 
1111  C_ImapPassive = true;
1112  OptKeepQuiet = true;
1113 
1114  sigprocmask(SIG_SETMASK, NULL, &oldmask);
1115 
1116  sigemptyset(&act.sa_mask);
1117  act.sa_handler = mutt_sig_empty_handler;
1118 #ifdef SA_INTERRUPT
1119  act.sa_flags = SA_INTERRUPT;
1120 #else
1121  act.sa_flags = 0;
1122 #endif
1123 
1124  sigaction(SIGALRM, &act, &oldalrm);
1125 
1126  alarm(C_ImapKeepalive);
1127  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1128  {
1129  alarm(0); /* cancel a possibly pending alarm */
1130  imap_keepalive();
1131  alarm(C_ImapKeepalive);
1132  }
1133 
1134  alarm(0); /* cancel a possibly pending alarm */
1135 
1136  sigaction(SIGALRM, &oldalrm, NULL);
1137  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1138 
1139  OptKeepQuiet = false;
1140  if (!imap_passive)
1141  C_ImapPassive = false;
1142 
1143  return rc;
1144 }
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
bool C_ImapPassive
Config: (imap) Reuse an existing IMAP connection to check for new mail.
Definition: config.c:54
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:1079
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_keepalive()

void imap_keepalive ( void  )

poll the current folder to keep the connection alive

Definition at line 1079 of file util.c.

1080 {
1081  time_t now = mutt_date_epoch();
1082  struct Account *np = NULL;
1083  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1084  {
1085  if (np->type != MUTT_IMAP)
1086  continue;
1087 
1088  struct ImapAccountData *adata = np->adata;
1089  if (!adata || !adata->mailbox)
1090  continue;
1091 
1092  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + C_ImapKeepalive)))
1093  imap_check_mailbox(adata->mailbox, true);
1094  }
1095 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Connection is authenticated.
Definition: private.h:109
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
A group of associated Mailboxes.
Definition: account.h:36
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
time_t lastread
last time we read a command for the server
Definition: private.h:189
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1091
IMAP-specific Account data -.
Definition: private.h:170
&#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_get_parent_path()

void imap_get_parent_path ( const char *  path,
char *  buf,
size_t  buflen 
)

Get the path of the parent folder.

Parameters
pathMailbox whose parent is to be determined
bufBuffer for the result
buflenLength of the buffer

Provided an imap path, returns in buf the parent directory if existent. Else returns the same path.

Definition at line 299 of file util.c.

300 {
301  struct ImapAccountData *adata = NULL;
302  struct ImapMboxData *mdata = NULL;
303  char mbox[1024];
304 
305  if (imap_adata_find(path, &adata, &mdata) < 0)
306  {
307  mutt_str_copy(buf, path, buflen);
308  return;
309  }
310 
311  /* Gets the parent mbox in mbox */
312  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
313 
314  /* Returns a fully qualified IMAP url */
315  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
316  imap_mdata_free((void *) &mdata);
317 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder&#39;s parent.
Definition: util.c:258
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:219
IMAP-specific Account data -.
Definition: private.h:170
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
IMAP-specific Mailbox data -.
Definition: private.h:217
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
struct Connection * conn
Definition: private.h:172
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_clean_path()

void imap_clean_path ( char *  path,
size_t  plen 
)

Cleans an IMAP path using imap_fix_path.

Parameters
pathPath to be cleaned
plenLength of the buffer

Does it in place.

Definition at line 326 of file util.c.

327 {
328  struct ImapAccountData *adata = NULL;
329  struct ImapMboxData *mdata = NULL;
330 
331  if (imap_adata_find(path, &adata, &mdata) < 0)
332  return;
333 
334  /* Returns a fully qualified IMAP url */
335  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
336  imap_mdata_free((void *) &mdata);
337 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:219
IMAP-specific Account data -.
Definition: private.h:170
IMAP-specific Mailbox data -.
Definition: private.h:217
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
struct Connection * conn
Definition: private.h:172
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_search()

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

Find messages in mailbox matching a pattern.

Parameters
mMailbox
patPattern to match
Return values
trueSuccess
falseFailure

Definition at line 228 of file search.c.

229 {
230  for (int i = 0; i < m->msg_count; i++)
231  {
232  struct Email *e = m->emails[i];
233  if (!e)
234  break;
235  e->matched = false;
236  }
237 
238  if (check_pattern_list(pat) == 0)
239  return true;
240 
241  struct Buffer buf;
242  mutt_buffer_init(&buf);
243  mutt_buffer_addstr(&buf, "UID SEARCH ");
244 
245  struct ImapAccountData *adata = imap_adata_get(m);
246  const bool ok = compile_search(adata, SLIST_FIRST(pat), &buf) &&
248 
249  FREE(&buf.data);
250  return ok;
251 }
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
static bool compile_search(const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
Convert NeoMutt pattern to IMAP search.
Definition: search.c:208
String manipulation buffer.
Definition: buffer.h:33
Imap command executed or queued successfully.
Definition: private.h:84
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1242
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
static int check_pattern_list(const struct PatternList *patterns)
Check how many patterns in a list can be searched server-side.
Definition: search.c:82
#define SLIST_FIRST(head)
Definition: queue.h:228
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
IMAP-specific Account data -.
Definition: private.h:170
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
char * buf
Definition: private.h:190
#define 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:

Variable Documentation

◆ C_ImapKeepalive

short C_ImapKeepalive

Config: (imap) Time to wait before polling an open IMAP connection.

Definition at line 49 of file config.c.

◆ C_ImapListSubscribed

bool C_ImapListSubscribed

Config: (imap) When browsing a mailbox, only display subscribed folders.

Definition at line 50 of file config.c.

◆ C_ImapPassive

bool C_ImapPassive

Config: (imap) Reuse an existing IMAP connection to check for new mail.

Definition at line 54 of file config.c.

◆ C_ImapPeek

bool C_ImapPeek

Config: (imap) Don't mark messages as read when fetching them from the server.

Definition at line 55 of file config.c.

◆ MxImapOps

struct MxOps MxImapOps

IMAP Mailbox - Implements MxOps.

Definition at line 2454 of file imap.c.