NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
compose.h File Reference

GUI editor for an email's headers. More...

#include <stdio.h>
+ Include dependency graph for compose.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MUTT_COMPOSE_NOFREEHEADER   (1 << 0)
 

Functions

int mutt_compose_menu (struct Email *e, char *fcc, size_t fcclen, struct Email *e_cur, int flags)
 Allow the user to edit the message envelope. More...
 

Variables

char * C_ComposeFormat
 Config: printf-like format string for the Compose panel's status bar. More...
 
char * C_Ispell
 Config: External command to perform spell-checking. More...
 
unsigned char C_Postpone
 Config: Save messages to the C_Postponed folder. More...
 

Detailed Description

GUI editor for an email's headers.

Authors
  • 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 compose.h.

Macro Definition Documentation

◆ MUTT_COMPOSE_NOFREEHEADER

#define MUTT_COMPOSE_NOFREEHEADER   (1 << 0)

Definition at line 36 of file compose.h.

Function Documentation

◆ mutt_compose_menu()

int mutt_compose_menu ( struct Email e,
char *  fcc,
size_t  fcclen,
struct Email e_cur,
int  flags 
)

Allow the user to edit the message envelope.

Parameters
eEmail to fill
fccBuffer to save FCC
fcclenLength of FCC buffer
e_curCurrent message
flagsFlags, e.g. MUTT_COMPOSE_NOFREEHEADER
Return values
1Message should be postponed
0Normal exit
-1Abort message

Definition at line 1049 of file compose.c.

1050 {
1051  char helpstr[1024]; // This isn't copied by the help bar
1052  char buf[PATH_MAX];
1053  int op_close = OP_NULL;
1054  int rc = -1;
1055  bool loop = true;
1056  bool fcc_set = false; /* has the user edited the Fcc: field ? */
1057  struct ComposeRedrawData redraw = { 0 };
1058  struct ComposeRedrawData *rd = &redraw;
1059 #ifdef USE_NNTP
1060  bool news = OptNewsSend; /* is it a news article ? */
1061 #endif
1062 
1064 
1065  rd->email = e;
1066  rd->fcc = fcc;
1067  rd->win = MuttIndexWindow;
1068 
1069  struct Menu *menu = mutt_menu_new(MENU_COMPOSE);
1070  menu->offset = HDR_ATTACH;
1072  menu->menu_tag = attach_tag;
1073 #ifdef USE_NNTP
1074  if (news)
1075  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeNewsHelp);
1076  else
1077 #endif
1078  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeHelp);
1080  menu->redraw_data = rd;
1081  mutt_menu_push_current(menu);
1082 
1083  struct AttachCtx *actx = mutt_actx_new();
1084  actx->email = e;
1085  mutt_update_compose_menu(actx, menu, true);
1086 
1087  update_crypt_info(rd);
1088 
1089  while (loop)
1090  {
1091 #ifdef USE_NNTP
1092  OptNews = false; /* for any case */
1093 #endif
1094  const int op = mutt_menu_loop(menu);
1095  switch (op)
1096  {
1097  case OP_COMPOSE_EDIT_FROM:
1098  edit_address_list(HDR_FROM, &e->env->from, rd);
1099  update_crypt_info(rd);
1101  break;
1102 
1103  case OP_COMPOSE_EDIT_TO:
1104 #ifdef USE_NNTP
1105  if (news)
1106  break;
1107 #endif
1108  edit_address_list(HDR_TO, &e->env->to, rd);
1109  update_crypt_info(rd);
1111  break;
1112 
1113  case OP_COMPOSE_EDIT_BCC:
1114 #ifdef USE_NNTP
1115  if (news)
1116  break;
1117 #endif
1118  edit_address_list(HDR_BCC, &e->env->bcc, rd);
1119  update_crypt_info(rd);
1121  break;
1122 
1123  case OP_COMPOSE_EDIT_CC:
1124 #ifdef USE_NNTP
1125  if (news)
1126  break;
1127 #endif
1128  edit_address_list(HDR_CC, &e->env->cc, rd);
1129  update_crypt_info(rd);
1131  break;
1132 #ifdef USE_NNTP
1133  case OP_COMPOSE_EDIT_NEWSGROUPS:
1134  if (!news)
1135  break;
1136  if (e->env->newsgroups)
1137  mutt_str_strfcpy(buf, e->env->newsgroups, sizeof(buf));
1138  else
1139  buf[0] = '\0';
1140  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) == 0)
1141  {
1142  mutt_str_replace(&e->env->newsgroups, buf);
1144  if (e->env->newsgroups)
1145  mutt_paddstr(W, e->env->newsgroups);
1146  else
1148  }
1149  break;
1150 
1151  case OP_COMPOSE_EDIT_FOLLOWUP_TO:
1152  if (!news)
1153  break;
1154  if (e->env->followup_to)
1155  mutt_str_strfcpy(buf, e->env->followup_to, sizeof(buf));
1156  else
1157  buf[0] = '\0';
1158  if (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) == 0)
1159  {
1160  mutt_str_replace(&e->env->followup_to, buf);
1162  if (e->env->followup_to)
1163  mutt_paddstr(W, e->env->followup_to);
1164  else
1166  }
1167  break;
1168 
1169  case OP_COMPOSE_EDIT_X_COMMENT_TO:
1170  if (!(news && C_XCommentTo))
1171  break;
1172  if (e->env->x_comment_to)
1173  mutt_str_strfcpy(buf, e->env->x_comment_to, sizeof(buf));
1174  else
1175  buf[0] = '\0';
1176  if (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) == 0)
1177  {
1178  mutt_str_replace(&e->env->x_comment_to, buf);
1180  if (e->env->x_comment_to)
1182  else
1184  }
1185  break;
1186 #endif
1187 
1188  case OP_COMPOSE_EDIT_SUBJECT:
1189  if (e->env->subject)
1190  mutt_str_strfcpy(buf, e->env->subject, sizeof(buf));
1191  else
1192  buf[0] = '\0';
1193  if (mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) == 0)
1194  {
1195  mutt_str_replace(&e->env->subject, buf);
1197  if (e->env->subject)
1198  mutt_paddstr(W, e->env->subject);
1199  else
1201  }
1203  break;
1204 
1205  case OP_COMPOSE_EDIT_REPLY_TO:
1208  break;
1209 
1210  case OP_COMPOSE_EDIT_FCC:
1211  mutt_str_strfcpy(buf, fcc, sizeof(buf));
1212  if (mutt_get_field(_("Fcc: "), buf, sizeof(buf), MUTT_FILE | MUTT_CLEAR) == 0)
1213  {
1214  mutt_str_strfcpy(fcc, buf, fcclen);
1215  mutt_pretty_mailbox(fcc, fcclen);
1217  mutt_paddstr(W, fcc);
1218  fcc_set = true;
1219  }
1221  break;
1222 
1223  case OP_COMPOSE_EDIT_MESSAGE:
1224  if (C_Editor && (mutt_str_strcmp("builtin", C_Editor) != 0) && !C_EditHeaders)
1225  {
1228  menu->redraw = REDRAW_FULL;
1230  break;
1231  }
1232  /* fallthrough */
1233 
1234  case OP_COMPOSE_EDIT_HEADERS:
1235  if ((mutt_str_strcmp("builtin", C_Editor) != 0) &&
1236  ((op == OP_COMPOSE_EDIT_HEADERS) || ((op == OP_COMPOSE_EDIT_MESSAGE) && C_EditHeaders)))
1237  {
1238  const char *tag = NULL;
1239  char *err = NULL;
1240  mutt_env_to_local(e->env);
1241  mutt_edit_headers(NONULL(C_Editor), e->content->filename, e, fcc, fcclen);
1242  if (mutt_env_to_intl(e->env, &tag, &err))
1243  {
1244  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
1245  FREE(&err);
1246  }
1247  update_crypt_info(rd);
1248  }
1249  else
1250  {
1251  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
1252  * attachment list could change if the user invokes ~v to edit
1253  * the message with headers, in which we need to execute the
1254  * code below to regenerate the index array */
1255  mutt_builtin_editor(e->content->filename, e, e_cur);
1256  }
1258 
1259  /* attachments may have been added */
1260  if (actx->idxlen && actx->idx[actx->idxlen - 1]->content->next)
1261  {
1262  mutt_actx_entries_free(actx);
1263  mutt_update_compose_menu(actx, menu, true);
1264  }
1265 
1266  menu->redraw = REDRAW_FULL;
1268  break;
1269 
1270  case OP_COMPOSE_ATTACH_KEY:
1271  {
1272  if (!(WithCrypto & APPLICATION_PGP))
1273  break;
1274  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1276  if (ap->content)
1277  {
1278  update_idx(menu, actx, ap);
1279  menu->redraw |= REDRAW_INDEX;
1280  }
1281  else
1282  FREE(&ap);
1283 
1284  menu->redraw |= REDRAW_STATUS;
1285 
1287  break;
1288  }
1289 
1290  case OP_COMPOSE_MOVE_UP:
1291  if (menu->current == 0)
1292  {
1293  mutt_error(_("Attachment is already at top"));
1294  break;
1295  }
1296  if (menu->current == 1)
1297  {
1298  mutt_error(_("The fundamental part can't be moved"));
1299  break;
1300  }
1301  compose_attach_swap(e->content, actx->idx, menu->current - 1);
1302  menu->redraw = REDRAW_INDEX;
1303  menu->current--;
1304  break;
1305 
1306  case OP_COMPOSE_MOVE_DOWN:
1307  if (menu->current == (actx->idxlen - 1))
1308  {
1309  mutt_error(_("Attachment is already at bottom"));
1310  break;
1311  }
1312  if (menu->current == 0)
1313  {
1314  mutt_error(_("The fundamental part can't be moved"));
1315  break;
1316  }
1317  compose_attach_swap(e->content, actx->idx, menu->current);
1318  menu->redraw = REDRAW_INDEX;
1319  menu->current++;
1320  break;
1321 
1322  case OP_COMPOSE_GROUP_ALTS:
1323  {
1324  if (menu->tagged < 2)
1325  {
1326  mutt_error(
1327  _("Grouping 'alternatives' requires at least 2 tagged messages"));
1328  break;
1329  }
1330 
1331  struct Body *group = mutt_body_new();
1332  group->type = TYPE_MULTIPART;
1333  group->subtype = mutt_str_strdup("alternative");
1334  group->disposition = DISP_INLINE;
1335 
1336  struct Body *alts = NULL;
1337  /* group tagged message into a multipart/alternative */
1338  struct Body *bptr = e->content;
1339  for (int i = 0; bptr;)
1340  {
1341  if (bptr->tagged)
1342  {
1343  bptr->tagged = false;
1344  bptr->disposition = DISP_INLINE;
1345 
1346  /* for first match, set group desc according to match */
1347 #define ALTS_TAG "Alternatives for \"%s\""
1348  if (!group->description)
1349  {
1350  char *p = bptr->description ? bptr->description : bptr->filename;
1351  if (p)
1352  {
1353  group->description =
1354  mutt_mem_calloc(1, strlen(p) + strlen(ALTS_TAG) + 1);
1355  sprintf(group->description, ALTS_TAG, p);
1356  }
1357  }
1358 
1359  /* append bptr to the alts list,
1360  * and remove from the e->content list */
1361  if (!alts)
1362  {
1363  group->parts = bptr;
1364  alts = bptr;
1365  bptr = bptr->next;
1366  alts->next = NULL;
1367  }
1368  else
1369  {
1370  alts->next = bptr;
1371  bptr = bptr->next;
1372  alts = alts->next;
1373  alts->next = NULL;
1374  }
1375 
1376  for (int j = i; j < actx->idxlen - 1; j++)
1377  {
1378  actx->idx[j] = actx->idx[j + 1];
1379  actx->idx[j + 1] = NULL; /* for debug reason */
1380  }
1381  actx->idxlen--;
1382  }
1383  else
1384  {
1385  bptr = bptr->next;
1386  i++;
1387  }
1388  }
1389 
1390  group->next = NULL;
1392 
1393  /* if no group desc yet, make one up */
1394  if (!group->description)
1395  group->description = mutt_str_strdup("unknown alternative group");
1396 
1397  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1398  gptr->content = group;
1399  update_idx(menu, actx, gptr);
1400  menu->redraw = REDRAW_INDEX;
1401  break;
1402  }
1403 
1404  case OP_COMPOSE_GROUP_LINGUAL:
1405  {
1406  if (menu->tagged < 2)
1407  {
1408  mutt_error(
1409  _("Grouping 'multilingual' requires at least 2 tagged messages"));
1410  break;
1411  }
1412 
1413  /* traverse to see whether all the parts have Content-Language: set */
1414  int tagged_with_lang_num = 0;
1415  for (struct Body *b = e->content; b; b = b->next)
1416  if (b->tagged && b->language && *b->language)
1417  tagged_with_lang_num++;
1418 
1419  if (menu->tagged != tagged_with_lang_num)
1420  {
1421  if (mutt_yesorno(
1422  _("Not all parts have 'Content-Language' set, continue?"), MUTT_YES) != MUTT_YES)
1423  {
1424  mutt_message(_("Not sending this message"));
1425  break;
1426  }
1427  }
1428 
1429  struct Body *group = mutt_body_new();
1430  group->type = TYPE_MULTIPART;
1431  group->subtype = mutt_str_strdup("multilingual");
1432  group->disposition = DISP_INLINE;
1433 
1434  struct Body *alts = NULL;
1435  /* group tagged message into a multipart/multilingual */
1436  struct Body *bptr = e->content;
1437  for (int i = 0; bptr;)
1438  {
1439  if (bptr->tagged)
1440  {
1441  bptr->tagged = false;
1442  bptr->disposition = DISP_INLINE;
1443 
1444  /* for first match, set group desc according to match */
1445 #define LINGUAL_TAG "Multilingual part for \"%s\""
1446  if (!group->description)
1447  {
1448  char *p = bptr->description ? bptr->description : bptr->filename;
1449  if (p)
1450  {
1451  group->description =
1452  mutt_mem_calloc(1, strlen(p) + strlen(LINGUAL_TAG) + 1);
1453  sprintf(group->description, LINGUAL_TAG, p);
1454  }
1455  }
1456 
1457  /* append bptr to the alts list,
1458  * and remove from the e->content list */
1459  if (!alts)
1460  {
1461  group->parts = bptr;
1462  alts = bptr;
1463  bptr = bptr->next;
1464  alts->next = NULL;
1465  }
1466  else
1467  {
1468  alts->next = bptr;
1469  bptr = bptr->next;
1470  alts = alts->next;
1471  alts->next = NULL;
1472  }
1473 
1474  for (int j = i; j < actx->idxlen - 1; j++)
1475  {
1476  actx->idx[j] = actx->idx[j + 1];
1477  actx->idx[j + 1] = NULL; /* for debug reason */
1478  }
1479  actx->idxlen--;
1480  }
1481  else
1482  {
1483  bptr = bptr->next;
1484  i++;
1485  }
1486  }
1487 
1488  group->next = NULL;
1490 
1491  /* if no group desc yet, make one up */
1492  if (!group->description)
1493  group->description = mutt_str_strdup("unknown multilingual group");
1494 
1495  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1496  gptr->content = group;
1497  update_idx(menu, actx, gptr);
1498  menu->redraw = REDRAW_INDEX;
1499  break;
1500  }
1501 
1502  case OP_COMPOSE_ATTACH_FILE:
1503  {
1504  char *prompt = _("Attach file");
1505  int numfiles = 0;
1506  char **files = NULL;
1507  buf[0] = '\0';
1508 
1509  if ((mutt_enter_fname_full(prompt, buf, sizeof(buf), false, true,
1510  &files, &numfiles, MUTT_SEL_MULTI) == -1) ||
1511  (*buf == '\0'))
1512  {
1513  break;
1514  }
1515 
1516  bool error = false;
1517  if (numfiles > 1)
1518  {
1519  mutt_message(ngettext("Attaching selected file...",
1520  "Attaching selected files...", numfiles));
1521  }
1522  for (int i = 0; i < numfiles; i++)
1523  {
1524  char *att = files[i];
1525  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1526  ap->unowned = true;
1527  ap->content = mutt_make_file_attach(att);
1528  if (ap->content)
1529  update_idx(menu, actx, ap);
1530  else
1531  {
1532  error = true;
1533  mutt_error(_("Unable to attach %s"), att);
1534  FREE(&ap);
1535  }
1536  FREE(&files[i]);
1537  }
1538 
1539  FREE(&files);
1540  if (!error)
1541  mutt_clear_error();
1542 
1543  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1545  break;
1546  }
1547 
1548  case OP_COMPOSE_ATTACH_MESSAGE:
1549 #ifdef USE_NNTP
1550  case OP_COMPOSE_ATTACH_NEWS_MESSAGE:
1551 #endif
1552  {
1553  char *prompt = _("Open mailbox to attach message from");
1554  buf[0] = '\0';
1555 
1556 #ifdef USE_NNTP
1557  OptNews = false;
1558  if (Context && (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE))
1559  {
1561  if (!CurrentNewsSrv)
1562  break;
1563 
1564  prompt = _("Open newsgroup to attach message from");
1565  OptNews = true;
1566  }
1567 #endif
1568 
1569  if (Context)
1570 #ifdef USE_NNTP
1571  if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->mailbox->magic == MUTT_NNTP))
1572 #endif
1573  {
1574  mutt_str_strfcpy(buf, mailbox_path(Context->mailbox), sizeof(buf));
1575  mutt_pretty_mailbox(buf, sizeof(buf));
1576  }
1577 
1578  if ((mutt_enter_fname(prompt, buf, sizeof(buf), true) == -1) || (buf[0] == '\0'))
1579  break;
1580 
1581 #ifdef USE_NNTP
1582  if (OptNews)
1583  nntp_expand_path(buf, sizeof(buf), &CurrentNewsSrv->conn->account);
1584  else
1585 #endif
1586  mutt_expand_path(buf, sizeof(buf));
1587 #ifdef USE_IMAP
1588  if (imap_path_probe(buf, NULL) != MUTT_IMAP)
1589 #endif
1590 #ifdef USE_POP
1591  if (pop_path_probe(buf, NULL) != MUTT_POP)
1592 #endif
1593 #ifdef USE_NNTP
1594  if (!OptNews && (nntp_path_probe(buf, NULL) != MUTT_NNTP))
1595 #endif
1596  /* check to make sure the file exists and is readable */
1597  if (access(buf, R_OK) == -1)
1598  {
1599  mutt_perror(buf);
1600  break;
1601  }
1602 
1603  menu->redraw = REDRAW_FULL;
1604 
1605  struct Mailbox *m = mx_path_resolve(buf);
1606  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
1607  if (!ctx)
1608  {
1609  mutt_error(_("Unable to open mailbox %s"), buf);
1610  mailbox_free(&m);
1611  break;
1612  }
1613 
1614  if (ctx->mailbox->msg_count == 0)
1615  {
1616  mx_mbox_close(&ctx);
1617  mutt_error(_("No messages in that folder"));
1618  break;
1619  }
1620 
1621  struct Context *ctx_cur = Context; /* remember current folder and sort methods */
1622  int old_sort = C_Sort; /* C_Sort, SortAux could be changed in mutt_index_menu() */
1623  int old_sort_aux = C_SortAux;
1624 
1625  Context = ctx;
1626  OptAttachMsg = true;
1627  mutt_message(_("Tag the messages you want to attach"));
1628  op_close = mutt_index_menu();
1629  OptAttachMsg = false;
1630 
1631  if (!Context)
1632  {
1633  /* go back to the folder we started from */
1634  Context = ctx_cur;
1635  /* Restore old $sort and $sort_aux */
1636  C_Sort = old_sort;
1637  C_SortAux = old_sort_aux;
1638  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1639  break;
1640  }
1641 
1642  for (int i = 0; i < Context->mailbox->msg_count; i++)
1643  {
1644  if (!message_is_tagged(Context, i))
1645  continue;
1646 
1647  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1649  Context->mailbox->emails[i], true);
1650  if (ap->content)
1651  update_idx(menu, actx, ap);
1652  else
1653  {
1654  mutt_error(_("Unable to attach"));
1655  FREE(&ap);
1656  }
1657  }
1658  menu->redraw |= REDRAW_FULL;
1659 
1660  if (op_close == OP_QUIT)
1662  else
1663  {
1665  ctx_free(&Context);
1666  }
1667 
1668  /* go back to the folder we started from */
1669  Context = ctx_cur;
1670  /* Restore old $sort and $sort_aux */
1671  C_Sort = old_sort;
1672  C_SortAux = old_sort_aux;
1674  break;
1675  }
1676 
1677  case OP_DELETE:
1678  CHECK_COUNT;
1679  if (CUR_ATTACH->unowned)
1680  CUR_ATTACH->content->unlink = false;
1681  if (delete_attachment(actx, menu->current) == -1)
1682  break;
1683  mutt_update_compose_menu(actx, menu, false);
1684  if (menu->current == 0)
1685  e->content = actx->idx[0]->content;
1686 
1688  break;
1689 
1690  case OP_COMPOSE_TOGGLE_RECODE:
1691  {
1692  CHECK_COUNT;
1693  if (!mutt_is_text_part(CUR_ATTACH->content))
1694  {
1695  mutt_error(_("Recoding only affects text attachments"));
1696  break;
1697  }
1698  CUR_ATTACH->content->noconv = !CUR_ATTACH->content->noconv;
1699  if (CUR_ATTACH->content->noconv)
1700  mutt_message(_("The current attachment won't be converted"));
1701  else
1702  mutt_message(_("The current attachment will be converted"));
1703  menu->redraw = REDRAW_CURRENT;
1705  break;
1706  }
1707 
1708  case OP_COMPOSE_EDIT_DESCRIPTION:
1709  CHECK_COUNT;
1711  buf, CUR_ATTACH->content->description ? CUR_ATTACH->content->description : "",
1712  sizeof(buf));
1713  /* header names should not be translated */
1714  if (mutt_get_field("Description: ", buf, sizeof(buf), 0) == 0)
1715  {
1716  mutt_str_replace(&CUR_ATTACH->content->description, buf);
1717  menu->redraw = REDRAW_CURRENT;
1718  }
1720  break;
1721 
1722  case OP_COMPOSE_UPDATE_ENCODING:
1723  CHECK_COUNT;
1724  if (menu->tagprefix)
1725  {
1726  struct Body *top = NULL;
1727  for (top = e->content; top; top = top->next)
1728  {
1729  if (top->tagged)
1730  mutt_update_encoding(top);
1731  }
1732  menu->redraw = REDRAW_FULL;
1733  }
1734  else
1735  {
1736  mutt_update_encoding(CUR_ATTACH->content);
1738  }
1740  break;
1741 
1742  case OP_COMPOSE_TOGGLE_DISPOSITION:
1743  /* toggle the content-disposition between inline/attachment */
1744  CUR_ATTACH->content->disposition =
1745  (CUR_ATTACH->content->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
1746  menu->redraw = REDRAW_CURRENT;
1747  break;
1748 
1749  case OP_EDIT_TYPE:
1750  CHECK_COUNT;
1751  {
1752  mutt_edit_content_type(NULL, CUR_ATTACH->content, NULL);
1753 
1754  /* this may have been a change to text/something */
1755  mutt_update_encoding(CUR_ATTACH->content);
1756 
1757  menu->redraw = REDRAW_CURRENT;
1758  }
1760  break;
1761 
1762  case OP_COMPOSE_EDIT_LANGUAGE:
1763  CHECK_COUNT;
1764  buf[0] = '\0'; /* clear buffer first */
1765  if (CUR_ATTACH->content->language)
1766  mutt_str_strfcpy(buf, CUR_ATTACH->content->language, sizeof(buf));
1767  if (mutt_get_field("Content-Language: ", buf, sizeof(buf), 0) == 0)
1768  {
1769  CUR_ATTACH->content->language = mutt_str_strdup(buf);
1771  mutt_clear_error();
1772  }
1773  else
1774  mutt_warning(_("Empty 'Content-Language'"));
1776  break;
1777 
1778  case OP_COMPOSE_EDIT_ENCODING:
1779  CHECK_COUNT;
1780  mutt_str_strfcpy(buf, ENCODING(CUR_ATTACH->content->encoding), sizeof(buf));
1781  if ((mutt_get_field("Content-Transfer-Encoding: ", buf, sizeof(buf), 0) == 0) &&
1782  (buf[0] != '\0'))
1783  {
1784  int enc = mutt_check_encoding(buf);
1785  if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1786  {
1787  CUR_ATTACH->content->encoding = enc;
1789  mutt_clear_error();
1790  }
1791  else
1792  mutt_error(_("Invalid encoding"));
1793  }
1795  break;
1796 
1797  case OP_COMPOSE_SEND_MESSAGE:
1798  /* Note: We don't invoke send2-hook here, since we want to leave
1799  * users an opportunity to change settings from the ":" prompt. */
1800  if (check_attachments(actx) != 0)
1801  {
1802  menu->redraw = REDRAW_FULL;
1803  break;
1804  }
1805 
1806 #ifdef MIXMASTER
1807  if (!STAILQ_EMPTY(&e->chain) && (mix_check_message(e) != 0))
1808  break;
1809 #endif
1810 
1811  if (!fcc_set && *fcc)
1812  {
1813  enum QuadOption ans =
1814  query_quadoption(C_Copy, _("Save a copy of this message?"));
1815  if (ans == MUTT_ABORT)
1816  break;
1817  else if (ans == MUTT_NO)
1818  *fcc = '\0';
1819  }
1820 
1821  loop = false;
1822  rc = 0;
1823  break;
1824 
1825  case OP_COMPOSE_EDIT_FILE:
1826  CHECK_COUNT;
1827  mutt_edit_file(NONULL(C_Editor), CUR_ATTACH->content->filename);
1828  mutt_update_encoding(CUR_ATTACH->content);
1831  break;
1832 
1833  case OP_COMPOSE_TOGGLE_UNLINK:
1834  CHECK_COUNT;
1835  CUR_ATTACH->content->unlink = !CUR_ATTACH->content->unlink;
1836 
1837  menu->redraw = REDRAW_INDEX;
1838  /* No send2hook since this doesn't change the message. */
1839  break;
1840 
1841  case OP_COMPOSE_GET_ATTACHMENT:
1842  CHECK_COUNT;
1843  if (menu->tagprefix)
1844  {
1845  for (struct Body *top = e->content; top; top = top->next)
1846  {
1847  if (top->tagged)
1849  }
1850  menu->redraw = REDRAW_FULL;
1851  }
1852  else if (mutt_get_tmp_attachment(CUR_ATTACH->content) == 0)
1853  menu->redraw = REDRAW_CURRENT;
1854 
1855  /* No send2hook since this doesn't change the message. */
1856  break;
1857 
1858  case OP_COMPOSE_RENAME_ATTACHMENT:
1859  {
1860  CHECK_COUNT;
1861  char *src = NULL;
1862  if (CUR_ATTACH->content->d_filename)
1863  src = CUR_ATTACH->content->d_filename;
1864  else
1865  src = CUR_ATTACH->content->filename;
1866  mutt_str_strfcpy(buf, mutt_path_basename(NONULL(src)), sizeof(buf));
1867  int ret = mutt_get_field(_("Send attachment with name: "), buf, sizeof(buf), MUTT_FILE);
1868  if (ret == 0)
1869  {
1870  /* As opposed to RENAME_FILE, we don't check buf[0] because it's
1871  * valid to set an empty string here, to erase what was set */
1872  mutt_str_replace(&CUR_ATTACH->content->d_filename, buf);
1873  menu->redraw = REDRAW_CURRENT;
1874  }
1875  break;
1876  }
1877 
1878  case OP_COMPOSE_RENAME_FILE:
1879  CHECK_COUNT;
1880  mutt_str_strfcpy(buf, CUR_ATTACH->content->filename, sizeof(buf));
1881  mutt_pretty_mailbox(buf, sizeof(buf));
1882  if ((mutt_get_field(_("Rename to: "), buf, sizeof(buf), MUTT_FILE) == 0) &&
1883  (buf[0] != '\0'))
1884  {
1885  struct stat st;
1886  if (stat(CUR_ATTACH->content->filename, &st) == -1)
1887  {
1888  /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
1889  mutt_error(_("Can't stat %s: %s"), buf, strerror(errno));
1890  break;
1891  }
1892 
1893  mutt_expand_path(buf, sizeof(buf));
1894  if (mutt_file_rename(CUR_ATTACH->content->filename, buf))
1895  break;
1896 
1897  mutt_str_replace(&CUR_ATTACH->content->filename, buf);
1898  menu->redraw = REDRAW_CURRENT;
1899 
1900  if (CUR_ATTACH->content->stamp >= st.st_mtime)
1902  }
1904  break;
1905 
1906  case OP_COMPOSE_NEW_MIME:
1907  {
1908  buf[0] = '\0';
1909  if ((mutt_get_field(_("New file: "), buf, sizeof(buf), MUTT_FILE) != 0) ||
1910  (buf[0] == '\0'))
1911  {
1912  continue;
1913  }
1914  mutt_expand_path(buf, sizeof(buf));
1915 
1916  /* Call to lookup_mime_type () ? maybe later */
1917  char type[256] = { 0 };
1918  if ((mutt_get_field("Content-Type: ", type, sizeof(type), 0) != 0) ||
1919  (type[0] == '\0'))
1920  {
1921  continue;
1922  }
1923 
1924  char *p = strchr(type, '/');
1925  if (!p)
1926  {
1927  mutt_error(_("Content-Type is of the form base/sub"));
1928  continue;
1929  }
1930  *p++ = 0;
1931  enum ContentType itype = mutt_check_mime_type(type);
1932  if (itype == TYPE_OTHER)
1933  {
1934  mutt_error(_("Unknown Content-Type %s"), type);
1935  continue;
1936  }
1937  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1938  /* Touch the file */
1939  FILE *fp = mutt_file_fopen(buf, "w");
1940  if (!fp)
1941  {
1942  mutt_error(_("Can't create file %s"), buf);
1943  FREE(&ap);
1944  continue;
1945  }
1946  mutt_file_fclose(&fp);
1947 
1948  ap->content = mutt_make_file_attach(buf);
1949  if (!ap->content)
1950  {
1951  mutt_error(_("What we have here is a failure to make an attachment"));
1952  FREE(&ap);
1953  continue;
1954  }
1955  update_idx(menu, actx, ap);
1956 
1957  CUR_ATTACH->content->type = itype;
1958  mutt_str_replace(&CUR_ATTACH->content->subtype, p);
1959  CUR_ATTACH->content->unlink = true;
1960  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1961 
1962  if (mutt_compose_attachment(CUR_ATTACH->content))
1963  {
1964  mutt_update_encoding(CUR_ATTACH->content);
1965  menu->redraw = REDRAW_FULL;
1966  }
1968  break;
1969  }
1970 
1971  case OP_COMPOSE_EDIT_MIME:
1972  CHECK_COUNT;
1973  if (mutt_edit_attachment(CUR_ATTACH->content))
1974  {
1975  mutt_update_encoding(CUR_ATTACH->content);
1976  menu->redraw = REDRAW_FULL;
1977  }
1979  break;
1980 
1981  case OP_VIEW_ATTACH:
1982  case OP_DISPLAY_HEADERS:
1983  CHECK_COUNT;
1984  mutt_attach_display_loop(menu, op, NULL, actx, false);
1985  menu->redraw = REDRAW_FULL;
1986  /* no send2hook, since this doesn't modify the message */
1987  break;
1988 
1989  case OP_SAVE:
1990  CHECK_COUNT;
1991  mutt_save_attachment_list(actx, NULL, menu->tagprefix,
1992  CUR_ATTACH->content, NULL, menu);
1993  /* no send2hook, since this doesn't modify the message */
1994  break;
1995 
1996  case OP_PRINT:
1997  CHECK_COUNT;
1998  mutt_print_attachment_list(actx, NULL, menu->tagprefix, CUR_ATTACH->content);
1999  /* no send2hook, since this doesn't modify the message */
2000  break;
2001 
2002  case OP_PIPE:
2003  case OP_FILTER:
2004  CHECK_COUNT;
2005  mutt_pipe_attachment_list(actx, NULL, menu->tagprefix,
2006  CUR_ATTACH->content, (op == OP_FILTER));
2007  if (op == OP_FILTER) /* cte might have changed */
2008  menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
2009  menu->redraw |= REDRAW_STATUS;
2011  break;
2012 
2013  case OP_EXIT:
2014  {
2015  enum QuadOption ans =
2016  query_quadoption(C_Postpone, _("Save (postpone) draft message?"));
2017  if (ans == MUTT_NO)
2018  {
2019  for (int i = 0; i < actx->idxlen; i++)
2020  if (actx->idx[i]->unowned)
2021  actx->idx[i]->content->unlink = false;
2022 
2023  if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
2024  {
2025  for (int i = 0; i < actx->idxlen; i++)
2026  {
2027  /* avoid freeing other attachments */
2028  actx->idx[i]->content->next = NULL;
2029  actx->idx[i]->content->parts = NULL;
2030  mutt_body_free(&actx->idx[i]->content);
2031  }
2032  }
2033  rc = -1;
2034  loop = false;
2035  break;
2036  }
2037  else if (ans == MUTT_ABORT)
2038  break; /* abort */
2039  }
2040  /* fallthrough */
2041 
2042  case OP_COMPOSE_POSTPONE_MESSAGE:
2043  if (check_attachments(actx) != 0)
2044  {
2045  menu->redraw = REDRAW_FULL;
2046  break;
2047  }
2048 
2049  loop = false;
2050  rc = 1;
2051  break;
2052 
2053  case OP_COMPOSE_ISPELL:
2054  endwin();
2055  snprintf(buf, sizeof(buf), "%s -x %s", NONULL(C_Ispell), e->content->filename);
2056  if (mutt_system(buf) == -1)
2057  mutt_error(_("Error running \"%s\""), buf);
2058  else
2059  {
2061  menu->redraw |= REDRAW_STATUS;
2062  }
2063  break;
2064 
2065  case OP_COMPOSE_WRITE_MESSAGE:
2066  buf[0] = '\0';
2067  if (Context)
2068  {
2069  mutt_str_strfcpy(buf, mailbox_path(Context->mailbox), sizeof(buf));
2070  mutt_pretty_mailbox(buf, sizeof(buf));
2071  }
2072  if (actx->idxlen)
2073  e->content = actx->idx[0]->content;
2074  if ((mutt_enter_fname(_("Write message to mailbox"), buf, sizeof(buf), true) != -1) &&
2075  (buf[0] != '\0'))
2076  {
2077  mutt_message(_("Writing message to %s ..."), buf);
2078  mutt_expand_path(buf, sizeof(buf));
2079 
2080  if (e->content->next)
2082 
2083  if (mutt_write_fcc(buf, e, NULL, false, NULL, NULL) < 0)
2085  else
2086  mutt_message(_("Message written"));
2087  }
2088  break;
2089 
2090  case OP_COMPOSE_PGP_MENU:
2091  if (!(WithCrypto & APPLICATION_PGP))
2092  break;
2093  if (!crypt_has_module_backend(APPLICATION_PGP))
2094  {
2095  mutt_error(_("No PGP backend configured"));
2096  break;
2097  }
2098  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
2099  {
2100  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2101  {
2102  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2103  {
2104  mutt_clear_error();
2105  break;
2106  }
2107  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2108  }
2109  e->security &= ~APPLICATION_SMIME;
2110  e->security |= APPLICATION_PGP;
2111  update_crypt_info(rd);
2112  }
2113  e->security = crypt_pgp_send_menu(e);
2114  update_crypt_info(rd);
2116  break;
2117 
2118  case OP_FORGET_PASSPHRASE:
2120  break;
2121 
2122  case OP_COMPOSE_SMIME_MENU:
2123  if (!(WithCrypto & APPLICATION_SMIME))
2124  break;
2125  if (!crypt_has_module_backend(APPLICATION_SMIME))
2126  {
2127  mutt_error(_("No S/MIME backend configured"));
2128  break;
2129  }
2130 
2131  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
2132  {
2133  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2134  {
2135  if (mutt_yesorno(_("PGP already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2136  {
2137  mutt_clear_error();
2138  break;
2139  }
2140  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2141  }
2142  e->security &= ~APPLICATION_PGP;
2144  update_crypt_info(rd);
2145  }
2147  update_crypt_info(rd);
2149  break;
2150 
2151 #ifdef MIXMASTER
2152  case OP_COMPOSE_MIX:
2153  mix_make_chain(&e->chain);
2155  break;
2156 #endif
2157 #ifdef USE_AUTOCRYPT
2158  case OP_COMPOSE_AUTOCRYPT_MENU:
2159  if (!C_Autocrypt)
2160  break;
2161 
2162  if ((WithCrypto & APPLICATION_SMIME) && (e->security & APPLICATION_SMIME))
2163  {
2164  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2165  {
2166  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2167  {
2168  mutt_clear_error();
2169  break;
2170  }
2171  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2172  }
2173  e->security &= ~APPLICATION_SMIME;
2174  e->security |= APPLICATION_PGP;
2175  update_crypt_info(rd);
2176  }
2178  update_crypt_info(rd);
2180  break;
2181 #endif
2182  }
2183  }
2184 
2185 #ifdef USE_AUTOCRYPT
2186  /* This is a fail-safe to make sure the bit isn't somehow turned
2187  * on. The user could have disabled the option after setting SEC_AUTOCRYPT,
2188  * or perhaps resuming or replying to an autocrypt message. */
2189  if (!C_Autocrypt)
2190  e->security &= ~SEC_AUTOCRYPT;
2191 #endif
2192 
2193  mutt_menu_pop_current(menu);
2194  mutt_menu_free(&menu);
2195 
2196  if (actx->idxlen)
2197  e->content = actx->idx[0]->content;
2198  else
2199  e->content = NULL;
2200 
2201  mutt_actx_free(&actx);
2202 
2203  return rc;
2204 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
struct NntpAccountData * nntp_select_server(struct Mailbox *m, char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:982
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1486
static int delete_attachment(struct AttachCtx *actx, int x)
Delete an attachment.
Definition: compose.c:730
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1418
Unknown Content-Type.
Definition: mime.h:31
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
void mutt_actx_free(struct AttachCtx **ptr)
Free an Attachment Context.
Definition: attach.c:140
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:205
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
An email to which things will be attached.
Definition: attach.h:34
int mutt_attach_display_loop(struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
Event loop for the Attachment menu.
Definition: recvattach.c:1146
int msg_count
Total number of messages.
Definition: mailbox.h:102
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1742
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:70
#define mutt_perror(...)
Definition: logging.h:85
GUI selectable list of items.
Definition: mutt_menu.h:82
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2425
struct ConnAccount account
Definition: connection.h:36
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:558
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3331
#define mutt_message(...)
Definition: logging.h:83
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1332
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
static void compose_custom_redraw(struct Menu *menu)
Redraw the compose menu - Implements Menu::menu_custom_redraw()
Definition: compose.c:844
static void edit_address_list(int line, struct AddressList *al, struct ComposeRedrawData *rd)
Let the user edit the address list.
Definition: compose.c:695
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
Definition: recvattach.c:651
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
"To:" field
Definition: compose.c:119
struct Body * content
List of MIME parts.
Definition: email.h:92
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:105
"Cc:" field
Definition: compose.c:120
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:254
#define _(a)
Definition: message.h:28
static void update_crypt_info(struct ComposeRedrawData *rd)
Update the crypto info.
Definition: compose.c:490
struct Body * next
next attachment in the list
Definition: body.h:53
short idxlen
Number of attachmentes.
Definition: attach.h:55
Compose an email.
Definition: keymap.h:64
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:254
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:186
struct Email * email
Definition: compose.c:249
char * C_Ispell
Config: External command to perform spell-checking.
Definition: compose.c:94
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:53
"Subject:" field
Definition: compose.c:122
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope&#39;s Address fields to Punycode format.
Definition: envelope.c:312
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
static int check_attachments(struct AttachCtx *actx)
Check if any attachments have changed or been deleted.
Definition: compose.c:574
"From:" field
Definition: compose.c:118
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1173
static void snd_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the attachment list - Implements Menu::menu_make_entry()
Definition: compose.c:314
#define CUR_ATTACH
Definition: compose.c:109
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
void * redraw_data
Definition: mutt_menu.h:150
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1029
int mutt_get_tmp_attachment(struct Body *a)
Get a temporary copy of an attachment.
Definition: mutt_attach.c:65
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:217
struct Mailbox * mailbox
Definition: context.h:50
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
int mutt_enter_fname_full(const char *prompt, char *buf, size_t buflen, bool mailbox, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:626
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: sendlib.c:604
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1620
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:55
enum ContentType mutt_check_mime_type(const char *s)
Check a MIME type string.
Definition: parse.c:317
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:528
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1455
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
struct Envelope * env
Envelope information.
Definition: email.h:91
#define ENCODING(x)
Definition: mime.h:85
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:392
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
Content is attached.
Definition: mime.h:63
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:307
static void compose_attach_swap(struct Body *msg, struct AttachPtr **idx, short first)
Swap two adjacent entries in the attachment list.
Definition: compose.c:893
void(* menu_custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:149
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition: attach.c:131
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:109
bool unowned
Don&#39;t unlink on detach.
Definition: attach.h:42
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1716
char * subtype
content-type subtype
Definition: body.h:37
WHERE char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: globals.h:134
static const struct Mapping ComposeHelp[]
Definition: compose.c:191
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
WHERE short C_SortAux
Config: Secondary sort method for the index.
Definition: sort.h:59
#define HDR_XOFFSET
Definition: compose.c:145
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE struct Context * Context
Definition: globals.h:42
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:447
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:54
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
int mutt_check_encoding(const char *c)
Check the encoding type.
Definition: parse.c:426
#define ALTS_TAG
A mailbox.
Definition: mailbox.h:92
#define PATH_MAX
Definition: mutt.h:52
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
bool tagprefix
Definition: mutt_menu.h:93
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:373
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
void mix_make_chain(struct ListHead *chainhead)
Create a Mixmaster chain.
Definition: remailer.c:563
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:801
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:612
char * description
content-description
Definition: body.h:40
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:433
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
#define W
Definition: compose.c:146
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:46
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
static struct Mapping ComposeNewsHelp[]
Definition: compose.c:207
int tagged
Number of tagged entries.
Definition: mutt_menu.h:111
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:549
#define MUTT_FILE
Do file completion.
Definition: mutt.h:66
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
unsigned int type
content-type primary type
Definition: body.h:65
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:137
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
"Bcc:" field
Definition: compose.c:121
#define LINGUAL_TAG
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:159
static void update_idx(struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
Add a new attchment to the message.
Definition: compose.c:830
struct Connection * conn
Definition: nntp.h:102
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
Definition: recvattach.c:879
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:274
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:295
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
int offset
Row offset within the window to start the index.
Definition: mutt_menu.h:91
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct MuttWindow * win
Definition: compose.c:255
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:56
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:294
struct Body * content
Attachment.
Definition: attach.h:36
unsigned char C_Postpone
Config: Save messages to the C_Postponed folder.
Definition: compose.c:95
#define mutt_error(...)
Definition: logging.h:84
int mutt_builtin_editor(const char *path, struct Email *e_new, struct Email *e_cur)
Show the user the built-in editor.
Definition: edit.c:402
enum MailboxType pop_path_probe(const char *path, const struct stat *st)
Is this a POP Mailbox? - Implements MxOps::path_probe()
Definition: pop.c:1231
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
static void autocrypt_compose_menu(struct Email *e)
Autocrypt compose settings.
Definition: compose.c:328
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:114
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, char *fcc, size_t fcclen)
Let the user edit the message header and body.
Definition: mutt_header.c:168
#define mutt_enter_fname(prompt, buf, buflen, mailbox)
Definition: curs_lib.h:85
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1539
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:36
#define STAILQ_EMPTY(head)
Definition: queue.h:346
Where to start printing the attachments.
Definition: compose.c:139
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: compose.c:283
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:48
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2825
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1216
int current
Current entry.
Definition: mutt_menu.h:87
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
"Fcc:" (save folder) field
Definition: compose.c:124
#define CHECK_COUNT
Definition: compose.c:102
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
int mutt_index_menu(void)
Display a list of emails.
Definition: index.c:1034
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
#define WithCrypto
Definition: ncrypt.h:160
A set of attachments.
Definition: attach.h:49
Encoding unknown.
Definition: mime.h:48
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:308
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
Keep track when the compose screen needs redrawing.
Definition: compose.c:247
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
UUEncoded text.
Definition: mime.h:54
bool message_is_tagged(struct Context *ctx, int index)
Is a message in the index tagged (and within limit)
Definition: context.c:343
#define REDRAW_CURRENT
Redraw the current line of the menu.
Definition: mutt_menu.h:45
int mutt_compose_attachment(struct Body *a)
Create an attachment.
Definition: mutt_attach.c:115
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:780
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:75
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
ContentType
Content-Type.
Definition: mime.h:29
"Reply-To:" field
Definition: compose.c:123
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3246
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ComposeFormat

char* C_ComposeFormat

Config: printf-like format string for the Compose panel's status bar.

Definition at line 93 of file compose.c.

◆ C_Ispell

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 94 of file compose.c.

◆ C_Postpone

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 95 of file compose.c.