NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference
#include "config.h"
#include <stddef.h>
#include <stdbool.h>
#include <sys/types.h>
#include "core/lib.h"
#include "mx.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, 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

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

Detailed Description

IMAP network mailbox

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

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

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

Definition in file lib.h.

Function Documentation

◆ imap_init()

void imap_init ( void  )

Setup feature commands.

Definition at line 82 of file imap.c.

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

◆ imap_access()

int imap_access ( const char *  path)

Check permissions on an IMAP mailbox with a new connection.

Parameters
pathMailbox path
Return values
0Success
<0Failure

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

Definition at line 473 of file imap.c.

474 {
475  if (imap_path_status(path, false) >= 0)
476  return 0;
477  return -1;
478 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

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

◆ imap_delete_mailbox()

int imap_delete_mailbox ( struct Mailbox m,
char *  path 
)

Delete a mailbox.

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

Definition at line 515 of file imap.c.

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

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

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

◆ imap_path_status()

int imap_path_status ( const char *  path,
bool  queue 
)

Refresh the number of total and new messages.

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

Definition at line 1222 of file imap.c.

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

◆ imap_mailbox_status()

int imap_mailbox_status ( struct Mailbox m,
bool  queue 
)

Refresh the number of total and new messages.

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

Definition at line 1256 of file imap.c.

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

◆ imap_subscribe()

int imap_subscribe ( char *  path,
bool  subscribe 
)

Subscribe to a mailbox.

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

Definition at line 1272 of file imap.c.

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

◆ imap_complete()

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

Try to complete an IMAP folder path.

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

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

Definition at line 1327 of file imap.c.

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

◆ imap_fast_trash()

int imap_fast_trash ( struct Mailbox m,
char *  dest 
)

Use server COPY command to copy deleted messages to trash.

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

Definition at line 1405 of file imap.c.

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

◆ imap_path_probe()

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

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

Definition at line 2372 of file imap.c.

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

◆ imap_path_canon()

int imap_path_canon ( char *  buf,
size_t  buflen 
)

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

Definition at line 2386 of file imap.c.

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

◆ imap_notify_delete_email()

void imap_notify_delete_email ( struct Mailbox m,
struct Email e 
)

Inform IMAP that an Email has been deleted.

Parameters
mMailbox
eEmail

Definition at line 651 of file imap.c.

652 {
653  struct ImapMboxData *mdata = imap_mdata_get(m);
654  struct ImapEmailData *edata = imap_edata_get(e);
655 
656  if (!mdata || !edata)
657  return;
658 
659  imap_msn_remove(&mdata->msn, edata->msn - 1);
660  edata->msn = 0;
661 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_browse()

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

IMAP hook into the folder browser.

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

Fill out browser_state, given a current folder to browse

Definition at line 179 of file browse.c.

180 {
181  struct ImapAccountData *adata = NULL;
182  struct ImapList list = { 0 };
183  struct ConnAccount cac = { { 0 } };
184  char buf[PATH_MAX + 16];
185  char mbox[PATH_MAX];
186  char munged_mbox[PATH_MAX];
187  const char *list_cmd = NULL;
188  int len;
189  int n;
190  char ctmp;
191  bool showparents = false;
192  bool save_lsub;
193 
194  if (imap_parse_path(path, &cac, buf, sizeof(buf)))
195  {
196  mutt_error(_("%s is an invalid IMAP path"), path);
197  return -1;
198  }
199 
200  save_lsub = C_ImapCheckSubscribed;
201  C_ImapCheckSubscribed = false;
202 
203  // Pick first mailbox connected to the same server
204  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
206  struct MailboxNode *np = NULL;
207  STAILQ_FOREACH(np, &ml, entries)
208  {
209  adata = imap_adata_get(np->mailbox);
210  // Pick first mailbox connected on the same server
211  if (imap_account_match(&adata->conn->account, &cac))
212  break;
213  adata = NULL;
214  }
216  if (!adata)
217  goto fail;
218 
220  {
221  /* RFC3348 section 3 states LSUB is unreliable for hierarchy information.
222  * The newer LIST extensions are designed for this. */
224  list_cmd = "LIST (SUBSCRIBED RECURSIVEMATCH)";
225  else
226  list_cmd = "LSUB";
227  }
228  else
229  {
230  list_cmd = "LIST";
231  }
232 
233  mutt_message(_("Getting folder list..."));
234 
235  /* skip check for parents when at the root */
236  if (buf[0] == '\0')
237  {
238  mbox[0] = '\0';
239  n = 0;
240  }
241  else
242  {
243  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
244  n = mutt_str_len(mbox);
245  }
246 
247  if (n)
248  {
249  int rc;
250  mutt_debug(LL_DEBUG3, "mbox: %s\n", mbox);
251 
252  /* if our target exists and has inferiors, enter it if we
253  * aren't already going to */
254  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), mbox);
255  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
257  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
258  imap_cmd_start(adata, buf);
259  adata->cmdresult = &list;
260  do
261  {
262  list.name = 0;
263  rc = imap_cmd_step(adata);
264  if ((rc == IMAP_RES_CONTINUE) && list.name)
265  {
266  if (!list.noinferiors && list.name[0] &&
267  (imap_mxcmp(list.name, mbox) == 0) && (n < sizeof(mbox) - 1))
268  {
269  mbox[n++] = list.delim;
270  mbox[n] = '\0';
271  }
272  }
273  } while (rc == IMAP_RES_CONTINUE);
274  adata->cmdresult = NULL;
275 
276  /* if we're descending a folder, mark it as current in browser_state */
277  if (mbox[n - 1] == list.delim)
278  {
279  showparents = true;
280  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
281  state->folder = mutt_str_dup(buf);
282  n--;
283  }
284 
285  /* Find superiors to list
286  * Note: UW-IMAP servers return folder + delimiter when asked to list
287  * folder + delimiter. Cyrus servers don't. So we ask for folder,
288  * and tack on delimiter ourselves.
289  * Further note: UW-IMAP servers return nothing when asked for
290  * NAMESPACES without delimiters at the end. Argh! */
291  for (n--; n >= 0 && mbox[n] != list.delim; n--)
292  ; // do nothing
293 
294  if (n > 0) /* "aaaa/bbbb/" -> "aaaa" */
295  {
296  /* forget the check, it is too delicate (see above). Have we ever
297  * had the parent not exist? */
298  ctmp = mbox[n];
299  mbox[n] = '\0';
300 
301  if (showparents)
302  {
303  mutt_debug(LL_DEBUG3, "adding parent %s\n", mbox);
304  add_folder(list.delim, mbox, true, false, state, true);
305  }
306 
307  /* if our target isn't a folder, we are in our superior */
308  if (!state->folder)
309  {
310  /* store folder with delimiter */
311  mbox[n++] = ctmp;
312  ctmp = mbox[n];
313  mbox[n] = '\0';
314  imap_qualify_path(buf, sizeof(buf), &cac, mbox);
315  state->folder = mutt_str_dup(buf);
316  }
317  mbox[n] = ctmp;
318  }
319  /* "/bbbb/" -> add "/", "aaaa/" -> add "" */
320  else
321  {
322  char relpath[2];
323  /* folder may be "/" */
324  snprintf(relpath, sizeof(relpath), "%c", (n < 0) ? '\0' : adata->delim);
325  if (showparents)
326  add_folder(adata->delim, relpath, true, false, state, true);
327  if (!state->folder)
328  {
329  imap_qualify_path(buf, sizeof(buf), &cac, relpath);
330  state->folder = mutt_str_dup(buf);
331  }
332  }
333  }
334 
335  /* no namespace, no folder: set folder to host only */
336  if (!state->folder)
337  {
338  imap_qualify_path(buf, sizeof(buf), &cac, NULL);
339  state->folder = mutt_str_dup(buf);
340  }
341 
342  mutt_debug(LL_DEBUG3, "Quoting mailbox scan: %s -> ", mbox);
343  snprintf(buf, sizeof(buf), "%s%%", mbox);
344  imap_munge_mbox_name(adata->unicode, munged_mbox, sizeof(munged_mbox), buf);
345  mutt_debug(LL_DEBUG3, "%s\n", munged_mbox);
346  len = snprintf(buf, sizeof(buf), "%s \"\" %s", list_cmd, munged_mbox);
348  snprintf(buf + len, sizeof(buf) - len, " RETURN (CHILDREN)");
349  if (browse_add_list_result(adata, buf, state, false))
350  goto fail;
351 
352  if (ARRAY_EMPTY(&state->entry))
353  {
354  // L10N: (%s) is the name / path of the folder we were trying to browse
355  mutt_error(_("No such folder: %s"), path);
356  goto fail;
357  }
358 
360 
361  if (save_lsub)
362  C_ImapCheckSubscribed = true;
363 
364  return 0;
365 
366 fail:
367  if (save_lsub)
368  C_ImapCheckSubscribed = true;
369  return -1;
370 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mailbox_create()

int imap_mailbox_create ( const char *  path)

Create a new IMAP mailbox.

Parameters
pathMailbox to create
Return values
0Success
-1Failure

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

Definition at line 380 of file browse.c.

381 {
382  struct ImapAccountData *adata = NULL;
383  struct ImapMboxData *mdata = NULL;
384  char name[1024];
385 
386  if (imap_adata_find(path, &adata, &mdata) < 0)
387  {
388  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
389  goto err;
390  }
391 
392  /* append a delimiter if necessary */
393  const size_t n = mutt_str_copy(name, mdata->real_name, sizeof(name));
394  if (n && (n < sizeof(name) - 1) && (name[n - 1] != adata->delim))
395  {
396  name[n] = adata->delim;
397  name[n + 1] = '\0';
398  }
399 
400  if (mutt_get_field(_("Create mailbox: "), name, sizeof(name), MUTT_FILE,
401  false, NULL, NULL) < 0)
402  {
403  goto err;
404  }
405 
406  if (mutt_str_len(name) == 0)
407  {
408  mutt_error(_("Mailbox must have a name"));
409  goto err;
410  }
411 
412  if (imap_create_mailbox(adata, name) < 0)
413  goto err;
414 
415  imap_mdata_free((void *) &mdata);
416  mutt_message(_("Mailbox created"));
417  mutt_sleep(0);
418  return 0;
419 
420 err:
421  imap_mdata_free((void *) &mdata);
422  return -1;
423 }
+ 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 433 of file browse.c.

434 {
435  struct ImapAccountData *adata = NULL;
436  struct ImapMboxData *mdata = NULL;
437  char buf[PATH_MAX];
438  char newname[PATH_MAX];
439 
440  if (imap_adata_find(path, &adata, &mdata) < 0)
441  {
442  mutt_debug(LL_DEBUG1, "Couldn't find open connection to %s\n", path);
443  return -1;
444  }
445 
446  if (mdata->real_name[0] == '\0')
447  {
448  mutt_error(_("Can't rename root folder"));
449  goto err;
450  }
451 
452  snprintf(buf, sizeof(buf), _("Rename mailbox %s to: "), mdata->name);
453  mutt_str_copy(newname, mdata->name, sizeof(newname));
454 
455  if (mutt_get_field(buf, newname, sizeof(newname), MUTT_FILE, false, NULL, NULL) < 0)
456  goto err;
457 
458  if (mutt_str_len(newname) == 0)
459  {
460  mutt_error(_("Mailbox must have a name"));
461  goto err;
462  }
463 
464  imap_fix_path(adata->delim, newname, buf, sizeof(buf));
465 
466  if (imap_rename_mailbox(adata, mdata->name, buf) < 0)
467  {
468  mutt_error(_("Rename failed: %s"), imap_get_qualifier(adata->buf));
469  goto err;
470  }
471 
472  mutt_message(_("Mailbox renamed"));
473  mutt_sleep(0);
474  return 0;
475 
476 err:
477  imap_mdata_free((void *) &mdata);
478  return -1;
479 }
+ 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 1623 of file message.c.

1625 {
1626  if (!m || !el || !dest)
1627  return -1;
1628 
1629  struct Buffer cmd, sync_cmd;
1630  char buf[PATH_MAX];
1631  char mbox[PATH_MAX];
1632  char mmbox[PATH_MAX];
1633  char prompt[PATH_MAX + 64];
1634  int rc;
1635  struct ConnAccount cac = { { 0 } };
1636  enum QuadOption err_continue = MUTT_NO;
1637  int triedcreate = 0;
1638  struct EmailNode *en = STAILQ_FIRST(el);
1639  bool single = !STAILQ_NEXT(en, entries);
1640  struct ImapAccountData *adata = imap_adata_get(m);
1641 
1642  if (single && en->email->attach_del)
1643  {
1644  mutt_debug(LL_DEBUG3, "#1 Message contains attachments to be deleted\n");
1645  return 1;
1646  }
1647 
1648  if (imap_parse_path(dest, &cac, buf, sizeof(buf)))
1649  {
1650  mutt_debug(LL_DEBUG1, "bad destination %s\n", dest);
1651  return -1;
1652  }
1653 
1654  /* check that the save-to folder is in the same account */
1655  if (!imap_account_match(&adata->conn->account, &cac))
1656  {
1657  mutt_debug(LL_DEBUG3, "%s not same server as %s\n", dest, mailbox_path(m));
1658  return 1;
1659  }
1660 
1661  imap_fix_path(adata->delim, buf, mbox, sizeof(mbox));
1662  if (*mbox == '\0')
1663  mutt_str_copy(mbox, "INBOX", sizeof(mbox));
1664  imap_munge_mbox_name(adata->unicode, mmbox, sizeof(mmbox), mbox);
1665 
1666  /* loop in case of TRYCREATE */
1667  do
1668  {
1669  mutt_buffer_init(&sync_cmd);
1670  mutt_buffer_init(&cmd);
1671 
1672  if (!single) /* copy tagged messages */
1673  {
1674  /* if any messages have attachments to delete, fall through to FETCH
1675  * and APPEND. TODO: Copy what we can with COPY, fall through for the
1676  * remainder. */
1677  STAILQ_FOREACH(en, el, entries)
1678  {
1679  if (en->email->attach_del)
1680  {
1682  "#2 Message contains attachments to be deleted\n");
1683  return 1;
1684  }
1685 
1686  if (en->email->active && en->email->changed)
1687  {
1688  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1689  if (rc < 0)
1690  {
1691  mutt_debug(LL_DEBUG1, "#1 could not sync\n");
1692  goto out;
1693  }
1694  }
1695  }
1696 
1697  rc = imap_exec_msgset(m, "UID COPY", mmbox, MUTT_TAG, false, false);
1698  if (rc == 0)
1699  {
1700  mutt_debug(LL_DEBUG1, "No messages tagged\n");
1701  rc = -1;
1702  goto out;
1703  }
1704  else if (rc < 0)
1705  {
1706  mutt_debug(LL_DEBUG1, "#1 could not queue copy\n");
1707  goto out;
1708  }
1709  else
1710  {
1711  mutt_message(ngettext("Copying %d message to %s...", "Copying %d messages to %s...", rc),
1712  rc, mbox);
1713  }
1714  }
1715  else
1716  {
1717  mutt_message(_("Copying message %d to %s..."), en->email->index + 1, mbox);
1718  mutt_buffer_add_printf(&cmd, "UID COPY %u %s", imap_edata_get(en->email)->uid, mmbox);
1719 
1720  if (en->email->active && en->email->changed)
1721  {
1722  rc = imap_sync_message_for_copy(m, en->email, &sync_cmd, &err_continue);
1723  if (rc < 0)
1724  {
1725  mutt_debug(LL_DEBUG1, "#2 could not sync\n");
1726  goto out;
1727  }
1728  }
1729  rc = imap_exec(adata, cmd.data, IMAP_CMD_QUEUE);
1730  if (rc != IMAP_EXEC_SUCCESS)
1731  {
1732  mutt_debug(LL_DEBUG1, "#2 could not queue copy\n");
1733  goto out;
1734  }
1735  }
1736 
1737  /* let's get it on */
1738  rc = imap_exec(adata, NULL, IMAP_CMD_NO_FLAGS);
1739  if (rc == IMAP_EXEC_ERROR)
1740  {
1741  if (triedcreate)
1742  {
1743  mutt_debug(LL_DEBUG1, "Already tried to create mailbox %s\n", mbox);
1744  break;
1745  }
1746  /* bail out if command failed for reasons other than nonexistent target */
1747  if (!mutt_istr_startswith(imap_get_qualifier(adata->buf), "[TRYCREATE]"))
1748  break;
1749  mutt_debug(LL_DEBUG3, "server suggests TRYCREATE\n");
1750  snprintf(prompt, sizeof(prompt), _("Create %s?"), mbox);
1751  if (C_ConfirmCreate && (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES))
1752  {
1753  mutt_clear_error();
1754  goto out;
1755  }
1756  if (imap_create_mailbox(adata, mbox) < 0)
1757  break;
1758  triedcreate = 1;
1759  }
1760  } while (rc == IMAP_EXEC_ERROR);
1761 
1762  if (rc != 0)
1763  {
1764  imap_error("imap_copy_messages", adata->buf);
1765  goto out;
1766  }
1767 
1768  /* cleanup */
1769  if (save_opt == SAVE_MOVE)
1770  {
1771  STAILQ_FOREACH(en, el, entries)
1772  {
1773  mutt_set_flag(m, en->email, MUTT_DELETE, true);
1774  mutt_set_flag(m, en->email, MUTT_PURGE, true);
1775  if (C_DeleteUntag)
1776  mutt_set_flag(m, en->email, MUTT_TAG, false);
1777  }
1778  }
1779 
1780  rc = 0;
1781 
1782 out:
1783  FREE(&cmd.data);
1784  FREE(&sync_cmd.data);
1785 
1786  return (rc < 0) ? -1 : rc;
1787 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_logout_all()

void imap_logout_all ( void  )

close all open connections

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

Definition at line 560 of file imap.c.

561 {
562  struct Account *np = NULL;
563  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
564  {
565  if (np->type != MUTT_IMAP)
566  continue;
567 
568  struct ImapAccountData *adata = np->adata;
569  if (!adata)
570  continue;
571 
572  struct Connection *conn = adata->conn;
573  if (!conn || (conn->fd < 0))
574  continue;
575 
576  mutt_message(_("Closing connection to %s..."), conn->account.host);
577  imap_logout(np->adata);
579  }
580 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_expand_path()

int imap_expand_path ( struct Buffer buf)

Buffer wrapper around imap_path_canon()

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

Definition at line 2412 of file imap.c.

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

◆ imap_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 }
+ 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  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  if (hlen == 0)
619  home_match = true;
620  else if (C_ImapDelimChars)
621  {
622  for (delim = C_ImapDelimChars; *delim != '\0'; delim++)
623  if (target_mailbox[hlen] == *delim)
624  home_match = true;
625  }
626  }
627 
628  /* do the '+' substitution */
629  if (home_match)
630  {
631  *path++ = '+';
632  /* copy remaining path, skipping delimiter */
633  if (hlen == 0)
634  hlen = -1;
635  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
636  path[tlen - hlen - 1] = '\0';
637  return;
638  }
639 
640 fallback:
641  mutt_account_tourl(&cac_target, &url);
642  url.path = target_mailbox;
643  url_tostring(&url, path, pathlen, U_NO_FLAGS);
644 }
+ 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 }
+ 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 967 of file util.c.

968 {
969  struct sigaction oldalrm;
970  struct sigaction act;
971  sigset_t oldmask;
972  int rc;
973 
974  bool imap_passive = C_ImapPassive;
975 
976  C_ImapPassive = true;
977  OptKeepQuiet = true;
978 
979  sigprocmask(SIG_SETMASK, NULL, &oldmask);
980 
981  sigemptyset(&act.sa_mask);
982  act.sa_handler = mutt_sig_empty_handler;
983 #ifdef SA_INTERRUPT
984  act.sa_flags = SA_INTERRUPT;
985 #else
986  act.sa_flags = 0;
987 #endif
988 
989  sigaction(SIGALRM, &act, &oldalrm);
990 
991  alarm(C_ImapKeepalive);
992  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
993  {
994  alarm(0); /* cancel a possibly pending alarm */
995  imap_keepalive();
996  alarm(C_ImapKeepalive);
997  }
998 
999  alarm(0); /* cancel a possibly pending alarm */
1000 
1001  sigaction(SIGALRM, &oldalrm, NULL);
1002  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1003 
1004  OptKeepQuiet = false;
1005  if (!imap_passive)
1006  C_ImapPassive = false;
1007 
1008  return rc;
1009 }
+ 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 944 of file util.c.

945 {
946  time_t now = mutt_date_epoch();
947  struct Account *np = NULL;
948  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
949  {
950  if (np->type != MUTT_IMAP)
951  continue;
952 
953  struct ImapAccountData *adata = np->adata;
954  if (!adata || !adata->mailbox)
955  continue;
956 
957  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + C_ImapKeepalive)))
958  imap_check_mailbox(adata->mailbox, true);
959  }
960 }
+ 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 163 of file util.c.

164 {
165  struct ImapAccountData *adata = NULL;
166  struct ImapMboxData *mdata = NULL;
167  char mbox[1024];
168 
169  if (imap_adata_find(path, &adata, &mdata) < 0)
170  {
171  mutt_str_copy(buf, path, buflen);
172  return;
173  }
174 
175  /* Gets the parent mbox in mbox */
176  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
177 
178  /* Returns a fully qualified IMAP url */
179  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
180  imap_mdata_free((void *) &mdata);
181 }
+ 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 190 of file util.c.

191 {
192  struct ImapAccountData *adata = NULL;
193  struct ImapMboxData *mdata = NULL;
194 
195  if (imap_adata_find(path, &adata, &mdata) < 0)
196  return;
197 
198  /* Returns a fully qualified IMAP url */
199  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
200  imap_mdata_free((void *) &mdata);
201 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_search()

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

Find messages in mailbox matching a pattern.

Parameters
mMailbox
patPattern to match
Return values
trueSuccess
falseFailure

Definition at line 228 of file search.c.

229 {
230  for (int i = 0; i < m->msg_count; i++)
231  {
232  struct Email *e = m->emails[i];
233  if (!e)
234  break;
235  e->matched = false;
236  }
237 
238  if (check_pattern_list(pat) == 0)
239  return true;
240 
241  struct Buffer buf;
242  mutt_buffer_init(&buf);
243  mutt_buffer_addstr(&buf, "UID SEARCH ");
244 
245  struct ImapAccountData *adata = imap_adata_get(m);
246  const bool ok = compile_search(adata, SLIST_FIRST(pat), &buf) &&
248 
249  FREE(&buf.data);
250  return ok;
251 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ImapKeepalive

short C_ImapKeepalive

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

Definition at line 49 of file config.c.

◆ C_ImapListSubscribed

bool C_ImapListSubscribed

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

Definition at line 50 of file config.c.

◆ C_ImapPassive

bool C_ImapPassive

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

Definition at line 54 of file config.c.

◆ C_ImapPeek

bool C_ImapPeek

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

Definition at line 55 of file config.c.

◆ MxImapOps

struct MxOps MxImapOps

IMAP Mailbox - Implements MxOps.

Definition at line 2459 of file imap.c.

imap_cache_del
int imap_cache_del(struct Mailbox *m, struct Email *e)
Delete an email from the body cache.
Definition: message.c:1796
ImapMboxData::real_name
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: mdata.h:42
C_ImapDelimChars
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:45
ConnAccount
Login details for a remote server.
Definition: connaccount.h:51
C_Timeout
WHERE short C_Timeout
Config: Time to wait for user input in menus.
Definition: mutt_globals.h:115
Mailbox::rights
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:121
C_ImapKeepalive
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
mutt_parse_rc_line
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1044
Connection
An open network connection (socket)
Definition: connection.h:34
MUTT_FLAG
@ MUTT_FLAG
Flagged messages.
Definition: mutt.h:102
imap_hcache_open
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:299
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
BrowserState::entry
struct BrowserStateEntry entry
Definition: browser.h:98
imap_hcache_put
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:381
MxStatus
MxStatus
Return values from mx_mbox_check(), mx_mbox_sync(), and mx_mbox_close()
Definition: mx.h:71
ConnAccount::host
char host[128]
Server to login to.
Definition: connaccount.h:53
U_IMAP
@ U_IMAP
Url is imap://.
Definition: url.h:38
MailboxNode
List of Mailboxes.
Definition: mailbox.h:152
NeoMutt::accounts
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
mutt_account_fromurl
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
_
#define _(a)
Definition: message.h:28
imap_quote_string
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:836
imap_sync_message_for_copy
int imap_sync_message_for_copy(struct Mailbox *m, struct Email *e, struct Buffer *cmd, enum QuadOption *err_continue)
Update server to reflect the flags of a single message.
Definition: imap.c:995
Mailbox
A mailbox.
Definition: mailbox.h:81
ImapMboxData::munge_name
char * munge_name
Munged version of the mailbox name.
Definition: mdata.h:41
TRANSFORM_NONE
@ TRANSFORM_NONE
No transformation.
Definition: commands.h:51
C_ImapCheckSubscribed
bool C_ImapCheckSubscribed
Config: (imap) When opening a mailbox, ask the server for a list of subscribed folders.
Definition: config.c:40
IMAP_EXPUNGE_PENDING
#define IMAP_EXPUNGE_PENDING
Messages on the server have been expunged.
Definition: private.h:70
Mailbox::emails
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
Mailbox::append
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
MUTT_ACCT_PORT
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:42
longest_common_prefix
static size_t longest_common_prefix(char *dest, const char *src, size_t start, size_t dlen)
Find longest prefix common to two strings.
Definition: imap.c:364
imap_mdata_free
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:36
Email::matched
bool matched
Search matches this Email.
Definition: email.h:68
IMAP_EXEC_SUCCESS
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
Definition: private.h:86
Buffer
String manipulation buffer.
Definition: buffer.h:33
Account::type
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
ImapAccountData::closing
bool closing
If true, we are waiting for CLOSE completion.
Definition: adata.h:40
LL_DEBUG3
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
C_DeleteUntag
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: mutt_globals.h:145
Connection::account
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
ImapList::delim
char delim
Definition: private.h:153
IMAP_IDLE
@ IMAP_IDLE
Connection is idle.
Definition: private.h:115
ConnAccount::get_field
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
MUTT_ACL_DELETE
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:66
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
IMAP_SSL_PORT
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:48
C_ImapIdle
bool C_ImapIdle
Config: (imap) Use the IMAP IDLE extension to check for new mail.
Definition: config.c:48
mutt_buffer_add_printf
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
mutt_account_tourl
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
imap_munge_mbox_name
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:910
ImapAccountData::cmdresult
struct ImapList * cmdresult
Definition: adata.h:63
imap_qualify_path
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *conn_account, char *path)
Make an absolute IMAP folder target.
Definition: util.c:819
U_NO_FLAGS
#define U_NO_FLAGS
Definition: url.h:48
ImapAccountData::buf
char * buf
Definition: adata.h:56
IMAP_PORT
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:47
ImapAccountData::capabilities
ImapCapFlags capabilities
Definition: adata.h:52
EmailNode::email
struct Email * email
Email in the list.
Definition: email.h:127
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
imap_cmd_step
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1074
mutt_buffer_init
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
Url::scheme
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:69
neomutt_mailboxlist_get_all
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
IMAP_FLAGS_PENDING
#define IMAP_FLAGS_PENDING
Flags have changed on the server.
Definition: private.h:72
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
IMAP_CMD_POLL
#define IMAP_CMD_POLL
Poll the tcp connection before running the imap command.
Definition: private.h:78
SAVE_MOVE
@ SAVE_MOVE
Move message to another mailbox, removing the original.
Definition: commands.h:62
FREE
#define FREE(x)
Definition: memory.h:40
EmailNode
List of Emails.
Definition: email.h:125
STAILQ_FIRST
#define STAILQ_FIRST(head)
Definition: queue.h:347
MUTT_DELETED
@ MUTT_DELETED
Deleted messages.
Definition: mutt.h:101
mutt_get_sort_func
sort_t mutt_get_sort_func(enum SortType method)
Get the sort function for a given sort id.
Definition: sort.c:325
Email::path
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
imap_hcache_del
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:399
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
ImapList::noinferiors
bool noinferiors
Definition: private.h:155
ImapList
Items in an IMAP browser.
Definition: private.h:150
MailboxNode::mailbox
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:154
ImapAccountData::lastread
time_t lastread
last time we read a command for the server
Definition: adata.h:55
mutt_sleep
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1448
mutt_socket_poll
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
imap_exec_msgset
int imap_exec_msgset(struct Mailbox *m, const char *pre, const char *post, enum MessageType flag, bool changed, bool invert)
Prepare commands for all messages matching conditions.
Definition: imap.c:917
imap_adata_get
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:86
mailbox_free
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
mutt_sig_empty_handler
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
url_parse
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
mx_path_resolve
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
C_MessageCacheClean
bool C_MessageCacheClean
Config: (imap/pop) Clean out obsolete entries from the message cache.
Definition: bcache.c:44
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
ImapAccountData::conn
struct Connection * conn
Definition: adata.h:38
MX_STATUS_REOPENED
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mx.h:77
mutt_buffer_alloc
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
imap_cmd_finish
void imap_cmd_finish(struct ImapAccountData *adata)
Attempt to perform cleanup.
Definition: command.c:1309
MUTT_READ
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:96
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
MX_STATUS_NEW_MAIL
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mx.h:75
Connection::fd
int fd
Socket file descriptor.
Definition: connection.h:40
Email::old
bool old
Email is seen, but unread.
Definition: email.h:50
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
MUTT_PURGE
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition: mutt.h:100
Email::active
bool active
Message is not to be removed.
Definition: email.h:59
imap_account_match
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1043
imap_status
static int imap_status(struct ImapAccountData *adata, struct ImapMboxData *mdata, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1163
imap_hcache_close
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:340
imap_adata_find
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:74
imap_adata_find
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:74
Mailbox::mdata
void * mdata
Driver specific data.
Definition: mailbox.h:136
Envelope::changed
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
url_tostring
int url_tostring(struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:418
imap_commands
static const struct Command imap_commands[]
Definition: imap.c:72
imap_logout
static void imap_logout(struct ImapAccountData *adata)
Gracefully log out of server.
Definition: imap.c:535
Account
A group of associated Mailboxes.
Definition: account.h:36
Mailbox::changed
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
Url
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:67
Mailbox::account
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
imap_mailbox_status
int imap_mailbox_status(struct Mailbox *m, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1256
ImapEmailData
IMAP-specific Email data -.
Definition: edata.h:33
MUTT_ACCT_TYPE_IMAP
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:37
url_free
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
Mailbox::msg_count
int msg_count
Total number of messages.
Definition: mailbox.h:91
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
ImapAccountData::unicode
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: adata.h:59
MUTT_UNKNOWN
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
ImapEmailData::uid
unsigned int uid
32-bit Message UID
Definition: edata.h:44
imap_mxcmp
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:554
IMAP_CAP_LIST_EXTENDED
#define IMAP_CAP_LIST_EXTENDED
RFC5258: IMAP4 LIST Command Extensions.
Definition: private.h:141
U_IMAPS
@ U_IMAPS
Url is imaps://.
Definition: url.h:39
imap_cmd_start
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1060
mutt_save_message_ctx
int mutt_save_message_ctx(struct Email *e, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt, struct Mailbox *m)
Save a message to a given mailbox.
Definition: commands.c:1001
imap_msn_remove
void imap_msn_remove(struct MSN *msn, size_t idx)
Remove an entry from the cache.
Definition: msn.c:113
MUTT_IMAP
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:53
compile_search
static bool compile_search(const struct ImapAccountData *adata, const struct Pattern *pat, struct Buffer *buf)
Convert NeoMutt pattern to IMAP search.
Definition: search.c:208
imap_cmd_idle
int imap_cmd_idle(struct ImapAccountData *adata)
Enter the IDLE state.
Definition: command.c:1376
check_pattern_list
static int check_pattern_list(const struct PatternList *patterns)
Check how many patterns in a list can be searched server-side.
Definition: search.c:82
imap_error
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:663
ConnAccount::type
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MUTT_REPLIED
@ MUTT_REPLIED
Messages that have been replied to.
Definition: mutt.h:95
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
Email::purge
bool purge
Skip trash folder when deleting.
Definition: email.h:46
imap_path_canon
int imap_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
Definition: imap.c:2386
MX_STATUS_ERROR
@ MX_STATUS_ERROR
An error occurred.
Definition: mx.h:73
Email::flagged
bool flagged
Marked important?
Definition: email.h:43
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
Mailbox::verbose
bool verbose
Display status messages?
Definition: mailbox.h:118
ConnAccount::flags
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
IMAP_OPEN_NO_FLAGS
#define IMAP_OPEN_NO_FLAGS
No flags are set.
Definition: private.h:67
mutt_date_epoch
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
SORT_ORDER
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:50
complete_hosts
static int complete_hosts(char *buf, size_t buflen)
Look for completion matches for mailboxes.
Definition: imap.c:385
ImapAccountData
IMAP-specific Account data -.
Definition: adata.h:36
SLIST_FIRST
#define SLIST_FIRST(head)
Definition: queue.h:228
imap_get_parent
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder's parent.
Definition: util.c:122
MUTT_ACL_WRITE
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:74
ImapMboxData
IMAP-specific Mailbox data -.
Definition: mdata.h:38
MUTT_OLD
@ MUTT_OLD
Old messages.
Definition: mutt.h:94
imap_cache_clean
int imap_cache_clean(struct Mailbox *m)
Delete all the entries in the message cache.
Definition: message.c:1815
Email::deleted
bool deleted
Email is deleted.
Definition: email.h:45
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
BrowserState::folder
char * folder
Definition: browser.h:101
mutt_str_cmp
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:567
MUTT_TRASH
@ MUTT_TRASH
Trashed messages.
Definition: mutt.h:108
MUTT_ACCT_SSL
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
imap_fix_path
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:685
imap_keepalive
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:944
C_ImapPassive
bool C_ImapPassive
Config: (imap) Reuse an existing IMAP connection to check for new mail.
Definition: config.c:54
imap_path_status
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1222
ARRAY_EMPTY
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
imap_get_qualifier
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:771
MUTT_DELETE
@ MUTT_DELETE
Messages to be deleted.
Definition: mutt.h:98
imap_qualify_path
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:819
C_ImapListSubscribed
bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: config.c:50
ConnAccount::port
unsigned short port
Port to connect to.
Definition: connaccount.h:57
C_Sort
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:60
Email::edata
void * edata
Driver-specific data.
Definition: email.h:111
mutt_mem_malloc
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
ImapAccountData::state
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: adata.h:41
imap_exec
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1245
IMAP_RES_CONTINUE
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:59
MUTT_TAG
@ MUTT_TAG
Tagged messages.
Definition: mutt.h:103
browse_add_list_result
static int browse_add_list_result(struct ImapAccountData *adata, const char *cmd, struct BrowserState *state, bool isparent)
Add entries to the folder browser.
Definition: browse.c:139
IMAP_CAP_IDLE
#define IMAP_CAP_IDLE
RFC2177: IDLE.
Definition: private.h:136
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
IMAP_EXPUNGE_EXPECTED
#define IMAP_EXPUNGE_EXPECTED
Messages will be expunged from the server.
Definition: private.h:69
mutt_istr_startswith
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
imap_allow_reopen
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1015
IMAP_EXEC_ERROR
@ IMAP_EXEC_ERROR
Imap command failure.
Definition: private.h:87
mx_ac_remove
int mx_ac_remove(struct Mailbox *m)
Remove a Mailbox from an Account and delete Account if empty.
Definition: mx.c:1780
imap_path_probe
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2372
imap_mdata_get
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:55
ImapList::noselect
bool noselect
Definition: private.h:154
IMAP_CMD_QUEUE
#define IMAP_CMD_QUEUE
Queue a command, do not execute.
Definition: private.h:77
Account::adata
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
imap_account_match
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1043
Email::index
int index
The absolute (unsorted) message number.
Definition: email.h:86
imap_parse_path
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:483
imap_create_mailbox
int imap_create_mailbox(struct ImapAccountData *adata, char *mailbox)
Create a new mailbox.
Definition: imap.c:447
plen
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
OptKeepQuiet
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program
Definition: options.h:39
IMAP_AUTHENTICATED
@ IMAP_AUTHENTICATED
Connection is authenticated.
Definition: private.h:111
ConnAccount::service
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
IMAP_CMD_NO_FLAGS
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:75
STAILQ_NEXT
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
ImapMboxData::reopen
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: mdata.h:44
mutt_get_field
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:311
IMAP_NEWMAIL_PENDING
#define IMAP_NEWMAIL_PENDING
New mail is waiting on the server.
Definition: private.h:71
Url::path
char * path
Path.
Definition: url.h:74
MX_STATUS_FLAGS
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mx.h:78
Email::attach_del
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
mailbox_path
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:206
imap_fix_path
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:685
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
Email::replied
bool replied
Email has been replied to.
Definition: email.h:54
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
Email
The envelope/body of an email.
Definition: email.h:37
MUTT_ACL_SEEN
#define MUTT_ACL_SEEN
Change the 'seen' status of a message.
Definition: mailbox.h:73
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_set_flag
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
IMAP_SELECTED
@ IMAP_SELECTED
Mailbox is selected.
Definition: private.h:112
imap_edata_get
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:63
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
mx_mbox_ac_link
bool mx_mbox_ac_link(struct Mailbox *m)
Link a Mailbox to an existing or new Account.
Definition: mx.c:272
Email::read
bool read
Email is read.
Definition: email.h:51
C_ConfirmCreate
WHERE bool C_ConfirmCreate
Config: Confirm before creating a new mailbox.
Definition: mutt_globals.h:142
COMMANDS_REGISTER
#define COMMANDS_REGISTER(cmds)
Definition: mutt_commands.h:77
imap_rename_mailbox
int imap_rename_mailbox(struct ImapAccountData *adata, char *oldname, const char *newname)
Rename a mailbox.
Definition: imap.c:488
LL_DEBUG2
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
neomutt_mailboxlist_clear
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
Email::changed
bool changed
Email has been edited.
Definition: email.h:48
ImapMboxData::name
char * name
Mailbox name.
Definition: mdata.h:40
add_folder
static void add_folder(char delim, char *folder, bool noselect, bool noinferiors, struct BrowserState *state, bool isparent)
Format and add an IMAP folder to the browser.
Definition: browse.c:60
mx_mbox_find2
struct Mailbox * mx_mbox_find2(const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1654
ImapList::name
char * name
Definition: private.h:152
sync_helper
static int sync_helper(struct Mailbox *m, AclFlags right, enum MessageType flag, const char *name)
Sync flag changes to the server.
Definition: imap.c:323
imap_check_mailbox
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1094
imap_parse_path
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:483
MX_STATUS_OK
@ MX_STATUS_OK
No changes.
Definition: mx.h:74
ImapAccountData::delim
char delim
Definition: adata.h:72
mutt_error
#define mutt_error(...)
Definition: logging.h:84
imap_get_field
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:206
mutt_str_copy
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716