NeoMutt  2021-02-05-666-ge300cd
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 "commands.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, const 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...
 
int imap_copy_messages (struct Mailbox *m, struct EmailList *el, const char *dest, enum MessageSaveOpt save_opt)
 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

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

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

475 {
476  if (imap_path_status(path, false) >= 0)
477  return 0;
478  return -1;
479 }
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1235
+ 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 enum MxStatus

Definition at line 1103 of file imap.c.

1104 {
1105  if (!m || !m->account)
1106  return MX_STATUS_ERROR;
1107 
1108  struct ImapAccountData *adata = imap_adata_get(m);
1109  struct ImapMboxData *mdata = imap_mdata_get(m);
1110 
1111  /* overload keyboard timeout to avoid many mailbox checks in a row.
1112  * Most users don't like having to wait exactly when they press a key. */
1113  int rc = 0;
1114 
1115  /* try IDLE first, unless force is set */
1116  const bool c_imap_idle = cs_subset_bool(NeoMutt->sub, "imap_idle");
1117  const short c_imap_keepalive =
1118  cs_subset_number(NeoMutt->sub, "imap_keepalive");
1119  if (!force && c_imap_idle && (adata->capabilities & IMAP_CAP_IDLE) &&
1120  ((adata->state != IMAP_IDLE) || (mutt_date_epoch() >= adata->lastread + c_imap_keepalive)))
1121  {
1122  if (imap_cmd_idle(adata) < 0)
1123  return MX_STATUS_ERROR;
1124  }
1125  if (adata->state == IMAP_IDLE)
1126  {
1127  while ((rc = mutt_socket_poll(adata->conn, 0)) > 0)
1128  {
1129  if (imap_cmd_step(adata) != IMAP_RES_CONTINUE)
1130  {
1131  mutt_debug(LL_DEBUG1, "Error reading IDLE response\n");
1132  return MX_STATUS_ERROR;
1133  }
1134  }
1135  if (rc < 0)
1136  {
1137  mutt_debug(LL_DEBUG1, "Poll failed, disabling IDLE\n");
1138  adata->capabilities &= ~IMAP_CAP_IDLE; // Clear the flag
1139  }
1140  }
1141 
1142  const short c_timeout = cs_subset_number(NeoMutt->sub, "timeout");
1143  if ((force || ((adata->state != IMAP_IDLE) &&
1144  (mutt_date_epoch() >= adata->lastread + c_timeout))) &&
1145  (imap_exec(adata, "NOOP", IMAP_CMD_POLL) != IMAP_EXEC_SUCCESS))
1146  {
1147  return MX_STATUS_ERROR;
1148  }
1149 
1150  /* We call this even when we haven't run NOOP in case we have pending
1151  * changes to process, since we can reopen here. */
1152  imap_cmd_finish(adata);
1153 
1154  enum MxStatus check = MX_STATUS_OK;
1155  if (mdata->check_status & IMAP_EXPUNGE_PENDING)
1156  check = MX_STATUS_REOPENED;
1157  else if (mdata->check_status & IMAP_NEWMAIL_PENDING)
1158  check = MX_STATUS_NEW_MAIL;
1159  else if (mdata->check_status & IMAP_FLAGS_PENDING)
1160  check = MX_STATUS_FLAGS;
1161  else if (rc < 0)
1162  check = MX_STATUS_ERROR;
1163 
1165 
1166  return check;
1167 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1079
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: adata.h:44
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: private.h:70
Nondestructive flags change (IMAP)
Definition: mxapi.h:82
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:76
New mail received in Mailbox.
Definition: mxapi.h:79
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
Mailbox was reopened.
Definition: mxapi.h:81
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:192
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
Definition: command.c:1383
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:59
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition: mdata.h:45
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:1250
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
No changes.
Definition: mxapi.h:78
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1316
ImapCapFlags capabilities
Definition: adata.h:55
#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: adata.h:58
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Connection is idle.
Definition: private.h:113
IMAP-specific Account data -.
Definition: adata.h:39
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: mdata.h:38
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:69
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
#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
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
struct Connection * conn
Definition: adata.h:41
An error occurred.
Definition: mxapi.h:77
+ 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 516 of file imap.c.

517 {
518  char buf[PATH_MAX + 7];
519  char mbox[PATH_MAX];
520  struct Url *url = url_parse(path);
521 
522  struct ImapAccountData *adata = imap_adata_get(m);
523  imap_munge_mbox_name(adata->unicode, mbox, sizeof(mbox), url->path);
524  url_free(&url);
525  snprintf(buf, sizeof(buf), "DELETE %s", mbox);
527  return -1;
528 
529  return 0;
530 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
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:914
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:1250
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
char * path
Path.
Definition: url.h:75
IMAP-specific Account data -.
Definition: adata.h:39
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: adata.h:62
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
enumMxStatus
Note
The flag retvals come from a call to imap_check_mailbox()

Definition at line 1534 of file imap.c.

1535 {
1536  if (!m)
1537  return -1;
1538 
1539  struct Email **emails = NULL;
1540  int rc;
1541 
1542  struct ImapAccountData *adata = imap_adata_get(m);
1543  struct ImapMboxData *mdata = imap_mdata_get(m);
1544 
1545  if (adata->state < IMAP_SELECTED)
1546  {
1547  mutt_debug(LL_DEBUG2, "no mailbox selected\n");
1548  return -1;
1549  }
1550 
1551  /* This function is only called when the calling code expects the context
1552  * to be changed. */
1553  imap_allow_reopen(m);
1554 
1555  enum MxStatus check = imap_check_mailbox(m, false);
1556  if (check == MX_STATUS_ERROR)
1557  return check;
1558 
1559  /* if we are expunging anyway, we can do deleted messages very quickly... */
1560  if (expunge && (m->rights & MUTT_ACL_DELETE))
1561  {
1562  rc = imap_exec_msgset(m, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
1563  MUTT_DELETED, true, false);
1564  if (rc < 0)
1565  {
1566  mutt_error(_("Expunge failed"));
1567  return rc;
1568  }
1569 
1570  if (rc > 0)
1571  {
1572  /* mark these messages as unchanged so second pass ignores them. Done
1573  * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
1574  for (int i = 0; i < m->msg_count; i++)
1575  {
1576  struct Email *e = m->emails[i];
1577  if (!e)
1578  break;
1579  if (e->deleted && e->changed)
1580  e->active = false;
1581  }
1582  if (m->verbose)
1583  {
1584  mutt_message(ngettext("Marking %d message deleted...",
1585  "Marking %d messages deleted...", rc),
1586  rc);
1587  }
1588  }
1589  }
1590 
1591 #ifdef USE_HCACHE
1592  imap_hcache_open(adata, mdata);
1593 #endif
1594 
1595  /* save messages with real (non-flag) changes */
1596  for (int i = 0; i < m->msg_count; i++)
1597  {
1598  struct Email *e = m->emails[i];
1599  if (!e)
1600  break;
1601 
1602  if (e->deleted)
1603  {
1604  imap_cache_del(m, e);
1605 #ifdef USE_HCACHE
1606  imap_hcache_del(mdata, imap_edata_get(e)->uid);
1607 #endif
1608  }
1609 
1610  if (e->active && e->changed)
1611  {
1612 #ifdef USE_HCACHE
1613  imap_hcache_put(mdata, e);
1614 #endif
1615  /* if the message has been rethreaded or attachments have been deleted
1616  * we delete the message and reupload it.
1617  * This works better if we're expunging, of course. */
1618  /* TODO: why the e->env check? */
1619  if ((e->env && e->env->changed) || e->attach_del)
1620  {
1621  /* L10N: The plural is chosen by the last %d, i.e. the total number */
1622  if (m->verbose)
1623  {
1624  mutt_message(ngettext("Saving changed message... [%d/%d]",
1625  "Saving changed messages... [%d/%d]", m->msg_count),
1626  i + 1, m->msg_count);
1627  }
1628  bool save_append = m->append;
1629  m->append = true;
1631  m->append = save_append;
1632  /* TODO: why the check for e->env? Is this possible? */
1633  if (e->env)
1634  e->env->changed = 0;
1635  }
1636  }
1637  }
1638 
1639 #ifdef USE_HCACHE
1640  imap_hcache_close(mdata);
1641 #endif
1642 
1643  /* presort here to avoid doing 10 resorts in imap_exec_msgset */
1644  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
1645  if (c_sort != SORT_ORDER)
1646  {
1647  emails = m->emails;
1648  m->emails = mutt_mem_malloc(m->msg_count * sizeof(struct Email *));
1649  memcpy(m->emails, emails, m->msg_count * sizeof(struct Email *));
1650 
1652  qsort(m->emails, m->msg_count, sizeof(struct Email *), compare_uid);
1653  }
1654 
1655  rc = sync_helper(m, MUTT_ACL_DELETE, MUTT_DELETED, "\\Deleted");
1656  if (rc >= 0)
1657  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_FLAG, "\\Flagged");
1658  if (rc >= 0)
1659  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_OLD, "Old");
1660  if (rc >= 0)
1661  rc |= sync_helper(m, MUTT_ACL_SEEN, MUTT_READ, "\\Seen");
1662  if (rc >= 0)
1663  rc |= sync_helper(m, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
1664 
1665  if (c_sort != SORT_ORDER)
1666  {
1667  cs_subset_str_native_set(NeoMutt->sub, "sort", c_sort, NULL);
1668  FREE(&m->emails);
1669  m->emails = emails;
1670  }
1671 
1672  /* Flush the queued flags if any were changed in sync_helper. */
1673  if (rc > 0)
1674  if (imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1675  rc = -1;
1676 
1677  if (rc < 0)
1678  {
1679  if (close)
1680  {
1681  if (mutt_yesorno(_("Error saving flags. Close anyway?"), MUTT_NO) == MUTT_YES)
1682  {
1683  adata->state = IMAP_AUTHENTICATED;
1684  return 0;
1685  }
1686  }
1687  else
1688  mutt_error(_("Error saving flags"));
1689  return -1;
1690  }
1691 
1692  /* Update local record of server state to reflect the synchronization just
1693  * completed. imap_read_headers always overwrites hcache-origin flags, so
1694  * there is no need to mutate the hcache after flag-only changes. */
1695  for (int i = 0; i < m->msg_count; i++)
1696  {
1697  struct Email *e = m->emails[i];
1698  if (!e)
1699  break;
1700  struct ImapEmailData *edata = imap_edata_get(e);
1701  edata->deleted = e->deleted;
1702  edata->flagged = e->flagged;
1703  edata->old = e->old;
1704  edata->read = e->read;
1705  edata->replied = e->replied;
1706  e->changed = false;
1707  }
1708  m->changed = false;
1709 
1710  /* We must send an EXPUNGE command if we're not closing. */
1711  if (expunge && !close && (m->rights & MUTT_ACL_DELETE))
1712  {
1713  if (m->verbose)
1714  mutt_message(_("Expunging messages from server..."));
1715  /* Set expunge bit so we don't get spurious reopened messages */
1716  mdata->reopen |= IMAP_EXPUNGE_EXPECTED;
1717  if (imap_exec(adata, "EXPUNGE", IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1718  {
1719  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1720  imap_error(_("imap_sync_mailbox: EXPUNGE failed"), adata->buf);
1721  return -1;
1722  }
1723  mdata->reopen &= ~IMAP_EXPUNGE_EXPECTED;
1724  }
1725 
1726  if (expunge && close)
1727  {
1728  adata->closing = true;
1729  imap_exec(adata, "CLOSE", IMAP_CMD_QUEUE);
1730  adata->state = IMAP_AUTHENTICATED;
1731  }
1732 
1733  const bool c_message_cache_clean =
1734  cs_subset_bool(NeoMutt->sub, "message_cache_clean");
1735  if (c_message_cache_clean)
1736  imap_cache_clean(m);
1737 
1738  return check;
1739 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
Deleted messages.
Definition: mutt.h:97
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
#define mutt_error(...)
Definition: logging.h:88
Connection is authenticated.
Definition: private.h:109
int mutt_save_message_ctx(struct Mailbox *m_src, struct Email *e, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt, struct Mailbox *m_dst)
Save a message to a given mailbox.
Definition: commands.c:1103
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:381
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:399
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: adata.h:44
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: mdata.h:44
No transformation.
Definition: commands.h:41
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1819
Flagged messages.
Definition: mutt.h:98
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:64
static int sync_helper(struct Mailbox *m, AclFlags right, enum MessageType flag, const char *name)
Sync flag changes to the server.
Definition: imap.c:324
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
Messages that have been replied to.
Definition: mutt.h:91
Imap command executed or queued successfully.
Definition: private.h:84
bool flagged
Definition: edata.h:39
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
bool deleted
Definition: edata.h:38
bool read
Email is read.
Definition: email.h:51
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:340
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:48
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:59
struct Envelope * env
Envelope information.
Definition: email.h:90
Mailbox is selected.
Definition: private.h:110
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:1250
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Old messages.
Definition: mutt.h:90
bool closing
If true, we are waiting for CLOSE completion.
Definition: adata.h:43
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:665
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
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:927
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: private.h:67
Messages that have been read.
Definition: mutt.h:92
bool replied
Definition: edata.h:40
bool old
Definition: edata.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:1021
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
int imap_cache_clean(struct Mailbox *m)
Delete all the entries in the message cache.
Definition: message.c:1838
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1103
IMAP-specific Account data -.
Definition: adata.h:39
Move message to another mailbox, removing the original.
Definition: commands.h:52
bool flagged
Marked important?
Definition: email.h:43
IMAP-specific Mailbox data -.
Definition: mdata.h:38
char * buf
Definition: adata.h:59
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:111
bool replied
Email has been replied to.
Definition: email.h:54
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
bool read
Definition: edata.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:38
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:75
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
IMAP-specific Email data -.
Definition: edata.h:33
static int compare_uid(const void *a, const void *b)
Compare two Emails by UID - Implements sort_t.
Definition: imap.c:904
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:297
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close() ...
Definition: mxapi.h:75
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
An error occurred.
Definition: mxapi.h:77
+ 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 1235 of file imap.c.

1236 {
1237  struct Mailbox *m = mx_mbox_find2(path);
1238 
1239  const bool is_temp = !m;
1240  if (is_temp)
1241  {
1242  m = mx_path_resolve(path);
1243  if (!mx_mbox_ac_link(m))
1244  {
1245  mailbox_free(&m);
1246  return 0;
1247  }
1248  }
1249 
1250  int rc = imap_mailbox_status(m, queue);
1251 
1252  if (is_temp)
1253  {
1254  mx_ac_remove(m);
1255  mailbox_free(&m);
1256  }
1257 
1258  return rc;
1259 }
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1640
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
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:1270
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1668
bool mx_mbox_ac_link(struct Mailbox *m)
Link a Mailbox to an existing or new Account.
Definition: mx.c:267
int mx_ac_remove(struct Mailbox *m)
Remove a Mailbox from an Account and delete Account if empty.
Definition: mx.c:1772
+ 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 1270 of file imap.c.

1271 {
1272  struct ImapAccountData *adata = imap_adata_get(m);
1273  struct ImapMboxData *mdata = imap_mdata_get(m);
1274  if (!adata || !mdata)
1275  return -1;
1276  return imap_status(adata, mdata, queue);
1277 }
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1176
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:59
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
IMAP-specific Account data -.
Definition: adata.h:39
IMAP-specific Mailbox data -.
Definition: mdata.h:38
+ 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 1286 of file imap.c.

1287 {
1288  struct ImapAccountData *adata = NULL;
1289  struct ImapMboxData *mdata = NULL;
1290  char buf[2048];
1291  struct Buffer err;
1292 
1293  if (imap_adata_find(path, &adata, &mdata) < 0)
1294  return -1;
1295 
1296  if (subscribe)
1297  mutt_message(_("Subscribing to %s..."), mdata->name);
1298  else
1299  mutt_message(_("Unsubscribing from %s..."), mdata->name);
1300 
1301  snprintf(buf, sizeof(buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mdata->munge_name);
1302 
1303  if (imap_exec(adata, buf, IMAP_CMD_NO_FLAGS) != IMAP_EXEC_SUCCESS)
1304  {
1305  imap_mdata_free((void *) &mdata);
1306  return -1;
1307  }
1308 
1309  const bool c_imap_check_subscribed =
1310  cs_subset_bool(NeoMutt->sub, "imap_check_subscribed");
1311  if (c_imap_check_subscribed)
1312  {
1313  char mbox[1024];
1314  mutt_buffer_init(&err);
1315  err.dsize = 256;
1316  err.data = mutt_mem_malloc(err.dsize);
1317  size_t len = snprintf(mbox, sizeof(mbox), "%smailboxes ", subscribe ? "" : "un");
1318  imap_quote_string(mbox + len, sizeof(mbox) - len, path, true);
1319  if (mutt_parse_rc_line(mbox, &err))
1320  mutt_debug(LL_DEBUG1, "Error adding subscribed mailbox: %s\n", err.data);
1321  FREE(&err.data);
1322  }
1323 
1324  if (subscribe)
1325  mutt_message(_("Subscribed to %s"), mdata->name);
1326  else
1327  mutt_message(_("Unsubscribed from %s"), mdata->name);
1328  imap_mdata_free((void *) &mdata);
1329  return 0;
1330 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
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
Container for Accounts, Notifications.
Definition: neomutt.h:36
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:72
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:1250
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: mdata.h:40
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
IMAP-specific Account data -.
Definition: adata.h:39
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: mdata.h:38
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
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: mdata.h:41
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:840
+ 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 1343 of file imap.c.

1344 {
1345  struct ImapAccountData *adata = NULL;
1346  struct ImapMboxData *mdata = NULL;
1347  char tmp[2048];
1348  struct ImapList listresp = { 0 };
1349  char completion[1024];
1350  int clen;
1351  size_t matchlen = 0;
1352  int completions = 0;
1353  int rc;
1354 
1355  if (imap_adata_find(path, &adata, &mdata) < 0)
1356  {
1357  mutt_str_copy(buf, path, buflen);
1358  return complete_hosts(buf, buflen);
1359  }
1360 
1361  /* fire off command */
1362  const bool c_imap_list_subscribed =
1363  cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
1364  snprintf(tmp, sizeof(tmp), "%s \"\" \"%s%%\"",
1365  c_imap_list_subscribed ? "LSUB" : "LIST", mdata->real_name);
1366 
1367  imap_cmd_start(adata, tmp);
1368 
1369  /* and see what the results are */
1370  mutt_str_copy(completion, mdata->name, sizeof(completion));
1371  imap_mdata_free((void *) &mdata);
1372 
1373  adata->cmdresult = &listresp;
1374  do
1375  {
1376  listresp.name = NULL;
1377  rc = imap_cmd_step(adata);
1378 
1379  if ((rc == IMAP_RES_CONTINUE) && listresp.name)
1380  {
1381  /* if the folder isn't selectable, append delimiter to force browse
1382  * to enter it on second tab. */
1383  if (listresp.noselect)
1384  {
1385  clen = strlen(listresp.name);
1386  listresp.name[clen++] = listresp.delim;
1387  listresp.name[clen] = '\0';
1388  }
1389  /* copy in first word */
1390  if (!completions)
1391  {
1392  mutt_str_copy(completion, listresp.name, sizeof(completion));
1393  matchlen = strlen(completion);
1394  completions++;
1395  continue;
1396  }
1397 
1398  matchlen = longest_common_prefix(completion, listresp.name, 0, matchlen);
1399  completions++;
1400  }
1401  } while (rc == IMAP_RES_CONTINUE);
1402  adata->cmdresult = NULL;
1403 
1404  if (completions)
1405  {
1406  /* reformat output */
1407  imap_qualify_path(buf, buflen, &adata->conn->account, completion);
1408  mutt_pretty_mailbox(buf, buflen);
1409  return 0;
1410  }
1411 
1412  return -1;
1413 }
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:526
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1079
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
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:1065
char delim
Definition: private.h:151
Container for Accounts, Notifications.
Definition: neomutt.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:72
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:386
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: mdata.h:40
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
IMAP-specific Account data -.
Definition: adata.h:39
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:365
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
struct ImapList * cmdresult
Definition: adata.h:66
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:57
bool noselect
Definition: private.h:152
struct Connection * conn
Definition: adata.h:41
+ 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,
const 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 1423 of file imap.c.

1424 {
1425  char prompt[1024];
1426  int rc = -1;
1427  bool triedcreate = false;
1428  enum QuadOption err_continue = MUTT_NO;
1429 
1430  struct ImapAccountData *adata = imap_adata_get(m);
1431  struct ImapAccountData *dest_adata = NULL;
1432  struct ImapMboxData *dest_mdata = NULL;
1433 
1434  if (imap_adata_find(dest, &dest_adata, &dest_mdata) < 0)
1435  return -1;
1436 
1437  struct Buffer sync_cmd = mutt_buffer_make(0);
1438 
1439  /* check that the save-to folder is in the same account */
1440  if (!imap_account_match(&(adata->conn->account), &(dest_adata->conn->account)))
1441  {
1442  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1443  goto out;
1444  }
1445 
1446  for (int i = 0; i < m->msg_count; i++)
1447  {
1448  struct Email *e = m->emails[i];
1449  if (!e)
1450  break;
1451  if (e->active && e->changed && e->deleted && !e->purge)
1452  {
1453  rc = imap_sync_message_for_copy(m, e, &sync_cmd, &err_continue);
1454  if (rc < 0)
1455  {
1456  mutt_debug(LL_DEBUG1, "could not sync\n");
1457  goto out;
1458  }
1459  }
1460  }
1461 
1462  /* loop in case of TRYCREATE */
1463  do
1464  {
1465  rc = imap_exec_msgset(m, "UID COPY", dest_mdata->munge_name, MUTT_TRASH, false, false);
1466  if (rc == 0)
1467  {
1468  mutt_debug(LL_DEBUG1, "No messages to trash\n");
1469  rc = -1;
1470  goto out;
1471  }
1472  else if (rc < 0)
1473  {
1474  mutt_debug(LL_DEBUG1, "could not queue copy\n");
1475  goto out;
1476  }
1477  else if (m->verbose)
1478  {
1479  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1480  rc, dest_mdata->name);
1481  }
1482 
1483  /* let's get it on */
1484  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1485  if (rc == IMAP_EXEC_ERROR)
1486  {
1487  if (triedcreate)
1488  {
1489  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", dest_mdata->name);
1490  break;
1491  }
1492  /* bail out if command failed for reasons other than nonexistent target */
1493  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1494  break;
1495  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1496  snprintf(prompt, sizeof(prompt), _("Create %s?"), dest_mdata->name);
1497  const bool c_confirm_create =
1498  cs_subset_bool(NeoMutt->sub, "confirm_create");
1499  if (c_confirm_create && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1500  {
1501  mutt_clear_error();
1502  goto out;
1503  }
1504  if (imap_create_mailbox(adata, dest_mdata->name) < 0)
1505  break;
1506  triedcreate = true;
1507  }
1508  } while (rc == IMAP_EXEC_ERROR);
1509 
1510  if (rc != IMAP_EXEC_SUCCESS)
1511  {
1512  imap_error("imap_fast_trash", adata->buf);
1513  goto out;
1514  }
1515 
1516  rc = IMAP_EXEC_SUCCESS;
1517 
1518 out:
1519  mutt_buffer_dealloc(&sync_cmd);
1520  imap_mdata_free((void *) &dest_mdata);
1521 
1522  return ((rc == IMAP_EXEC_SUCCESS) ? 0 : -1);
1523 }
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:215
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
The envelope/body of an email.
Definition: email.h:37
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
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:1049
Container for Accounts, Notifications.
Definition: neomutt.h:36
Imap command executed or queued successfully.
Definition: private.h:84
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
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:112
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:1250
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:1004
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:665
bool active
Message is not to be removed.
Definition: email.h:59
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:927
char * name
Mailbox name.
Definition: mdata.h:40
bool verbose
Display status messages?
Definition: mailbox.h:118
bool purge
Skip trash folder when deleting.
Definition: email.h:46
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
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:448
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
Imap command failure.
Definition: private.h:85
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:775
Log at debug level 1.
Definition: logging.h:40
IMAP-specific Mailbox data -.
Definition: mdata.h:38
char * buf
Definition: adata.h:59
bool deleted
Email is deleted.
Definition: email.h:45
#define mutt_message(...)
Definition: logging.h:87
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
char * munge_name
Munged version of the mailbox name.
Definition: mdata.h:41
Trashed messages.
Definition: mutt.h:104
Log at debug level 3.
Definition: logging.h:42
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Connection * conn
Definition: adata.h:41
+ 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 656 of file imap.c.

657 {
658  struct ImapMboxData *mdata = imap_mdata_get(m);
659  struct ImapEmailData *edata = imap_edata_get(e);
660 
661  if (!mdata || !edata)
662  return;
663 
664  imap_msn_remove(&mdata->msn, edata->msn - 1);
665  edata->msn = 0;
666 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:64
unsigned int msn
Message Sequence Number.
Definition: edata.h:45
void imap_msn_remove(struct MSN *msn, size_t idx)
Remove an entry from the cache.
Definition: msn.c:112
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:59
void * mdata
Driver specific data.
Definition: mailbox.h:136
IMAP-specific Mailbox data -.
Definition: mdata.h:38
void * edata
Driver-specific data.
Definition: email.h:111
IMAP-specific Email data -.
Definition: edata.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 182 of file browse.c.

183 {
184  struct ImapAccountData *adata = NULL;
185  struct ImapList list = { 0 };
186  struct ConnAccount cac = { { 0 } };
187  char buf[PATH_MAX + 16];
188  char mbox[PATH_MAX];
189  char munged_mbox[PATH_MAX];
190  const char *list_cmd = NULL;
191  int len;
192  int n;
193  char ctmp;
194  bool showparents = false;
195 
196  if (imap_parse_path(path, &cac, buf, sizeof(buf)))
197  {
198  mutt_error(_("%s is an invalid IMAP path"), path);
199  return -1;
200  }
201 
202  const bool c_imap_check_subscribed =
203  cs_subset_bool(NeoMutt->sub, "imap_check_subscribed");
204  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed", false, NULL);
205 
206  // Pick first mailbox connected to the same server
207  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
209  struct MailboxNode *np = NULL;
210  STAILQ_FOREACH(np, &ml, entries)
211  {
212  adata = imap_adata_get(np->mailbox);
213  // Pick first mailbox connected on the same server
214  if (imap_account_match(&adata->conn->account, &cac))
215  break;
216  adata = NULL;
217  }
219  if (!adata)
220  goto fail;
221 
222  const bool c_imap_list_subscribed =
223  cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
224  if (c_imap_list_subscribed)
225  {
226  /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
227  * The newer LIST extensions are designed for this. */
229  list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
230  else
231  list_cmd = "LSUB";
232  }
233  else
234  {
235  list_cmd = "LIST";
236  }
237 
238  mutt_message(_("Getting folder list..."));
239 
240  /* skip check for parents when at the root */
241  if (buf[0] == '\0')
242  {
243  mbox[0] = '\0';
244  n = 0;
245  }
246  else
247  {
248  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
249  n = mutt_str_len(mbox);
250  }
251 
252  if (n)
253  {
254  int rc;
255  mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
256 
257  /* if our target exists and has inferiors, enter it if we
258  * aren't already going to */
259  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
260  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
262  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
263  imap_cmd_start(adata, buf);
264  adata->cmdresult = &list;
265  do
266  {
267  list.name = 0;
268  rc = imap_cmd_step(adata);
269  if ((rc == IMAP_RES_CONTINUE) && list.name)
270  {
271  if (!list.noinferiors && list.name[0] &&
272  (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
273  {
274  mbox[n++] = list.delim;
275  mbox[n] = '\0';
276  }
277  }
278  } while (rc == IMAP_RES_CONTINUE);
279  adata->cmdresult = NULL;
280 
281  /* if we're descending a folder, mark it as current in browser_state */
282  if (mbox[n - 1] == list.delim)
283  {
284  showparents = true;
285  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
286  state->folder = mutt_str_dup(buf);
287  n--;
288  }
289 
290  /* Find superiors to list
291  * Note: UW-IMAP servers return folder + delimiter when asked to list
292  * folder + delimiter. Cyrus servers don't. So we ask for folder,
293  * and tack on delimiter ourselves.
294  * Further note: UW-IMAP servers return nothing when asked for
295  * NAMESPACES without delimiters at the end. Argh! */
296  for (n--; n >= 0 && mbox[n] != list.delim; n--)
297  ; // do nothing
298 
299  if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
300  {
301  /* forget the check, it is too delicate (see above). Have we ever
302  * had the parent not exist? */
303  ctmp = mbox[n];
304  mbox[n] = '\0';
305 
306  if (showparents)
307  {
308  mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
309  add_folder(list.delim, mbox, true, false, state, true);
310  }
311 
312  /* if our target isn't a folder, we are in our superior */
313  if (!state->folder)
314  {
315  /* store folder with delimiter */
316  mbox[n++] = ctmp;
317  ctmp = mbox[n];
318  mbox[n] = '\0';
319  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
320  state->folder = mutt_str_dup(buf);
321  }
322  mbox[n] = ctmp;
323  }
324  /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
325  else
326  {
327  char relpath[2];
328  /* folder may be "/" */
329  snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
330  if (showparents)
331  add_folder(adata->delim, relpath, true, false, state, true);
332  if (!state->folder)
333  {
334  imap_qualify_path(buf, sizeof(buf), &cac, relpath);
335  state->folder = mutt_str_dup(buf);
336  }
337  }
338  }
339 
340  /* no namespace, no folder: set folder to host only */
341  if (!state->folder)
342  {
343  imap_qualify_path(buf, sizeof(buf), &cac, NULL);
344  state->folder = mutt_str_dup(buf);
345  }
346 
347  mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
348  snprintf(buf, sizeof(buf), "%s%%", mbox);
349  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
350  mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
351  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
353  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
354  if (browse_add_list_result(adata, buf, state, false))
355  goto fail;
356 
357  if (ARRAY_EMPTY(&state->entry))
358  {
359  // L10N: (%s) is the name / path of the folder we were trying to browse
360  mutt_error(_("No such folder: %s"), path);
361  goto fail;
362  }
363 
365 
366  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
367  c_imap_check_subscribed, NULL);
368  return 0;
369 
370 fail:
371  cs_subset_str_native_set(NeoMutt->sub, "imap_check_subscribed",
372  c_imap_check_subscribed, NULL);
373  return -1;
374 }
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1079
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:141
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:483
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:914
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:164
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:93
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:1049
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1065
char delim
Definition: private.h:151
Container for Accounts, Notifications.
Definition: neomutt.h:36
char * folder
Definition: browser.h:96
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
char delim
Definition: adata.h:75
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:554
#define PATH_MAX
Definition: mutt.h:40
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
ImapCapFlags capabilities
Definition: adata.h:55
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition: private.h:139
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
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:664
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:687
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:142
#define mutt_message(...)
Definition: logging.h:87
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
struct ImapList * cmdresult
Definition: adata.h:66
List of Mailboxes.
Definition: mailbox.h:156
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#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:62
&#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: adata.h:62
struct Connection * conn
Definition: adata.h:41
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:158
+ 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 384 of file browse.c.

385 {
386  struct ImapAccountData *adata = NULL;
387  struct ImapMboxData *mdata = NULL;
388  char name[1024];
389 
390  if (imap_adata_find(path, &adata, &mdata) < 0)
391  {
392  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
393  goto err;
394  }
395 
396  /* append a delimiter if necessary */
397  const size_t n = mutt_str_copy(name, mdata->real_name, sizeof(name));
398  if (n && (n < sizeof(name) - 1) && (name[n - 1] != adata->delim))
399  {
400  name[n] = adata->delim;
401  name[n + 1] = '\0';
402  }
403 
404  if (mutt_get_field(_("Create mailbox: "), name, sizeof(name), MUTT_FILE,
405  false, NULL, NULL) < 0)
406  {
407  goto err;
408  }
409 
410  if (mutt_str_len(name) == 0)
411  {
412  mutt_error(_("Mailbox must have a name"));
413  goto err;
414  }
415 
416  if (imap_create_mailbox(adata, name) < 0)
417  goto err;
418 
419  imap_mdata_free((void *) &mdata);
420  mutt_message(_("Mailbox created"));
421  mutt_sleep(0);
422  return 0;
423 
424 err:
425  imap_mdata_free((void *) &mdata);
426  return -1;
427 }
#define mutt_error(...)
Definition: logging.h:88
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
#define _(a)
Definition: message.h:28
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
char delim
Definition: adata.h:75
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: mdata.h:40
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:448
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
IMAP-specific Account data -.
Definition: adata.h:39
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
#define mutt_message(...)
Definition: logging.h:87
+ 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 437 of file browse.c.

438 {
439  struct ImapAccountData *adata = NULL;
440  struct ImapMboxData *mdata = NULL;
441  char buf[PATH_MAX];
442  char newname[PATH_MAX];
443 
444  if (imap_adata_find(path, &adata, &mdata) < 0)
445  {
446  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
447  return -1;
448  }
449 
450  if (mdata->real_name[0] == '\0')
451  {
452  mutt_error(_("Can't rename root folder"));
453  goto err;
454  }
455 
456  snprintf(buf, sizeof(buf), _("Rename mailbox %s to: "), mdata->name);
457  mutt_str_copy(newname, mdata->name, sizeof(newname));
458 
459  if (mutt_get_field(buf, newname, sizeof(newname), MUTT_FILE, false, NULL, NULL) < 0)
460  goto err;
461 
462  if (mutt_str_len(newname) == 0)
463  {
464  mutt_error(_("Mailbox must have a name"));
465  goto err;
466  }
467 
468  imap_fix_path(adata->delim, newname, buf, sizeof(buf));
469 
470  if (imap_rename_mailbox(adata, mdata->name, buf) < 0)
471  {
472  mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
473  goto err;
474  }
475 
476  mutt_message(_("Mailbox renamed"));
477  mutt_sleep(0);
478  return 0;
479 
480 err:
481  imap_mdata_free((void *) &mdata);
482  return -1;
483 }
#define mutt_error(...)
Definition: logging.h:88
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition: imap.c:489
#define _(a)
Definition: message.h:28
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
char delim
Definition: adata.h:75
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: mdata.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:775
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:687
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
char * buf
Definition: adata.h:59
#define mutt_message(...)
Definition: logging.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_copy_messages()

int imap_copy_messages ( struct Mailbox m,
struct EmailList *  el,
const char *  dest,
enum MessageSaveOpt  save_opt 
)

Server COPY messages to another folder.

Parameters
mMailbox
elList of Emails to copy
destDestination folder
save_optCopy or move, e.g. SAVE_MOVE
Return values
-1Error
0Success
1Non-fatal error - try fetch/append

Definition at line 1643 of file message.c.

1645 {
1646  if (!m || !el || !dest)
1647  return -1;
1648 
1649  struct Buffer cmd, sync_cmd;
1650  char buf[PATH_MAX];
1651  char mbox[PATH_MAX];
1652  char mmbox[PATH_MAX];
1653  char prompt[PATH_MAX + 64];
1654  int rc;
1655  struct ConnAccount cac = { { 0 } };
1656  enum QuadOption err_continue = MUTT_NO;
1657  int triedcreate = 0;
1658  struct EmailNode *en = STAILQ_FIRST(el);
1659  bool single = !STAILQ_NEXT(en, entries);
1660  struct ImapAccountData *adata = imap_adata_get(m);
1661 
1662  if (single && en->email->attach_del)
1663  {
1664  mutt_debug(LL_DEBUG3, "#1 Message contains attachments to be deleted\n");
1665  return 1;
1666  }
1667 
1668  if (imap_parse_path(dest, &cac, buf, sizeof(buf)))
1669  {
1670  mutt_debug(LL_DEBUG1, "bad destination %s\n", dest);
1671  return -1;
1672  }
1673 
1674  /* check that the save-to folder is in the same account */
1675  if (!imap_account_match(&adata->conn->account, &cac))
1676  {
1677  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1678  return 1;
1679  }
1680 
1681  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
1682  if (*mbox == '\0')
1683  mutt_str_copy(mbox, "INBOX", sizeof(mbox));
1684  imap_munge_mbox_name(adata->unicode, mmbox, sizeof(mmbox), mbox);
1685 
1686  /* loop in case of TRYCREATE */
1687  do
1688  {
1689  mutt_buffer_init(&sync_cmd);
1690  mutt_buffer_init(&cmd);
1691 
1692  if (!single) /* copy tagged messages */
1693  {
1694  /* if any messages have attachments to delete, fall through to FETCH
1695  * and APPEND. TODO: Copy what we can with COPY, fall through for the
1696  * remainder. */
1697  STAILQ_FOREACH(en, el, entries)
1698  {
1699  if (en->email->attach_del)
1700  {
1702  "#2 Message contains attachments to be deleted\n");
1703  return 1;
1704  }
1705 
1706  if (en->email->active && en->email->changed)
1707  {
1708  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1709  if (rc < 0)
1710  {
1711  mutt_debug(LL_DEBUG1, "#1 could not sync\n");
1712  goto out;
1713  }
1714  }
1715  }
1716 
1717  rc = imap_exec_msgset(m, "UID COPY", mmbox, MUTT_TAG, false, false);
1718  if (rc == 0)
1719  {
1720  mutt_debug(LL_DEBUG1, "No messages tagged\n");
1721  rc = -1;
1722  goto out;
1723  }
1724  else if (rc < 0)
1725  {
1726  mutt_debug(LL_DEBUG1, "#1 could not queue copy\n");
1727  goto out;
1728  }
1729  else
1730  {
1731  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1732  rc, mbox);
1733  }
1734  }
1735  else
1736  {
1737  mutt_message(_("Copying message %d to %s..."), en->email->index + 1, mbox);
1738  mutt_buffer_add_printf(&cmd, "UID COPY %u %s", imap_edata_get(en->email)->uid, mmbox);
1739 
1740  if (en->email->active && en->email->changed)
1741  {
1742  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1743  if (rc < 0)
1744  {
1745  mutt_debug(LL_DEBUG1, "#2 could not sync\n");
1746  goto out;
1747  }
1748  }
1749  rc = imap_exec(adata, cmd.data, IMAP_CMD_QUEUE);
1750  if (rc != IMAP_EXEC_SUCCESS)
1751  {
1752  mutt_debug(LL_DEBUG1, "#2 could not queue copy\n");
1753  goto out;
1754  }
1755  }
1756 
1757  /* let's get it on */
1758  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1759  if (rc == IMAP_EXEC_ERROR)
1760  {
1761  if (triedcreate)
1762  {
1763  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", mbox);
1764  break;
1765  }
1766  /* bail out if command failed for reasons other than nonexistent target */
1767  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1768  break;
1769  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1770  snprintf(prompt, sizeof(prompt), _("Create %s?"), mbox);
1771  const bool c_confirm_create =
1772  cs_subset_bool(NeoMutt->sub, "confirm_create");
1773  if (c_confirm_create && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1774  {
1775  mutt_clear_error();
1776  goto out;
1777  }
1778  if (imap_create_mailbox(adata, mbox) < 0)
1779  break;
1780  triedcreate = 1;
1781  }
1782  } while (rc == IMAP_EXEC_ERROR);
1783 
1784  if (rc != 0)
1785  {
1786  imap_error("imap_copy_messages", adata->buf);
1787  goto out;
1788  }
1789 
1790  /* cleanup */
1791  if (save_opt == SAVE_MOVE)
1792  {
1793  const bool c_delete_untag = cs_subset_bool(NeoMutt->sub, "delete_untag");
1794  STAILQ_FOREACH(en, el, entries)
1795  {
1796  mutt_set_flag(m, en->email, MUTT_DELETE, true);
1797  mutt_set_flag(m, en->email, MUTT_PURGE, true);
1798  if (c_delete_untag)
1799  mutt_set_flag(m, en->email, MUTT_TAG, false);
1800  }
1801  }
1802 
1803  rc = 0;
1804 
1805 out:
1806  FREE(&cmd.data);
1807  FREE(&sync_cmd.data);
1808 
1809  return (rc < 0) ? -1 : rc;
1810 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:483
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:914
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
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:64
Messages to be purged (bypass trash)
Definition: mutt.h:96
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1049
Container for Accounts, Notifications.
Definition: neomutt.h:36
Imap command executed or queued successfully.
Definition: private.h:84
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
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:112
char delim
Definition: adata.h:75
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:1250
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:1004
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:665
bool active
Message is not to be removed.
Definition: email.h:59
unsigned int uid
32-bit Message UID
Definition: edata.h:44
Messages to be deleted.
Definition: mutt.h:94
#define PATH_MAX
Definition: mutt.h:40
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Tagged messages.
Definition: mutt.h:99
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:927
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:352
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:448
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Login details for a remote server.
Definition: connaccount.h:51
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
Imap command failure.
Definition: private.h:85
IMAP-specific Account data -.
Definition: adata.h:39
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:775
Move message to another mailbox, removing the original.
Definition: commands.h:52
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:687
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:749
char * buf
Definition: adata.h:59
struct Email * email
Email in the list.
Definition: email.h:131
int index
The absolute (unsorted) message number.
Definition: email.h:86
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
List of Emails.
Definition: email.h:129
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#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:350
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: adata.h:62
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Connection * conn
Definition: adata.h:41
+ 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 564 of file imap.c.

565 {
566  struct Account *np = NULL;
567  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
568  {
569  if (np->type != MUTT_IMAP)
570  continue;
571 
572  struct ImapAccountData *adata = np->adata;
573  if (!adata)
574  continue;
575 
576  struct Connection *conn = adata->conn;
577  if (!conn || (conn->fd < 0))
578  continue;
579 
580  mutt_message(_("Closing connection to %s..."), conn->account.host);
581  imap_logout(np->adata);
583  }
584 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
A group of associated Mailboxes.
Definition: account.h:36
static void imap_logout(struct ImapAccountData *adata)
Gracefully log out of server.
Definition: imap.c:536
#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:112
int fd
Socket file descriptor.
Definition: connection.h:44
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: adata.h:39
#define mutt_message(...)
Definition: logging.h:87
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Connection * conn
Definition: adata.h:41
+ 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 2442 of file imap.c.

2443 {
2445  return imap_path_canon(buf->data, PATH_MAX);
2446 }
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon() -.
Definition: imap.c:2416
#define PATH_MAX
Definition: mutt.h:40
char * data
Pointer to data.
Definition: buffer.h:35
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 483 of file util.c.

484 {
485  static unsigned short ImapPort = 0;
486  static unsigned short ImapsPort = 0;
487 
488  if (ImapPort == 0)
489  {
490  struct servent *service = getservbyname("imap", "tcp");
491  if (service)
492  ImapPort = ntohs(service->s_port);
493  else
494  ImapPort = IMAP_PORT;
495  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
496  }
497 
498  if (ImapsPort == 0)
499  {
500  struct servent *service = getservbyname("imaps", "tcp");
501  if (service)
502  ImapsPort = ntohs(service->s_port);
503  else
504  ImapsPort = IMAP_SSL_PORT;
505  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
506  }
507 
508  /* Defaults */
509  cac->port = ImapPort;
510  cac->type = MUTT_ACCT_TYPE_IMAP;
511  cac->service = "imap";
512  cac->get_field = imap_get_field;
513 
514  struct Url *url = url_parse(path);
515  if (!url)
516  return -1;
517 
518  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
519  {
520  url_free(&url);
521  return -1;
522  }
523 
524  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
525  {
526  url_free(&url);
527  return -1;
528  }
529 
530  if (url->scheme == U_IMAPS)
531  cac->flags |= MUTT_ACCT_SSL;
532 
533  mutt_str_copy(mailbox, url->path, mailboxlen);
534 
535  url_free(&url);
536 
537  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
538  cac->port = ImapsPort;
539 
540  return 0;
541 }
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:68
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:45
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
Url is imaps://.
Definition: url.h:40
Url is imap://.
Definition: url.h:39
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:204
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
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Imap Account.
Definition: mutt_account.h:37
char * path
Path.
Definition: url.h:75
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:749
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 590 of file util.c.

591 {
592  struct ConnAccount cac_target = { { 0 } };
593  struct ConnAccount cac_home = { { 0 } };
594  struct Url url = { 0 };
595  const char *delim = NULL;
596  int tlen;
597  int hlen = 0;
598  bool home_match = false;
599  char target_mailbox[1024];
600  char home_mailbox[1024];
601 
602  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
603  return;
604 
605  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
606  goto fallback;
607 
608  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
609  goto fallback;
610 
611  tlen = mutt_str_len(target_mailbox);
612  hlen = mutt_str_len(home_mailbox);
613 
614  /* check whether we can do '+' substitution */
615  if (tlen && imap_account_match(&cac_home, &cac_target) &&
616  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
617  {
618  const char *const c_imap_delim_chars =
619  cs_subset_string(NeoMutt->sub, "imap_delim_chars");
620  if (hlen == 0)
621  home_match = true;
622  else if (c_imap_delim_chars)
623  {
624  for (delim = c_imap_delim_chars; *delim != '\0'; delim++)
625  if (target_mailbox[hlen] == *delim)
626  home_match = true;
627  }
628  }
629 
630  /* do the '+' substitution */
631  if (home_match)
632  {
633  *path++ = '+';
634  /* copy remaining path, skipping delimiter */
635  if (hlen == 0)
636  hlen = -1;
637  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
638  path[tlen - hlen - 1] = '\0';
639  return;
640  }
641 
642 fallback:
643  mutt_account_tourl(&cac_target, &url);
644  url.path = target_mailbox;
645  url_tostring(&url, path, pathlen, U_NO_FLAGS);
646 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
#define U_NO_FLAGS
Definition: url.h:49
Container for Accounts, Notifications.
Definition: neomutt.h:36
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:483
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1049
int url_tostring(struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:418
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
Login details for a remote server.
Definition: connaccount.h:51
char * path
Path.
Definition: url.h:75
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
&#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 554 of file util.c.

555 {
556  char *b1 = NULL;
557  char *b2 = NULL;
558  int rc;
559 
560  if (!mx1 || (*mx1 == '\0'))
561  mx1 = "INBOX";
562  if (!mx2 || (*mx2 == '\0'))
563  mx2 = "INBOX";
564  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
565  {
566  return 0;
567  }
568 
569  b1 = mutt_mem_malloc(strlen(mx1) + 1);
570  b2 = mutt_mem_malloc(strlen(mx2) + 1);
571 
572  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
573  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
574 
575  rc = mutt_str_cmp(b1, b2);
576  FREE(&b1);
577  FREE(&b2);
578 
579  return rc;
580 }
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:687
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
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 973 of file util.c.

974 {
975  struct sigaction oldalrm;
976  struct sigaction act;
977  sigset_t oldmask;
978  int rc;
979 
980  const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
981  cs_subset_str_native_set(NeoMutt->sub, "imap_passive", true, NULL);
982  OptKeepQuiet = true;
983 
984  sigprocmask(SIG_SETMASK, NULL, &oldmask);
985 
986  sigemptyset(&act.sa_mask);
987  act.sa_handler = mutt_sig_empty_handler;
988 #ifdef SA_INTERRUPT
989  act.sa_flags = SA_INTERRUPT;
990 #else
991  act.sa_flags = 0;
992 #endif
993 
994  sigaction(SIGALRM, &act, &oldalrm);
995 
996  const short c_imap_keepalive =
997  cs_subset_number(NeoMutt->sub, "imap_keepalive");
998  alarm(c_imap_keepalive);
999  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1000  {
1001  alarm(0); /* cancel a possibly pending alarm */
1002  imap_keepalive();
1003  alarm(c_imap_keepalive);
1004  }
1005 
1006  alarm(0); /* cancel a possibly pending alarm */
1007 
1008  sigaction(SIGALRM, &oldalrm, NULL);
1009  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1010 
1011  OptKeepQuiet = false;
1012  cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1013 
1014  return rc;
1015 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:948
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:38
+ 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 948 of file util.c.

949 {
950  time_t now = mutt_date_epoch();
951  struct Account *np = NULL;
952  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
953  {
954  if (np->type != MUTT_IMAP)
955  continue;
956 
957  struct ImapAccountData *adata = np->adata;
958  if (!adata || !adata->mailbox)
959  continue;
960 
961  const short c_imap_keepalive =
962  cs_subset_number(NeoMutt->sub, "imap_keepalive");
963  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + c_imap_keepalive)))
964  imap_check_mailbox(adata->mailbox, true);
965  }
966 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
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: adata.h:44
A group of associated Mailboxes.
Definition: account.h:36
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
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: adata.h:58
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1103
IMAP-specific Account data -.
Definition: adata.h:39
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
&#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 161 of file util.c.

162 {
163  struct ImapAccountData *adata = NULL;
164  struct ImapMboxData *mdata = NULL;
165  char mbox[1024];
166 
167  if (imap_adata_find(path, &adata, &mdata) < 0)
168  {
169  mutt_str_copy(buf, path, buflen);
170  return;
171  }
172 
173  /* Gets the parent mbox in mbox */
174  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
175 
176  /* Returns a fully qualified IMAP url */
177  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
178  imap_mdata_free((void *) &mdata);
179 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder&#39;s parent.
Definition: util.c:120
char delim
Definition: adata.h:75
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: mdata.h:40
IMAP-specific Account data -.
Definition: adata.h:39
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:749
IMAP-specific Mailbox data -.
Definition: mdata.h:38
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
struct Connection * conn
Definition: adata.h:41
+ 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 188 of file util.c.

189 {
190  struct ImapAccountData *adata = NULL;
191  struct ImapMboxData *mdata = NULL;
192 
193  if (imap_adata_find(path, &adata, &mdata) < 0)
194  return;
195 
196  /* Returns a fully qualified IMAP url */
197  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
198  imap_mdata_free((void *) &mdata);
199 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
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: mdata.c:40
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
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: mdata.h:40
IMAP-specific Account data -.
Definition: adata.h:39
IMAP-specific Mailbox data -.
Definition: mdata.h:38
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
struct Connection * conn
Definition: adata.h:41
+ 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 229 of file search.c.

230 {
231  for (int i = 0; i < m->msg_count; i++)
232  {
233  struct Email *e = m->emails[i];
234  if (!e)
235  break;
236  e->matched = false;
237  }
238 
239  if (check_pattern_list(pat) == 0)
240  return true;
241 
242  struct Buffer buf;
243  mutt_buffer_init(&buf);
244  mutt_buffer_addstr(&buf, "UID SEARCH ");
245 
246  struct ImapAccountData *adata = imap_adata_get(m);
247  const bool ok = compile_search(adata, SLIST_FIRST(pat), &buf) &&
249 
250  FREE(&buf.data);
251  return ok;
252 }
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:209
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:1250
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:83
#define SLIST_FIRST(head)
Definition: queue.h:229
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
IMAP-specific Account data -.
Definition: adata.h:39
char * buf
Definition: adata.h:59
#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: