NeoMutt  2018-07-16 +2388-bcedc8
Teaching an old dog new tricks
DOXYGEN
compose.c File Reference

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

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/conn.h"
#include "mutt.h"
#include "compose.h"
#include "alias.h"
#include "browser.h"
#include "commands.h"
#include "context.h"
#include "curs_lib.h"
#include "edit.h"
#include "format_flags.h"
#include "globals.h"
#include "hook.h"
#include "index.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_curses.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "recvattach.h"
#include "sendlib.h"
#include "sort.h"
#include <libintl.h>
#include "nntp/nntp.h"
#include "pop/pop.h"
#include "imap/imap.h"
#include "autocrypt/autocrypt.h"
+ Include dependency graph for compose.c:

Go to the source code of this file.

Data Structures

struct  ComposeRedrawData
 Keep track when the compose screen needs redrawing. More...
 

Macros

#define CHECK_COUNT
 
#define CUR_ATTACH   actx->idx[actx->v2r[menu->current]]
 
#define HDR_XOFFSET   MaxHeaderWidth
 
#define W   (MuttIndexWindow->cols - MaxHeaderWidth)
 
#define ALTS_TAG   "Alternatives for \"%s\""
 
#define LINGUAL_TAG   "Multilingual part for \"%s\""
 

Enumerations

enum  HeaderField {
  HDR_FROM = 0, HDR_TO, HDR_CC, HDR_BCC,
  HDR_SUBJECT, HDR_REPLYTO, HDR_FCC, HDR_CRYPT,
  HDR_CRYPTINFO, HDR_AUTOCRYPT, HDR_NEWSGROUPS, HDR_FOLLOWUPTO,
  HDR_XCOMMENTTO, HDR_ATTACH_TITLE, HDR_ATTACH
}
 Ordered list of headers for the compose screen. More...
 

Functions

static void calc_header_width_padding (int idx, const char *header, bool calc_max)
 Calculate the width needed for the compose labels. More...
 
static void init_header_padding (void)
 Calculate how much padding the compose table will need. More...
 
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() More...
 
static void autocrypt_compose_menu (struct Email *e)
 Autocrypt compose settings. More...
 
static void redraw_crypt_lines (struct ComposeRedrawData *rd)
 Update the encryption info in the compose window. More...
 
static void update_crypt_info (struct ComposeRedrawData *rd)
 Update the crypto info. More...
 
static int check_attachments (struct AttachCtx *actx)
 Check if any attachments have changed or been deleted. More...
 
static void draw_envelope_addr (int line, struct AddressList *al)
 Write addresses to the compose window. More...
 
static void draw_envelope (struct ComposeRedrawData *rd)
 Write the email headers to the compose window. More...
 
static void edit_address_list (int line, struct AddressList *al)
 Let the user edit the address list. More...
 
static int delete_attachment (struct AttachCtx *actx, int x)
 Delete an attachment. More...
 
static void mutt_gen_compose_attach_list (struct AttachCtx *actx, struct Body *m, int parent_type, int level)
 Generate the attachment list for the compose screen. More...
 
static void mutt_update_compose_menu (struct AttachCtx *actx, struct Menu *menu, bool init)
 Redraw the compose window. More...
 
static void update_idx (struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
 Add a new attchment to the message. More...
 
static void compose_status_line (char *buf, size_t buflen, size_t col, int cols, struct Menu *menu, const char *src)
 Compose the string for the status bar. More...
 
static void compose_custom_redraw (struct Menu *menu)
 Redraw the compose menu - Implements Menu::menu_custom_redraw() More...
 
static void compose_attach_swap (struct Body *msg, struct AttachPtr **idx, short first)
 Swap two adjacent entries in the attachment list. More...
 
static unsigned long cum_attachs_size (struct Menu *menu)
 Cumulative Attachments Size. More...
 
static const char * compose_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
 Create the status bar string for compose mode - Implements format_t. More...
 
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...
 
static const char * There_are_no_attachments = N_("There are no attachments")
 
int HeaderPadding [HDR_ATTACH_TITLE] = { 0 }
 
int MaxHeaderWidth = 0
 
static const char *const Prompts []
 
static const struct Mapping ComposeHelp []
 
static struct Mapping ComposeNewsHelp []
 
static const char * AutocryptRecUiFlags []
 

Detailed Description

GUI editor for an email's headers.

Authors
  • Michael R. Elkins
  • g10 Code GmbH
  • Pietro Cerutti

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.c.

Macro Definition Documentation

#define CHECK_COUNT
Value:
if (actx->idxlen == 0) \
{ \
break; \
}
static const char * There_are_no_attachments
Definition: compose.c:97
#define _(a)
Definition: message.h:28
#define mutt_error(...)
Definition: logging.h:84

Definition at line 99 of file compose.c.

#define CUR_ATTACH   actx->idx[actx->v2r[menu->current]]

Definition at line 106 of file compose.c.

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 142 of file compose.c.

#define W   (MuttIndexWindow->cols - MaxHeaderWidth)

Definition at line 143 of file compose.c.

#define ALTS_TAG   "Alternatives for \"%s\""
#define LINGUAL_TAG   "Multilingual part for \"%s\""

Enumeration Type Documentation

Ordered list of headers for the compose screen.

The position of various fields on the compose screen.

Enumerator
HDR_FROM 

"From:" field

HDR_TO 

"To:" field

HDR_CC 

"Cc:" field

HDR_BCC 

"Bcc:" field

HDR_SUBJECT 

"Subject:" field

HDR_REPLYTO 

"Reply-To:" field

HDR_FCC 

"Fcc:" (save folder) field

HDR_CRYPT 

"Security:" field (encryption/signing info)

HDR_CRYPTINFO 

"Sign as:" field (encryption/signing info)

HDR_AUTOCRYPT 
HDR_NEWSGROUPS 

"Newsgroups:" field

HDR_FOLLOWUPTO 

"Followup-To:" field

HDR_XCOMMENTTO 

"X-Comment-To:" field

HDR_ATTACH_TITLE 

The "-- Attachments" line.

HDR_ATTACH 

Where to start printing the attachments.

Definition at line 113 of file compose.c.

114 {
115  HDR_FROM = 0,
116  HDR_TO,
117  HDR_CC,
118  HDR_BCC,
119  HDR_SUBJECT,
120  HDR_REPLYTO,
121  HDR_FCC,
122 #ifdef MIXMASTER
123  HDR_MIX,
124 #endif
125  HDR_CRYPT,
126  HDR_CRYPTINFO,
127 #ifdef USE_AUTOCRYPT
129 #endif
130 #ifdef USE_NNTP
134 #endif
136  HDR_ATTACH
137 };
"To:" field
Definition: compose.c:116
"Cc:" field
Definition: compose.c:117
"Subject:" field
Definition: compose.c:119
"Sign as:" field (encryption/signing info)
Definition: compose.c:126
"From:" field
Definition: compose.c:115
The "-- Attachments" line.
Definition: compose.c:135
"X-Comment-To:" field
Definition: compose.c:133
"Security:" field (encryption/signing info)
Definition: compose.c:125
"Bcc:" field
Definition: compose.c:118
"Followup-To:" field
Definition: compose.c:132
Where to start printing the attachments.
Definition: compose.c:136
"Newsgroups:" field
Definition: compose.c:131
"Fcc:" (save folder) field
Definition: compose.c:121
"Reply-To:" field
Definition: compose.c:120

Function Documentation

static void calc_header_width_padding ( int  idx,
const char *  header,
bool  calc_max 
)
static

Calculate the width needed for the compose labels.

Parameters
idxStore the result at this index of HeaderPadding
headerHeader string
calc_maxIf true, calculate the maximum width

Definition at line 260 of file compose.c.

261 {
262  int width;
263 
264  HeaderPadding[idx] = mutt_str_strlen(header);
265  width = mutt_strwidth(header);
266  if (calc_max && (MaxHeaderWidth < width))
267  MaxHeaderWidth = width;
268  HeaderPadding[idx] -= width;
269 }
int MaxHeaderWidth
Definition: compose.c:140
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1262
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:139

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void init_header_padding ( void  )
static

Calculate how much padding the compose table will need.

The padding needed for each header is strlen() + max_width - strwidth().

calc_header_width_padding sets each entry in HeaderPadding to strlen - width. Then, afterwards, we go through and add max_width to each entry.

Definition at line 279 of file compose.c.

280 {
281  static bool done = false;
282 
283  if (done)
284  return;
285  done = true;
286 
287  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
288  {
289  if (i == HDR_CRYPTINFO)
290  continue;
291  calc_header_width_padding(i, _(Prompts[i]), true);
292  }
293 
294  /* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
295  * doesn't show up by default, and so can make the indentation of
296  * the other fields look funny. */
298 
299  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
300  {
302  if (HeaderPadding[i] < 0)
303  HeaderPadding[i] = 0;
304  }
305 }
static void calc_header_width_padding(int idx, const char *header, bool calc_max)
Calculate the width needed for the compose labels.
Definition: compose.c:260
int MaxHeaderWidth
Definition: compose.c:140
#define _(a)
Definition: message.h:28
"Sign as:" field (encryption/signing info)
Definition: compose.c:126
The "-- Attachments" line.
Definition: compose.c:135
static const char *const Prompts[]
Definition: compose.c:145
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:139

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void snd_make_entry ( char *  buf,
size_t  buflen,
struct Menu menu,
int  line 
)
static

Format a menu item for the attachment list - Implements Menu::menu_make_entry()

Definition at line 310 of file compose.c.

311 {
312  struct AttachCtx *actx = menu->data;
313 
315  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
317 }
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:838
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:103
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
const char * line
Definition: common.c:36
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
const char * attach_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:210
void * data
extra data for the current menu
Definition: mutt_menu.h:86
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void autocrypt_compose_menu ( struct Email e)
static

Autocrypt compose settings.

Parameters
eEmail

Definition at line 324 of file compose.c.

325 {
326  /* L10N:
327  The compose menu autocrypt prompt.
328  (e)ncrypt enables encryption via autocrypt.
329  (c)lear sets cleartext.
330  (a)utomatic defers to the recommendation.
331  */
332  const char *prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic?");
333 
334  /* L10N:
335  The letter corresponding to the compose menu autocrypt prompt
336  (e)ncrypt, (c)lear, (a)utomatic
337  */
338  const char *letters = _("eca");
339 
340  int choice = mutt_multi_choice(prompt, letters);
341  switch (choice)
342  {
343  case 1:
346  break;
347  case 2:
348  e->security &= ~SEC_AUTOCRYPT;
350  break;
351  case 3:
354  e->security |= SEC_OPPENCRYPT;
355  break;
356  }
357 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:839
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:284
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 SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void redraw_crypt_lines ( struct ComposeRedrawData rd)
static

Update the encryption info in the compose window.

Parameters
rdEmail and other compose data

Definition at line 364 of file compose.c.

365 {
366  struct Email *e = rd->email;
367 
370  HeaderPadding[HDR_CRYPT], _(Prompts[HDR_CRYPT]));
371  NORMAL_COLOR;
372 
374  {
375  addstr(_("Not supported"));
376  return;
377  }
378 
379  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
380  {
382  addstr(_("Sign, Encrypt"));
383  }
384  else if (e->security & SEC_ENCRYPT)
385  {
387  addstr(_("Encrypt"));
388  }
389  else if (e->security & SEC_SIGN)
390  {
392  addstr(_("Sign"));
393  }
394  else
395  {
396  /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
398  addstr(_("None"));
399  }
400  NORMAL_COLOR;
401 
402  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
403  {
404  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
405  {
406  if ((e->security & SEC_INLINE))
407  addstr(_(" (inline PGP)"));
408  else
409  addstr(_(" (PGP/MIME)"));
410  }
411  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
412  addstr(_(" (S/MIME)"));
413  }
414 
416  addstr(_(" (OppEnc mode)"));
417 
421 
422  if (((WithCrypto & APPLICATION_PGP) != 0) &&
423  (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
424  {
426  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
427  NORMAL_COLOR;
428  printw("%s", C_PgpSignAs ? C_PgpSignAs : _("<default>"));
429  }
430 
431  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
432  (e->security & APPLICATION_SMIME) && (e->security & SEC_SIGN))
433  {
435  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
436  NORMAL_COLOR;
437  printw("%s", C_SmimeSignAs ? C_SmimeSignAs : _("<default>"));
438  }
439 
440  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
442  {
444  mutt_window_mvprintw(MuttIndexWindow, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
445  NORMAL_COLOR;
446  printw("%s", NONULL(C_SmimeEncryptWith));
447  }
448 
449 #ifdef USE_AUTOCRYPT
452  if (C_Autocrypt)
453  {
455  printw("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
456  NORMAL_COLOR;
457  if (e->security & SEC_AUTOCRYPT)
458  {
460  addstr(_("Encrypt"));
461  }
462  else
463  {
465  addstr(_("Off"));
466  }
467 
469  mutt_window_mvprintw(MuttIndexWindow, HDR_AUTOCRYPT, 40, "%s",
470  /* L10N:
471  The autocrypt compose menu Recommendation field.
472  Displays the output of the recommendation engine
473  (Off, No, Discouraged, Available, Yes)
474  */
475  _("Recommendation: "));
476  NORMAL_COLOR;
477  printw("%s", _(AutocryptRecUiFlags[rd->autocrypt_rec]));
478  }
479 #endif
480 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#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:209
The envelope/body of an email.
Definition: email.h:39
Mail will not be encrypted or signed.
Definition: mutt_curses.h:172
#define NORMAL_COLOR
Definition: mutt_curses.h:239
Mail will be encrypted.
Definition: mutt_curses.h:169
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
struct Email * email
Definition: compose.c:246
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
"Sign as:" field (encryption/signing info)
Definition: compose.c:126
Mail will be signed.
Definition: mutt_curses.h:170
Mail will be encrypted and signed.
Definition: mutt_curses.h:171
enum AutocryptRec autocrypt_rec
Definition: compose.c:249
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:284
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:177
"Security:" field (encryption/signing info)
Definition: compose.c:125
static const char *const Prompts[]
Definition: compose.c:145
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 SET_COLOR(X)
Definition: mutt_curses.h:224
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:139
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:217
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:172
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:176
static const char * AutocryptRecUiFlags[]
Definition: compose.c:217
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void update_crypt_info ( struct ComposeRedrawData rd)
static

Update the crypto info.

Parameters
rdEmail and other compose data

Definition at line 486 of file compose.c.

487 {
488  struct Email *e = rd->email;
489 
492 
493 #ifdef USE_AUTOCRYPT
494  if (C_Autocrypt)
495  {
497 
498  /* Anything that enables SEC_ENCRYPT or SEC_SIGN, or turns on SMIME
499  * overrides autocrypt, be it oppenc or the user having turned on
500  * those flags manually. */
503  else
504  {
505  if (!(e->security & SEC_AUTOCRYPT_OVERRIDE))
506  {
507  if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
508  {
509  e->security |= SEC_AUTOCRYPT;
510  e->security &= ~SEC_INLINE;
511  }
512  else
513  e->security &= ~SEC_AUTOCRYPT;
514  }
515  }
516  }
517 #endif
518 
519  redraw_crypt_lines(rd);
520 }
#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:209
The envelope/body of an email.
Definition: email.h:39
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
struct Email * email
Definition: compose.c:246
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
enum AutocryptRec autocrypt_rec
Definition: compose.c:249
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:284
Autocrypt should be used.
Definition: autocrypt.h:107
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
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:364
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1030
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:567
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int check_attachments ( struct AttachCtx actx)
static

Check if any attachments have changed or been deleted.

Parameters
actxAttachment context
Return values
0Success
-1Error

Definition at line 569 of file compose.c.

570 {
571  struct stat st;
572  char pretty[PATH_MAX], msg[PATH_MAX + 128];
573 
574  for (int i = 0; i < actx->idxlen; i++)
575  {
576  if (actx->idx[i]->content->type == TYPE_MULTIPART)
577  continue;
578  mutt_str_strfcpy(pretty, actx->idx[i]->content->filename, sizeof(pretty));
579  if (stat(actx->idx[i]->content->filename, &st) != 0)
580  {
581  mutt_pretty_mailbox(pretty, sizeof(pretty));
582  mutt_error(_("%s [#%d] no longer exists"), pretty, i + 1);
583  return -1;
584  }
585 
586  if (actx->idx[i]->content->stamp < st.st_mtime)
587  {
588  mutt_pretty_mailbox(pretty, sizeof(pretty));
589  snprintf(msg, sizeof(msg), _("%s [#%d] modified. Update encoding?"), pretty, i + 1);
590 
591  enum QuadOption ans = mutt_yesorno(msg, MUTT_YES);
592  if (ans == MUTT_YES)
593  mutt_update_encoding(actx->idx[i]->content);
594  else if (ans == MUTT_ABORT)
595  return -1;
596  }
597  }
598 
599  return 0;
600 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
User aborted the question (with Ctrl-G)
Definition: quad.h:37
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1455
#define PATH_MAX
Definition: mutt.h:51
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
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:612
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
time_t stamp
Time stamp of last encoding update.
Definition: body.h:61
#define mutt_error(...)
Definition: logging.h:84
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void draw_envelope_addr ( int  line,
struct AddressList *  al 
)
static

Write addresses to the compose window.

Parameters
lineLine to write to (index into Prompts)
alAddress list to write

Definition at line 607 of file compose.c.

608 {
609  char buf[1024];
610 
611  buf[0] = '\0';
612  mutt_addrlist_write(buf, sizeof(buf), al, true);
615  _(Prompts[line]));
616  NORMAL_COLOR;
617  mutt_paddstr(W, buf);
618 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#define NORMAL_COLOR
Definition: mutt_curses.h:239
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1169
const char * line
Definition: common.c:36
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
static const char *const Prompts[]
Definition: compose.c:145
#define W
Definition: compose.c:143
#define SET_COLOR(X)
Definition: mutt_curses.h:224
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:139
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:217

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void draw_envelope ( struct ComposeRedrawData rd)
static

Write the email headers to the compose window.

Parameters
rdEmail and other compose data

Definition at line 624 of file compose.c.

625 {
626  struct Email *e = rd->email;
627  char *fcc = rd->fcc;
628 
630 #ifdef USE_NNTP
631  if (!OptNewsSend)
632  {
633 #endif
637 #ifdef USE_NNTP
638  }
639  else
640  {
642  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
645  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
647  if (C_XCommentTo)
648  {
650  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
652  }
653  }
654 #endif
655 
658  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
659  NORMAL_COLOR;
661 
663 
666  HeaderPadding[HDR_FCC], _(Prompts[HDR_FCC]));
667  NORMAL_COLOR;
668  mutt_paddstr(W, fcc);
669 
670  if (WithCrypto)
671  redraw_crypt_lines(rd);
672 
673 #ifdef MIXMASTER
674  redraw_mix_line(&e->chain);
675 #endif
676 
678  mutt_window_mvaddstr(MuttIndexWindow, HDR_ATTACH_TITLE, 0, _("-- Attachments"));
680 
681  NORMAL_COLOR;
682 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#define NONULL(x)
Definition: string2.h:37
The envelope/body of an email.
Definition: email.h:39
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
#define NORMAL_COLOR
Definition: mutt_curses.h:239
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
"To:" field
Definition: compose.c:116
"Cc:" field
Definition: compose.c:117
#define _(a)
Definition: message.h:28
struct Email * email
Definition: compose.c:246
"Subject:" field
Definition: compose.c:119
"From:" field
Definition: compose.c:115
The "-- Attachments" line.
Definition: compose.c:135
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1169
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:91
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
"X-Comment-To:" field
Definition: compose.c:133
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
static void draw_envelope_addr(int line, struct AddressList *al)
Write addresses to the compose window.
Definition: compose.c:607
static const char *const Prompts[]
Definition: compose.c:145
#define SET_COLOR(X)
Definition: mutt_curses.h:224
#define W
Definition: compose.c:143
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:202
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:364
"Bcc:" field
Definition: compose.c:118
"Followup-To:" field
Definition: compose.c:132
char * subject
Email&#39;s subject.
Definition: envelope.h:66
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:298
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:139
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
Status bar.
Definition: mutt_curses.h:129
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:217
"Newsgroups:" field
Definition: compose.c:131
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
"Fcc:" (save folder) field
Definition: compose.c:121
#define WithCrypto
Definition: ncrypt.h:160
"Reply-To:" field
Definition: compose.c:120

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void edit_address_list ( int  line,
struct AddressList *  al 
)
static

Let the user edit the address list.

Parameters
[in]lineIndex into the Prompts lists
[in,out]alAddressList to edit

Definition at line 689 of file compose.c.

690 {
691  char buf[8192] = { 0 }; /* needs to be large for alias expansion */
692  char *err = NULL;
693 
695  mutt_addrlist_write(buf, sizeof(buf), al, false);
696  if (mutt_get_field(_(Prompts[line]), buf, sizeof(buf), MUTT_ALIAS) == 0)
697  {
699  mutt_addrlist_parse2(al, buf);
701  }
702 
703  if (mutt_addrlist_to_intl(al, &err) != 0)
704  {
705  mutt_error(_("Bad IDN: '%s'"), err);
706  mutt_refresh();
707  FREE(&err);
708  }
709 
710  /* redraw the expanded list so the user can see the result */
711  buf[0] = '\0';
712  mutt_addrlist_write(buf, sizeof(buf), al, true);
714  mutt_paddstr(W, buf);
715 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:289
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:64
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1295
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1378
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:603
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1169
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:94
const char * line
Definition: common.c:36
#define HDR_XOFFSET
Definition: compose.c:142
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
static const char *const Prompts[]
Definition: compose.c:145
#define W
Definition: compose.c:143
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1213
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int delete_attachment ( struct AttachCtx actx,
int  x 
)
static

Delete an attachment.

Parameters
actxAttachment context
xIndex number of attachment
Return values
0Success
-1Error

Definition at line 724 of file compose.c.

725 {
726  struct AttachPtr **idx = actx->idx;
727  int rindex = actx->v2r[x];
728 
729  if ((rindex == 0) && (actx->idxlen == 1))
730  {
731  mutt_error(_("You may not delete the only attachment"));
732  idx[rindex]->content->tagged = false;
733  return -1;
734  }
735 
736  for (int y = 0; y < actx->idxlen; y++)
737  {
738  if (idx[y]->content->next == idx[rindex]->content)
739  {
740  idx[y]->content->next = idx[rindex]->content->next;
741  break;
742  }
743  }
744 
745  idx[rindex]->content->next = NULL;
746  idx[rindex]->content->parts = NULL;
747  mutt_body_free(&(idx[rindex]->content));
748  FREE(&idx[rindex]->tree);
749  FREE(&idx[rindex]);
750  for (; rindex < actx->idxlen - 1; rindex++)
751  idx[rindex] = idx[rindex + 1];
752  idx[actx->idxlen - 1] = NULL;
753  actx->idxlen--;
754 
755  return 0;
756 }
An email to which things will be attached.
Definition: attach.h:34
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
short idxlen
Number of attachmentes.
Definition: attach.h:55
char * tree
Tree characters to display.
Definition: attach.h:39
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void mutt_gen_compose_attach_list ( struct AttachCtx actx,
struct Body m,
int  parent_type,
int  level 
)
static

Generate the attachment list for the compose screen.

Parameters
actxAttachment context
mAttachment
parent_typeAttachment type, e.g TYPE_MULTIPART
levelNesting depth of attachment

Definition at line 765 of file compose.c.

767 {
768  for (; m; m = m->next)
769  {
770  if ((m->type == TYPE_MULTIPART) && m->parts &&
772  {
774  }
775  else
776  {
777  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
778  mutt_actx_add_attach(actx, ap);
779  ap->content = m;
780  m->aptr = ap;
781  ap->parent_type = parent_type;
782  ap->level = level;
783 
784  /* We don't support multipart messages in the compose menu yet */
785  }
786  }
787 }
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
struct Body * next
next attachment in the list
Definition: body.h:53
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
static void mutt_gen_compose_attach_list(struct AttachCtx *actx, struct Body *m, int parent_type, int level)
Generate the attachment list for the compose screen.
Definition: compose.c:765
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define WithCrypto
Definition: ncrypt.h:160
int level
Nesting depth of attachment.
Definition: attach.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void mutt_update_compose_menu ( struct AttachCtx actx,
struct Menu menu,
bool  init 
)
static

Redraw the compose window.

Parameters
actxAttachment context
menuCurrent menu
initIf true, initialise the attachment list

Definition at line 795 of file compose.c.

796 {
797  if (init)
798  {
799  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
800  mutt_attach_init(actx);
801  menu->data = actx;
802  }
803 
804  mutt_update_tree(actx);
805 
806  menu->max = actx->vcount;
807  if (menu->max)
808  {
809  if (menu->current >= menu->max)
810  menu->current = menu->max - 1;
811  }
812  else
813  menu->current = 0;
814 
815  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
816 }
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
struct Body * content
List of MIME parts.
Definition: email.h:92
static void mutt_gen_compose_attach_list(struct AttachCtx *actx, struct Body *m, int parent_type, int level)
Generate the attachment list for the compose screen.
Definition: compose.c:765
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1321
int max
the number of entries in the menu
Definition: mutt_menu.h:88
MuttRedrawFlags redraw
when to redraw the screen
Definition: mutt_menu.h:89
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:144
void * data
extra data for the current menu
Definition: mutt_menu.h:86
int current
current entry
Definition: mutt_menu.h:87
short vcount
The number of virtual attachments.
Definition: attach.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void update_idx ( struct Menu menu,
struct AttachCtx actx,
struct AttachPtr ap 
)
static

Add a new attchment to the message.

Parameters
menuCurrent menu
actxAttachment context
apAttachment to add

Definition at line 824 of file compose.c.

825 {
826  ap->level = (actx->idxlen > 0) ? actx->idx[actx->idxlen - 1]->level : 0;
827  if (actx->idxlen)
828  actx->idx[actx->idxlen - 1]->content->next = ap->content;
829  ap->content->aptr = ap;
830  mutt_actx_add_attach(actx, ap);
831  mutt_update_compose_menu(actx, menu, false);
832  menu->current = actx->vcount - 1;
833 }
struct Body * next
next attachment in the list
Definition: body.h:53
short idxlen
Number of attachmentes.
Definition: attach.h:55
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:795
struct Body * content
Attachment.
Definition: attach.h:36
int current
current entry
Definition: mutt_menu.h:87
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
short vcount
The number of virtual attachments.
Definition: attach.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void compose_status_line ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
struct Menu menu,
const char *  src 
)
static

Compose the string for the status bar.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]colStarting column
[in]colsNumber of screen columns
[in]menuCurrent menu
[in]srcPrintf-like format string

Definition at line 1028 of file compose.c.

1030 {
1031  mutt_expando_format(buf, buflen, col, cols, src, compose_format_str,
1032  (unsigned long) menu, MUTT_FORMAT_NO_FLAGS);
1033 }
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:838
static const char * compose_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
Create the status bar string for compose mode - Implements format_t.
Definition: compose.c:970
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void compose_custom_redraw ( struct Menu menu)
static

Redraw the compose menu - Implements Menu::menu_custom_redraw()

Definition at line 841 of file compose.c.

842 {
843  struct ComposeRedrawData *rd = menu->redraw_data;
844 
845  if (!rd)
846  return;
847 
848  if (menu->redraw & REDRAW_FULL)
849  {
850  menu_redraw_full(menu);
851 
852  draw_envelope(rd);
853  menu->offset = HDR_ATTACH;
855  }
856 
857  menu_check_recenter(menu);
858 
859  if (menu->redraw & REDRAW_STATUS)
860  {
861  char buf[1024];
862  compose_status_line(buf, sizeof(buf), 0, MuttStatusWindow->cols, menu,
867  NORMAL_COLOR;
868  menu->redraw &= ~REDRAW_STATUS;
869  }
870 
871 #ifdef USE_SIDEBAR
872  if (menu->redraw & REDRAW_SIDEBAR)
873  menu_redraw_sidebar(menu);
874 #endif
875 
876  if (menu->redraw & REDRAW_INDEX)
877  menu_redraw_index(menu);
878  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNC))
879  menu_redraw_motion(menu);
880  else if (menu->redraw == REDRAW_CURRENT)
881  menu_redraw_current(menu);
882 }
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
#define NONULL(x)
Definition: string2.h:37
struct MuttWindow * MuttStatusWindow
Status Window.
Definition: mutt_window.c:41
#define NORMAL_COLOR
Definition: mutt_curses.h:239
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1169
void * redraw_data
Definition: mutt_menu.h:152
static void draw_envelope(struct ComposeRedrawData *rd)
Write the email headers to the compose window.
Definition: compose.c:624
static void compose_status_line(char *buf, size_t buflen, size_t col, int cols, struct Menu *menu, const char *p)
Compose the string for the status bar.
Definition: compose.c:1028
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:43
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
int pagelen
number of entries per screen
Definition: mutt_menu.h:92
#define SET_COLOR(X)
Definition: mutt_curses.h:224
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
MuttRedrawFlags redraw
when to redraw the screen
Definition: mutt_menu.h:89
int offset
row offset within the window to start the index
Definition: mutt_menu.h:91
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
Status bar.
Definition: mutt_curses.h:129
Where to start printing the attachments.
Definition: compose.c:136
char * C_ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:93
Keep track when the compose screen needs redrawing.
Definition: compose.c:244
#define REDRAW_CURRENT
Redraw the current line of the menu.
Definition: mutt_menu.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void compose_attach_swap ( struct Body msg,
struct AttachPtr **  idx,
short  first 
)
static

Swap two adjacent entries in the attachment list.

Parameters
[in]msgBody of email
[out]idxArray of Attachments
[in]firstIndex of first attachment to swap

Definition at line 890 of file compose.c.

891 {
892  /* Reorder Body pointers.
893  * Must traverse msg from top since Body has no previous ptr. */
894  for (struct Body *part = msg; part; part = part->next)
895  {
896  if (part->next == idx[first]->content)
897  {
898  idx[first]->content->next = idx[first + 1]->content->next;
899  idx[first + 1]->content->next = idx[first]->content;
900  part->next = idx[first + 1]->content;
901  break;
902  }
903  }
904 
905  /* Reorder index */
906  struct AttachPtr *saved = idx[first];
907  idx[first] = idx[first + 1];
908  idx[first + 1] = saved;
909 
910  /* Swap ptr->num */
911  int i = idx[first]->num;
912  idx[first]->num = idx[first + 1]->num;
913  idx[first + 1]->num = i;
914 }
An email to which things will be attached.
Definition: attach.h:34
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
int num
Attachment index number.
Definition: attach.h:41
struct Body * content
Attachment.
Definition: attach.h:36

+ Here is the caller graph for this function:

static unsigned long cum_attachs_size ( struct Menu menu)
static

Cumulative Attachments Size.

Parameters
menuMenu listing attachments
Return values
numBytes in attachments

Returns the total number of bytes used by the attachments in the attachment list after content-transfer-encodings have been applied.

Definition at line 924 of file compose.c.

925 {
926  size_t s = 0;
927  struct AttachCtx *actx = menu->data;
928  struct AttachPtr **idx = actx->idx;
929  struct Content *info = NULL;
930  struct Body *b = NULL;
931 
932  for (unsigned short i = 0; i < actx->idxlen; i++)
933  {
934  b = idx[i]->content;
935 
936  if (!b->content)
938 
939  info = b->content;
940  if (info)
941  {
942  switch (b->encoding)
943  {
945  s += 3 * (info->lobin + info->hibin) + info->ascii + info->crlf;
946  break;
947  case ENC_BASE64:
948  s += (4 * (info->lobin + info->hibin + info->ascii + info->crlf)) / 3;
949  break;
950  default:
951  s += info->lobin + info->hibin + info->ascii + info->crlf;
952  break;
953  }
954  }
955  }
956 
957  return s;
958 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
An email to which things will be attached.
Definition: attach.h:34
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
short idxlen
Number of attachmentes.
Definition: attach.h:55
long hibin
8-bit characters
Definition: content.h:35
The body of an email.
Definition: body.h:34
struct Content * mutt_get_content_info(const char *fname, struct Body *b)
Analyze file to determine MIME encoding to use.
Definition: sendlib.c:1013
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
Info about an attachment.
Definition: content.h:33
long ascii
Number of ascii chars.
Definition: content.h:39
long lobin
Unprintable 7-bit chars (eg., control chars)
Definition: content.h:36
struct Body * content
Attachment.
Definition: attach.h:36
Quoted-printable text.
Definition: mime.h:51
long crlf
\r and \n characters
Definition: content.h:38
void * data
extra data for the current menu
Definition: mutt_menu.h:86
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* compose_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
unsigned long  data,
MuttFormatFlags  flags 
)
static

Create the status bar string for compose mode - Implements format_t.

Expando Description
%a Total number of attachments
%h Local hostname
%l Approximate size (in bytes) of the current message
%v NeoMutt version string

Definition at line 970 of file compose.c.

974 {
975  char fmt[128], tmp[128];
976  int optional = (flags & MUTT_FORMAT_OPTIONAL);
977  struct Menu *menu = (struct Menu *) data;
978 
979  *buf = '\0';
980  switch (op)
981  {
982  case 'a': /* total number of attachments */
983  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
984  snprintf(buf, buflen, fmt, menu->max);
985  break;
986 
987  case 'h': /* hostname */
988  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
989  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
990  break;
991 
992  case 'l': /* approx length of current message in bytes */
993  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
994  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
995  snprintf(buf, buflen, fmt, tmp);
996  break;
997 
998  case 'v':
999  snprintf(buf, buflen, "%s", mutt_make_version());
1000  break;
1001 
1002  case 0:
1003  *buf = '\0';
1004  return src;
1005 
1006  default:
1007  snprintf(buf, buflen, "%%%s%c", prec, op);
1008  break;
1009  }
1010 
1011  if (optional)
1012  compose_status_line(buf, buflen, col, cols, menu, if_str);
1013  else if (flags & MUTT_FORMAT_OPTIONAL)
1014  compose_status_line(buf, buflen, col, cols, menu, else_str);
1015 
1016  return src;
1017 }
#define NONULL(x)
Definition: string2.h:37
GUI selectable list of items.
Definition: mutt_menu.h:82
int menu
menu definition for keymap entries.
Definition: mutt_menu.h:90
static void compose_status_line(char *buf, size_t buflen, size_t col, int cols, struct Menu *menu, const char *p)
Compose the string for the status bar.
Definition: compose.c:1028
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1720
int max
the number of entries in the menu
Definition: mutt_menu.h:88
static unsigned long cum_attachs_size(struct Menu *menu)
Cumulative Attachments Size.
Definition: compose.c:924
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:49
void * data
extra data for the current menu
Definition: mutt_menu.h:86
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1516

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 1046 of file compose.c.

1047 {
1048  char helpstr[1024]; // This isn't copied by the help bar
1049  char buf[PATH_MAX];
1050  int op_close = OP_NULL;
1051  int rc = -1;
1052  bool loop = true;
1053  bool fcc_set = false; /* has the user edited the Fcc: field ? */
1054  struct ComposeRedrawData rd = { 0 };
1055 #ifdef USE_NNTP
1056  bool news = OptNewsSend; /* is it a news article ? */
1057 #endif
1058 
1060 
1061  rd.email = e;
1062  rd.fcc = fcc;
1063 
1064  struct Menu *menu = mutt_menu_new(MENU_COMPOSE);
1065  menu->offset = HDR_ATTACH;
1067  menu->menu_tag = attach_tag;
1068 #ifdef USE_NNTP
1069  if (news)
1070  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeNewsHelp);
1071  else
1072 #endif
1073  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeHelp);
1075  menu->redraw_data = &rd;
1076  mutt_menu_push_current(menu);
1077 
1078  struct AttachCtx *actx = mutt_mem_calloc(sizeof(struct AttachCtx), 1);
1079  actx->email = e;
1080  mutt_update_compose_menu(actx, menu, true);
1081 
1082  update_crypt_info(&rd);
1083 
1084  while (loop)
1085  {
1086 #ifdef USE_NNTP
1087  OptNews = false; /* for any case */
1088 #endif
1089  const int op = mutt_menu_loop(menu);
1090  switch (op)
1091  {
1092  case OP_COMPOSE_EDIT_FROM:
1094  update_crypt_info(&rd);
1096  break;
1097 
1098  case OP_COMPOSE_EDIT_TO:
1099 #ifdef USE_NNTP
1100  if (news)
1101  break;
1102 #endif
1103  edit_address_list(HDR_TO, &e->env->to);
1104  update_crypt_info(&rd);
1106  break;
1107 
1108  case OP_COMPOSE_EDIT_BCC:
1109 #ifdef USE_NNTP
1110  if (news)
1111  break;
1112 #endif
1114  update_crypt_info(&rd);
1116  break;
1117 
1118  case OP_COMPOSE_EDIT_CC:
1119 #ifdef USE_NNTP
1120  if (news)
1121  break;
1122 #endif
1123  edit_address_list(HDR_CC, &e->env->cc);
1124  update_crypt_info(&rd);
1126  break;
1127 #ifdef USE_NNTP
1128  case OP_COMPOSE_EDIT_NEWSGROUPS:
1129  if (!news)
1130  break;
1131  if (e->env->newsgroups)
1132  mutt_str_strfcpy(buf, e->env->newsgroups, sizeof(buf));
1133  else
1134  buf[0] = '\0';
1135  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) == 0)
1136  {
1137  mutt_str_replace(&e->env->newsgroups, buf);
1139  if (e->env->newsgroups)
1140  mutt_paddstr(W, e->env->newsgroups);
1141  else
1142  clrtoeol();
1143  }
1144  break;
1145 
1146  case OP_COMPOSE_EDIT_FOLLOWUP_TO:
1147  if (!news)
1148  break;
1149  if (e->env->followup_to)
1150  mutt_str_strfcpy(buf, e->env->followup_to, sizeof(buf));
1151  else
1152  buf[0] = '\0';
1153  if (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) == 0)
1154  {
1155  mutt_str_replace(&e->env->followup_to, buf);
1157  if (e->env->followup_to)
1158  mutt_paddstr(W, e->env->followup_to);
1159  else
1160  clrtoeol();
1161  }
1162  break;
1163 
1164  case OP_COMPOSE_EDIT_X_COMMENT_TO:
1165  if (!(news && C_XCommentTo))
1166  break;
1167  if (e->env->x_comment_to)
1168  mutt_str_strfcpy(buf, e->env->x_comment_to, sizeof(buf));
1169  else
1170  buf[0] = '\0';
1171  if (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) == 0)
1172  {
1173  mutt_str_replace(&e->env->x_comment_to, buf);
1175  if (e->env->x_comment_to)
1177  else
1178  clrtoeol();
1179  }
1180  break;
1181 #endif
1182 
1183  case OP_COMPOSE_EDIT_SUBJECT:
1184  if (e->env->subject)
1185  mutt_str_strfcpy(buf, e->env->subject, sizeof(buf));
1186  else
1187  buf[0] = '\0';
1188  if (mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) == 0)
1189  {
1190  mutt_str_replace(&e->env->subject, buf);
1192  if (e->env->subject)
1193  mutt_paddstr(W, e->env->subject);
1194  else
1196  }
1198  break;
1199 
1200  case OP_COMPOSE_EDIT_REPLY_TO:
1203  break;
1204 
1205  case OP_COMPOSE_EDIT_FCC:
1206  mutt_str_strfcpy(buf, fcc, sizeof(buf));
1207  if (mutt_get_field(_("Fcc: "), buf, sizeof(buf), MUTT_FILE | MUTT_CLEAR) == 0)
1208  {
1209  mutt_str_strfcpy(fcc, buf, fcclen);
1210  mutt_pretty_mailbox(fcc, fcclen);
1212  mutt_paddstr(W, fcc);
1213  fcc_set = true;
1214  }
1216  break;
1217 
1218  case OP_COMPOSE_EDIT_MESSAGE:
1219  if (C_Editor && (mutt_str_strcmp("builtin", C_Editor) != 0) && !C_EditHeaders)
1220  {
1223  menu->redraw = REDRAW_FULL;
1225  break;
1226  }
1227  /* fallthrough */
1228 
1229  case OP_COMPOSE_EDIT_HEADERS:
1230  if ((mutt_str_strcmp("builtin", C_Editor) != 0) &&
1231  ((op == OP_COMPOSE_EDIT_HEADERS) || ((op == OP_COMPOSE_EDIT_MESSAGE) && C_EditHeaders)))
1232  {
1233  const char *tag = NULL;
1234  char *err = NULL;
1235  mutt_env_to_local(e->env);
1236  mutt_edit_headers(NONULL(C_Editor), e->content->filename, e, fcc, fcclen);
1237  if (mutt_env_to_intl(e->env, &tag, &err))
1238  {
1239  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
1240  FREE(&err);
1241  }
1242  update_crypt_info(&rd);
1243  }
1244  else
1245  {
1246  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
1247  * attachment list could change if the user invokes ~v to edit
1248  * the message with headers, in which we need to execute the
1249  * code below to regenerate the index array */
1250  mutt_builtin_editor(e->content->filename, e, e_cur);
1251  }
1253 
1254  /* attachments may have been added */
1255  if (actx->idxlen && actx->idx[actx->idxlen - 1]->content->next)
1256  {
1257  mutt_actx_free_entries(actx);
1258  mutt_update_compose_menu(actx, menu, true);
1259  }
1260 
1261  menu->redraw = REDRAW_FULL;
1263  break;
1264 
1265  case OP_COMPOSE_ATTACH_KEY:
1266  {
1267  if (!(WithCrypto & APPLICATION_PGP))
1268  break;
1269  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1271  if (ap->content)
1272  {
1273  update_idx(menu, actx, ap);
1274  menu->redraw |= REDRAW_INDEX;
1275  }
1276  else
1277  FREE(&ap);
1278 
1279  menu->redraw |= REDRAW_STATUS;
1280 
1282  break;
1283  }
1284 
1285  case OP_COMPOSE_MOVE_UP:
1286  if (menu->current == 0)
1287  {
1288  mutt_error(_("Attachment is already at top"));
1289  break;
1290  }
1291  if (menu->current == 1)
1292  {
1293  mutt_error(_("The fundamental part can't be moved"));
1294  break;
1295  }
1296  compose_attach_swap(e->content, actx->idx, menu->current - 1);
1297  menu->redraw = REDRAW_INDEX;
1298  menu->current--;
1299  break;
1300 
1301  case OP_COMPOSE_MOVE_DOWN:
1302  if (menu->current == (actx->idxlen - 1))
1303  {
1304  mutt_error(_("Attachment is already at bottom"));
1305  break;
1306  }
1307  if (menu->current == 0)
1308  {
1309  mutt_error(_("The fundamental part can't be moved"));
1310  break;
1311  }
1312  compose_attach_swap(e->content, actx->idx, menu->current);
1313  menu->redraw = REDRAW_INDEX;
1314  menu->current++;
1315  break;
1316 
1317  case OP_COMPOSE_GROUP_ALTS:
1318  {
1319  if (menu->tagged < 2)
1320  {
1321  mutt_error(
1322  _("Grouping 'alternatives' requires at least 2 tagged messages"));
1323  break;
1324  }
1325 
1326  struct Body *group = mutt_body_new();
1327  group->type = TYPE_MULTIPART;
1328  group->subtype = mutt_str_strdup("alternative");
1329  group->disposition = DISP_INLINE;
1330 
1331  struct Body *alts = NULL;
1332  /* group tagged message into a multipart/alternative */
1333  struct Body *bptr = e->content;
1334  for (int i = 0; bptr;)
1335  {
1336  if (bptr->tagged)
1337  {
1338  bptr->tagged = false;
1339  bptr->disposition = DISP_INLINE;
1340 
1341  /* for first match, set group desc according to match */
1342 #define ALTS_TAG "Alternatives for \"%s\""
1343  if (!group->description)
1344  {
1345  char *p = bptr->description ? bptr->description : bptr->filename;
1346  if (p)
1347  {
1348  group->description =
1349  mutt_mem_calloc(1, strlen(p) + strlen(ALTS_TAG) + 1);
1350  sprintf(group->description, ALTS_TAG, p);
1351  }
1352  }
1353 
1354  /* append bptr to the alts list,
1355  * and remove from the e->content list */
1356  if (!alts)
1357  {
1358  group->parts = bptr;
1359  alts = bptr;
1360  bptr = bptr->next;
1361  alts->next = NULL;
1362  }
1363  else
1364  {
1365  alts->next = bptr;
1366  bptr = bptr->next;
1367  alts = alts->next;
1368  alts->next = NULL;
1369  }
1370 
1371  for (int j = i; j < actx->idxlen - 1; j++)
1372  {
1373  actx->idx[j] = actx->idx[j + 1];
1374  actx->idx[j + 1] = NULL; /* for debug reason */
1375  }
1376  actx->idxlen--;
1377  }
1378  else
1379  {
1380  bptr = bptr->next;
1381  i++;
1382  }
1383  }
1384 
1385  group->next = NULL;
1387 
1388  /* if no group desc yet, make one up */
1389  if (!group->description)
1390  group->description = mutt_str_strdup("unknown alternative group");
1391 
1392  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1393  gptr->content = group;
1394  update_idx(menu, actx, gptr);
1395  menu->redraw = REDRAW_INDEX;
1396  break;
1397  }
1398 
1399  case OP_COMPOSE_GROUP_LINGUAL:
1400  {
1401  if (menu->tagged < 2)
1402  {
1403  mutt_error(
1404  _("Grouping 'multilingual' requires at least 2 tagged messages"));
1405  break;
1406  }
1407 
1408  /* traverse to see whether all the parts have Content-Language: set */
1409  int tagged_with_lang_num = 0;
1410  for (struct Body *b = e->content; b; b = b->next)
1411  if (b->tagged && b->language && *b->language)
1412  tagged_with_lang_num++;
1413 
1414  if (menu->tagged != tagged_with_lang_num)
1415  {
1416  if (mutt_yesorno(
1417  _("Not all parts have 'Content-Language' set, continue?"), MUTT_YES) != MUTT_YES)
1418  {
1419  mutt_message(_("Not sending this message"));
1420  break;
1421  }
1422  }
1423 
1424  struct Body *group = mutt_body_new();
1425  group->type = TYPE_MULTIPART;
1426  group->subtype = mutt_str_strdup("multilingual");
1427  group->disposition = DISP_INLINE;
1428 
1429  struct Body *alts = NULL;
1430  /* group tagged message into a multipart/multilingual */
1431  struct Body *bptr = e->content;
1432  for (int i = 0; bptr;)
1433  {
1434  if (bptr->tagged)
1435  {
1436  bptr->tagged = false;
1437  bptr->disposition = DISP_INLINE;
1438 
1439  /* for first match, set group desc according to match */
1440 #define LINGUAL_TAG "Multilingual part for \"%s\""
1441  if (!group->description)
1442  {
1443  char *p = bptr->description ? bptr->description : bptr->filename;
1444  if (p)
1445  {
1446  group->description =
1447  mutt_mem_calloc(1, strlen(p) + strlen(LINGUAL_TAG) + 1);
1448  sprintf(group->description, LINGUAL_TAG, p);
1449  }
1450  }
1451 
1452  /* append bptr to the alts list,
1453  * and remove from the e->content list */
1454  if (!alts)
1455  {
1456  group->parts = bptr;
1457  alts = bptr;
1458  bptr = bptr->next;
1459  alts->next = NULL;
1460  }
1461  else
1462  {
1463  alts->next = bptr;
1464  bptr = bptr->next;
1465  alts = alts->next;
1466  alts->next = NULL;
1467  }
1468 
1469  for (int j = i; j < actx->idxlen - 1; j++)
1470  {
1471  actx->idx[j] = actx->idx[j + 1];
1472  actx->idx[j + 1] = NULL; /* for debug reason */
1473  }
1474  actx->idxlen--;
1475  }
1476  else
1477  {
1478  bptr = bptr->next;
1479  i++;
1480  }
1481  }
1482 
1483  group->next = NULL;
1485 
1486  /* if no group desc yet, make one up */
1487  if (!group->description)
1488  group->description = mutt_str_strdup("unknown multilingual group");
1489 
1490  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1491  gptr->content = group;
1492  update_idx(menu, actx, gptr);
1493  menu->redraw = REDRAW_INDEX;
1494  break;
1495  }
1496 
1497  case OP_COMPOSE_ATTACH_FILE:
1498  {
1499  char *prompt = _("Attach file");
1500  int numfiles = 0;
1501  char **files = NULL;
1502  buf[0] = '\0';
1503 
1504  if ((mutt_enter_fname_full(prompt, buf, sizeof(buf), false, true,
1505  &files, &numfiles, MUTT_SEL_MULTI) == -1) ||
1506  (*buf == '\0'))
1507  {
1508  break;
1509  }
1510 
1511  bool error = false;
1512  if (numfiles > 1)
1513  {
1514  mutt_message(ngettext("Attaching selected file...",
1515  "Attaching selected files...", numfiles));
1516  }
1517  for (int i = 0; i < numfiles; i++)
1518  {
1519  char *att = files[i];
1520  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1521  ap->unowned = true;
1522  ap->content = mutt_make_file_attach(att);
1523  if (ap->content)
1524  update_idx(menu, actx, ap);
1525  else
1526  {
1527  error = true;
1528  mutt_error(_("Unable to attach %s"), att);
1529  FREE(&ap);
1530  }
1531  FREE(&files[i]);
1532  }
1533 
1534  FREE(&files);
1535  if (!error)
1536  mutt_clear_error();
1537 
1538  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1540  break;
1541  }
1542 
1543  case OP_COMPOSE_ATTACH_MESSAGE:
1544 #ifdef USE_NNTP
1545  case OP_COMPOSE_ATTACH_NEWS_MESSAGE:
1546 #endif
1547  {
1548  char *prompt = _("Open mailbox to attach message from");
1549  buf[0] = '\0';
1550 
1551 #ifdef USE_NNTP
1552  OptNews = false;
1553  if (Context && (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE))
1554  {
1556  if (!CurrentNewsSrv)
1557  break;
1558 
1559  prompt = _("Open newsgroup to attach message from");
1560  OptNews = true;
1561  }
1562 #endif
1563 
1564  if (Context)
1565 #ifdef USE_NNTP
1566  if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->mailbox->magic == MUTT_NNTP))
1567 #endif
1568  {
1569  mutt_str_strfcpy(buf, mutt_b2s(Context->mailbox->pathbuf), sizeof(buf));
1570  mutt_pretty_mailbox(buf, sizeof(buf));
1571  }
1572 
1573  if ((mutt_enter_fname(prompt, buf, sizeof(buf), true) == -1) || (buf[0] == '\0'))
1574  break;
1575 
1576 #ifdef USE_NNTP
1577  if (OptNews)
1578  nntp_expand_path(buf, sizeof(buf), &CurrentNewsSrv->conn->account);
1579  else
1580 #endif
1581  mutt_expand_path(buf, sizeof(buf));
1582 #ifdef USE_IMAP
1583  if (imap_path_probe(buf, NULL) != MUTT_IMAP)
1584 #endif
1585 #ifdef USE_POP
1586  if (pop_path_probe(buf, NULL) != MUTT_POP)
1587 #endif
1588 #ifdef USE_NNTP
1589  if (!OptNews && (nntp_path_probe(buf, NULL) != MUTT_NNTP))
1590 #endif
1591  /* check to make sure the file exists and is readable */
1592  if (access(buf, R_OK) == -1)
1593  {
1594  mutt_perror(buf);
1595  break;
1596  }
1597 
1598  menu->redraw = REDRAW_FULL;
1599 
1600  struct Mailbox *m = mx_path_resolve(buf);
1601  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
1602  if (!ctx)
1603  {
1604  mutt_error(_("Unable to open mailbox %s"), buf);
1605  mailbox_free(&m);
1606  break;
1607  }
1608 
1609  if (ctx->mailbox->msg_count == 0)
1610  {
1611  mx_mbox_close(&ctx);
1612  mutt_error(_("No messages in that folder"));
1613  break;
1614  }
1615 
1616  struct Context *ctx_cur = Context; /* remember current folder and sort methods */
1617  int old_sort = C_Sort; /* C_Sort, SortAux could be changed in mutt_index_menu() */
1618  int old_sort_aux = C_SortAux;
1619 
1620  Context = ctx;
1621  OptAttachMsg = true;
1622  mutt_message(_("Tag the messages you want to attach"));
1623  op_close = mutt_index_menu();
1624  OptAttachMsg = false;
1625 
1626  if (!Context)
1627  {
1628  /* go back to the folder we started from */
1629  Context = ctx_cur;
1630  /* Restore old $sort and $sort_aux */
1631  C_Sort = old_sort;
1632  C_SortAux = old_sort_aux;
1633  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1634  break;
1635  }
1636 
1637  for (int i = 0; i < Context->mailbox->msg_count; i++)
1638  {
1639  if (!message_is_tagged(Context, i))
1640  continue;
1641 
1642  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1644  Context->mailbox->emails[i], true);
1645  if (ap->content)
1646  update_idx(menu, actx, ap);
1647  else
1648  {
1649  mutt_error(_("Unable to attach"));
1650  FREE(&ap);
1651  }
1652  }
1653  menu->redraw |= REDRAW_FULL;
1654 
1655  if (op_close == OP_QUIT)
1657  else
1658  {
1660  ctx_free(&Context);
1661  }
1662 
1663  /* go back to the folder we started from */
1664  Context = ctx_cur;
1665  /* Restore old $sort and $sort_aux */
1666  C_Sort = old_sort;
1667  C_SortAux = old_sort_aux;
1669  break;
1670  }
1671 
1672  case OP_DELETE:
1673  CHECK_COUNT;
1674  if (CUR_ATTACH->unowned)
1675  CUR_ATTACH->content->unlink = false;
1676  if (delete_attachment(actx, menu->current) == -1)
1677  break;
1678  mutt_update_compose_menu(actx, menu, false);
1679  if (menu->current == 0)
1680  e->content = actx->idx[0]->content;
1681 
1683  break;
1684 
1685  case OP_COMPOSE_TOGGLE_RECODE:
1686  {
1687  CHECK_COUNT;
1688  if (!mutt_is_text_part(CUR_ATTACH->content))
1689  {
1690  mutt_error(_("Recoding only affects text attachments"));
1691  break;
1692  }
1693  CUR_ATTACH->content->noconv = !CUR_ATTACH->content->noconv;
1694  if (CUR_ATTACH->content->noconv)
1695  mutt_message(_("The current attachment won't be converted"));
1696  else
1697  mutt_message(_("The current attachment will be converted"));
1698  menu->redraw = REDRAW_CURRENT;
1700  break;
1701  }
1702 
1703  case OP_COMPOSE_EDIT_DESCRIPTION:
1704  CHECK_COUNT;
1706  buf, CUR_ATTACH->content->description ? CUR_ATTACH->content->description : "",
1707  sizeof(buf));
1708  /* header names should not be translated */
1709  if (mutt_get_field("Description: ", buf, sizeof(buf), 0) == 0)
1710  {
1711  mutt_str_replace(&CUR_ATTACH->content->description, buf);
1712  menu->redraw = REDRAW_CURRENT;
1713  }
1715  break;
1716 
1717  case OP_COMPOSE_UPDATE_ENCODING:
1718  CHECK_COUNT;
1719  if (menu->tagprefix)
1720  {
1721  struct Body *top = NULL;
1722  for (top = e->content; top; top = top->next)
1723  {
1724  if (top->tagged)
1725  mutt_update_encoding(top);
1726  }
1727  menu->redraw = REDRAW_FULL;
1728  }
1729  else
1730  {
1731  mutt_update_encoding(CUR_ATTACH->content);
1733  }
1735  break;
1736 
1737  case OP_COMPOSE_TOGGLE_DISPOSITION:
1738  /* toggle the content-disposition between inline/attachment */
1739  CUR_ATTACH->content->disposition =
1740  (CUR_ATTACH->content->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
1741  menu->redraw = REDRAW_CURRENT;
1742  break;
1743 
1744  case OP_EDIT_TYPE:
1745  CHECK_COUNT;
1746  {
1747  mutt_edit_content_type(NULL, CUR_ATTACH->content, NULL);
1748 
1749  /* this may have been a change to text/something */
1750  mutt_update_encoding(CUR_ATTACH->content);
1751 
1752  menu->redraw = REDRAW_CURRENT;
1753  }
1755  break;
1756 
1757  case OP_COMPOSE_EDIT_LANGUAGE:
1758  CHECK_COUNT;
1759  buf[0] = '\0'; /* clear buffer first */
1760  if (CUR_ATTACH->content->language)
1761  mutt_str_strfcpy(buf, CUR_ATTACH->content->language, sizeof(buf));
1762  if (mutt_get_field("Content-Language: ", buf, sizeof(buf), 0) == 0)
1763  {
1764  CUR_ATTACH->content->language = mutt_str_strdup(buf);
1766  mutt_clear_error();
1767  }
1768  else
1769  mutt_warning(_("Empty 'Content-Language'"));
1771  break;
1772 
1773  case OP_COMPOSE_EDIT_ENCODING:
1774  CHECK_COUNT;
1775  mutt_str_strfcpy(buf, ENCODING(CUR_ATTACH->content->encoding), sizeof(buf));
1776  if ((mutt_get_field("Content-Transfer-Encoding: ", buf, sizeof(buf), 0) == 0) &&
1777  (buf[0] != '\0'))
1778  {
1779  int enc = mutt_check_encoding(buf);
1780  if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1781  {
1782  CUR_ATTACH->content->encoding = enc;
1784  mutt_clear_error();
1785  }
1786  else
1787  mutt_error(_("Invalid encoding"));
1788  }
1790  break;
1791 
1792  case OP_COMPOSE_SEND_MESSAGE:
1793  /* Note: We don't invoke send2-hook here, since we want to leave
1794  * users an opportunity to change settings from the ":" prompt. */
1795  if (check_attachments(actx) != 0)
1796  {
1797  menu->redraw = REDRAW_FULL;
1798  break;
1799  }
1800 
1801 #ifdef MIXMASTER
1802  if (!STAILQ_EMPTY(&e->chain) && (mix_check_message(e) != 0))
1803  break;
1804 #endif
1805 
1806  if (!fcc_set && *fcc)
1807  {
1808  enum QuadOption ans =
1809  query_quadoption(C_Copy, _("Save a copy of this message?"));
1810  if (ans == MUTT_ABORT)
1811  break;
1812  else if (ans == MUTT_NO)
1813  *fcc = '\0';
1814  }
1815 
1816  loop = false;
1817  rc = 0;
1818  break;
1819 
1820  case OP_COMPOSE_EDIT_FILE:
1821  CHECK_COUNT;
1822  mutt_edit_file(NONULL(C_Editor), CUR_ATTACH->content->filename);
1823  mutt_update_encoding(CUR_ATTACH->content);
1826  break;
1827 
1828  case OP_COMPOSE_TOGGLE_UNLINK:
1829  CHECK_COUNT;
1830  CUR_ATTACH->content->unlink = !CUR_ATTACH->content->unlink;
1831 
1832  menu->redraw = REDRAW_INDEX;
1833  /* No send2hook since this doesn't change the message. */
1834  break;
1835 
1836  case OP_COMPOSE_GET_ATTACHMENT:
1837  CHECK_COUNT;
1838  if (menu->tagprefix)
1839  {
1840  for (struct Body *top = e->content; top; top = top->next)
1841  {
1842  if (top->tagged)
1844  }
1845  menu->redraw = REDRAW_FULL;
1846  }
1847  else if (mutt_get_tmp_attachment(CUR_ATTACH->content) == 0)
1848  menu->redraw = REDRAW_CURRENT;
1849 
1850  /* No send2hook since this doesn't change the message. */
1851  break;
1852 
1853  case OP_COMPOSE_RENAME_ATTACHMENT:
1854  {
1855  CHECK_COUNT;
1856  char *src = NULL;
1857  if (CUR_ATTACH->content->d_filename)
1858  src = CUR_ATTACH->content->d_filename;
1859  else
1860  src = CUR_ATTACH->content->filename;
1861  mutt_str_strfcpy(buf, mutt_path_basename(NONULL(src)), sizeof(buf));
1862  int ret = mutt_get_field(_("Send attachment with name: "), buf, sizeof(buf), MUTT_FILE);
1863  if (ret == 0)
1864  {
1865  /* As opposed to RENAME_FILE, we don't check buf[0] because it's
1866  * valid to set an empty string here, to erase what was set */
1867  mutt_str_replace(&CUR_ATTACH->content->d_filename, buf);
1868  menu->redraw = REDRAW_CURRENT;
1869  }
1870  break;
1871  }
1872 
1873  case OP_COMPOSE_RENAME_FILE:
1874  CHECK_COUNT;
1875  mutt_str_strfcpy(buf, CUR_ATTACH->content->filename, sizeof(buf));
1876  mutt_pretty_mailbox(buf, sizeof(buf));
1877  if ((mutt_get_field(_("Rename to: "), buf, sizeof(buf), MUTT_FILE) == 0) &&
1878  (buf[0] != '\0'))
1879  {
1880  struct stat st;
1881  if (stat(CUR_ATTACH->content->filename, &st) == -1)
1882  {
1883  /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
1884  mutt_error(_("Can't stat %s: %s"), buf, strerror(errno));
1885  break;
1886  }
1887 
1888  mutt_expand_path(buf, sizeof(buf));
1889  if (mutt_file_rename(CUR_ATTACH->content->filename, buf))
1890  break;
1891 
1892  mutt_str_replace(&CUR_ATTACH->content->filename, buf);
1893  menu->redraw = REDRAW_CURRENT;
1894 
1895  if (CUR_ATTACH->content->stamp >= st.st_mtime)
1897  }
1899  break;
1900 
1901  case OP_COMPOSE_NEW_MIME:
1902  {
1904  buf[0] = '\0';
1905  if ((mutt_get_field(_("New file: "), buf, sizeof(buf), MUTT_FILE) != 0) ||
1906  (buf[0] == '\0'))
1907  {
1908  continue;
1909  }
1910  mutt_expand_path(buf, sizeof(buf));
1911 
1912  /* Call to lookup_mime_type () ? maybe later */
1913  char type[256] = { 0 };
1914  if ((mutt_get_field("Content-Type: ", type, sizeof(type), 0) != 0) ||
1915  (type[0] == '\0'))
1916  {
1917  continue;
1918  }
1919 
1920  char *p = strchr(type, '/');
1921  if (!p)
1922  {
1923  mutt_error(_("Content-Type is of the form base/sub"));
1924  continue;
1925  }
1926  *p++ = 0;
1927  enum ContentType itype = mutt_check_mime_type(type);
1928  if (itype == TYPE_OTHER)
1929  {
1930  mutt_error(_("Unknown Content-Type %s"), type);
1931  continue;
1932  }
1933  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1934  /* Touch the file */
1935  FILE *fp = mutt_file_fopen(buf, "w");
1936  if (!fp)
1937  {
1938  mutt_error(_("Can't create file %s"), buf);
1939  FREE(&ap);
1940  continue;
1941  }
1942  mutt_file_fclose(&fp);
1943 
1944  ap->content = mutt_make_file_attach(buf);
1945  if (!ap->content)
1946  {
1947  mutt_error(_("What we have here is a failure to make an attachment"));
1948  FREE(&ap);
1949  continue;
1950  }
1951  update_idx(menu, actx, ap);
1952 
1953  CUR_ATTACH->content->type = itype;
1954  mutt_str_replace(&CUR_ATTACH->content->subtype, p);
1955  CUR_ATTACH->content->unlink = true;
1956  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1957 
1958  if (mutt_compose_attachment(CUR_ATTACH->content))
1959  {
1960  mutt_update_encoding(CUR_ATTACH->content);
1961  menu->redraw = REDRAW_FULL;
1962  }
1964  break;
1965  }
1966 
1967  case OP_COMPOSE_EDIT_MIME:
1968  CHECK_COUNT;
1969  if (mutt_edit_attachment(CUR_ATTACH->content))
1970  {
1971  mutt_update_encoding(CUR_ATTACH->content);
1972  menu->redraw = REDRAW_FULL;
1973  }
1975  break;
1976 
1977  case OP_VIEW_ATTACH:
1978  case OP_DISPLAY_HEADERS:
1979  CHECK_COUNT;
1980  mutt_attach_display_loop(menu, op, NULL, actx, false);
1981  menu->redraw = REDRAW_FULL;
1982  /* no send2hook, since this doesn't modify the message */
1983  break;
1984 
1985  case OP_SAVE:
1986  CHECK_COUNT;
1987  mutt_save_attachment_list(actx, NULL, menu->tagprefix,
1988  CUR_ATTACH->content, NULL, menu);
1989  /* no send2hook, since this doesn't modify the message */
1990  break;
1991 
1992  case OP_PRINT:
1993  CHECK_COUNT;
1994  mutt_print_attachment_list(actx, NULL, menu->tagprefix, CUR_ATTACH->content);
1995  /* no send2hook, since this doesn't modify the message */
1996  break;
1997 
1998  case OP_PIPE:
1999  case OP_FILTER:
2000  CHECK_COUNT;
2001  mutt_pipe_attachment_list(actx, NULL, menu->tagprefix,
2002  CUR_ATTACH->content, (op == OP_FILTER));
2003  if (op == OP_FILTER) /* cte might have changed */
2004  menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
2005  menu->redraw |= REDRAW_STATUS;
2007  break;
2008 
2009  case OP_EXIT:
2010  {
2011  enum QuadOption ans =
2012  query_quadoption(C_Postpone, _("Save (postpone) draft message?"));
2013  if (ans == MUTT_NO)
2014  {
2015  for (int i = 0; i < actx->idxlen; i++)
2016  if (actx->idx[i]->unowned)
2017  actx->idx[i]->content->unlink = false;
2018 
2019  if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
2020  {
2021  for (int i = 0; i < actx->idxlen; i++)
2022  {
2023  /* avoid freeing other attachments */
2024  actx->idx[i]->content->next = NULL;
2025  actx->idx[i]->content->parts = NULL;
2026  mutt_body_free(&actx->idx[i]->content);
2027  }
2028  }
2029  rc = -1;
2030  loop = false;
2031  break;
2032  }
2033  else if (ans == MUTT_ABORT)
2034  break; /* abort */
2035  }
2036  /* fallthrough */
2037 
2038  case OP_COMPOSE_POSTPONE_MESSAGE:
2039  if (check_attachments(actx) != 0)
2040  {
2041  menu->redraw = REDRAW_FULL;
2042  break;
2043  }
2044 
2045  loop = false;
2046  rc = 1;
2047  break;
2048 
2049  case OP_COMPOSE_ISPELL:
2050  endwin();
2051  snprintf(buf, sizeof(buf), "%s -x %s", NONULL(C_Ispell), e->content->filename);
2052  if (mutt_system(buf) == -1)
2053  mutt_error(_("Error running \"%s\""), buf);
2054  else
2055  {
2057  menu->redraw |= REDRAW_STATUS;
2058  }
2059  break;
2060 
2061  case OP_COMPOSE_WRITE_MESSAGE:
2062  buf[0] = '\0';
2063  if (Context)
2064  {
2065  mutt_str_strfcpy(buf, mutt_b2s(Context->mailbox->pathbuf), sizeof(buf));
2066  mutt_pretty_mailbox(buf, sizeof(buf));
2067  }
2068  if (actx->idxlen)
2069  e->content = actx->idx[0]->content;
2070  if ((mutt_enter_fname(_("Write message to mailbox"), buf, sizeof(buf), true) != -1) &&
2071  (buf[0] != '\0'))
2072  {
2073  mutt_message(_("Writing message to %s ..."), buf);
2074  mutt_expand_path(buf, sizeof(buf));
2075 
2076  if (e->content->next)
2078 
2079  if (mutt_write_fcc(buf, e, NULL, false, NULL, NULL) < 0)
2081  else
2082  mutt_message(_("Message written"));
2083  }
2084  break;
2085 
2086  case OP_COMPOSE_PGP_MENU:
2087  if (!(WithCrypto & APPLICATION_PGP))
2088  break;
2089  if (!crypt_has_module_backend(APPLICATION_PGP))
2090  {
2091  mutt_error(_("No PGP backend configured"));
2092  break;
2093  }
2094  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
2095  {
2096  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2097  {
2098  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2099  {
2100  mutt_clear_error();
2101  break;
2102  }
2103  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2104  }
2105  e->security &= ~APPLICATION_SMIME;
2106  e->security |= APPLICATION_PGP;
2107  update_crypt_info(&rd);
2108  }
2109  e->security = crypt_pgp_send_menu(e);
2110  update_crypt_info(&rd);
2112  break;
2113 
2114  case OP_FORGET_PASSPHRASE:
2116  break;
2117 
2118  case OP_COMPOSE_SMIME_MENU:
2119  if (!(WithCrypto & APPLICATION_SMIME))
2120  break;
2121  if (!crypt_has_module_backend(APPLICATION_SMIME))
2122  {
2123  mutt_error(_("No S/MIME backend configured"));
2124  break;
2125  }
2126 
2127  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
2128  {
2129  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2130  {
2131  if (mutt_yesorno(_("PGP already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2132  {
2133  mutt_clear_error();
2134  break;
2135  }
2136  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2137  }
2138  e->security &= ~APPLICATION_PGP;
2140  update_crypt_info(&rd);
2141  }
2143  update_crypt_info(&rd);
2145  break;
2146 
2147 #ifdef MIXMASTER
2148  case OP_COMPOSE_MIX:
2149  mix_make_chain(&e->chain);
2151  break;
2152 #endif
2153 #ifdef USE_AUTOCRYPT
2154  case OP_COMPOSE_AUTOCRYPT_MENU:
2155  if (!C_Autocrypt)
2156  break;
2157 
2158  if ((WithCrypto & APPLICATION_SMIME) && (e->security & APPLICATION_SMIME))
2159  {
2160  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2161  {
2162  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2163  {
2164  mutt_clear_error();
2165  break;
2166  }
2167  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2168  }
2169  e->security &= ~APPLICATION_SMIME;
2170  e->security |= APPLICATION_PGP;
2171  update_crypt_info(&rd);
2172  }
2174  update_crypt_info(&rd);
2176  break;
2177 #endif
2178  }
2179  }
2180 
2181 #ifdef USE_AUTOCRYPT
2182  /* This is a fail-safe to make sure the bit isn't somehow turned
2183  * on. The user could have disabled the option after setting SEC_AUTOCRYPT,
2184  * or perhaps resuming or replying to an autocrypt message. */
2185  if (!C_Autocrypt)
2186  e->security &= ~SEC_AUTOCRYPT;
2187 #endif
2188 
2189  mutt_menu_pop_current(menu);
2190  mutt_menu_free(&menu);
2191 
2192  if (actx->idxlen)
2193  e->content = actx->idx[0]->content;
2194  else
2195  e->content = NULL;
2196 
2197  mutt_actx_free(&actx);
2198 
2199  return rc;
2200 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:36
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:724
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
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:209
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:1136
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:69
#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:2430
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:3322
#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:1333
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:841
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:649
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
"To:" field
Definition: compose.c:116
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:117
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:486
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:73
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:190
struct Email * email
Definition: compose.c:246
char * C_Ispell
Config: External command to perform spell-checking.
Definition: compose.c:94
int menu
menu definition for keymap entries.
Definition: mutt_menu.h:90
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:53
"Subject:" field
Definition: compose.c:119
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:289
#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:569
"From:" field
Definition: compose.c:115
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:122
#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
char * mutt_compile_help(char *buf, size_t buflen, int menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1169
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:310
#define CUR_ATTACH
Definition: compose.c:106
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
void * redraw_data
Definition: mutt_menu.h:152
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1019
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:221
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:622
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:319
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
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
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:890
void(* menu_custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:151
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:143
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
void mutt_actx_free(struct AttachCtx **pactx)
Free an Attachment Context.
Definition: attach.c:131
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: globals.h:136
static const struct Mapping ComposeHelp[]
Definition: compose.c:188
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
void mutt_actx_free_entries(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
WHERE short C_SortAux
Config: Secondary sort method for the index.
Definition: sort.h:59
#define HDR_XOFFSET
Definition: compose.c:142
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE struct Context * Context
Definition: globals.h:41
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:428
#define ALTS_TAG
A mailbox.
Definition: mailbox.h:92
#define PATH_MAX
Definition: mutt.h:51
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
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:559
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:795
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:143
#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:204
int tagged
number of tagged entries
Definition: mutt_menu.h:113
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:65
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:139
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
"Bcc:" field
Definition: compose.c:118
static void edit_address_list(int line, struct AddressList *al)
Let the user edit the address list.
Definition: compose.c:689
#define LINGUAL_TAG
struct Buffer * pathbuf
Definition: mailbox.h:94
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:824
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:870
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:251
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:295
int offset
row offset within the window to start the index
Definition: mutt_menu.h:91
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * subject
Email&#39;s subject.
Definition: envelope.h:66
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:298
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:324
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:113
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:1541
#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:136
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: compose.c:279
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
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2824
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1203
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:121
#define CHECK_COUNT
Definition: compose.c:99
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:584
int mutt_index_menu(void)
Display a list of emails.
Definition: index.c:1034
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:244
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:776
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:120
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:3187

+ Here is the caller graph for this function:

Variable Documentation

char* C_ComposeFormat

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

Definition at line 93 of file compose.c.

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 94 of file compose.c.

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 95 of file compose.c.

const char* There_are_no_attachments = N_("There are no attachments")
static

Definition at line 97 of file compose.c.

int HeaderPadding[HDR_ATTACH_TITLE] = { 0 }

Definition at line 139 of file compose.c.

int MaxHeaderWidth = 0

Definition at line 140 of file compose.c.

const char* const Prompts[]
static

Definition at line 145 of file compose.c.

const struct Mapping ComposeHelp[]
static
Initial value:
= {
{ N_("Send"), OP_COMPOSE_SEND_MESSAGE },
{ N_("Abort"), OP_EXIT },
{ N_("To"), OP_COMPOSE_EDIT_TO },
{ N_("CC"), OP_COMPOSE_EDIT_CC },
{ N_("Subj"), OP_COMPOSE_EDIT_SUBJECT },
{ N_("Attach file"), OP_COMPOSE_ATTACH_FILE },
{ N_("Descrip"), OP_COMPOSE_EDIT_DESCRIPTION },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 188 of file compose.c.

struct Mapping ComposeNewsHelp[]
static
Initial value:
= {
{ N_("Send"), OP_COMPOSE_SEND_MESSAGE },
{ N_("Abort"), OP_EXIT },
{ N_("Newsgroups"), OP_COMPOSE_EDIT_NEWSGROUPS },
{ N_("Subj"), OP_COMPOSE_EDIT_SUBJECT },
{ N_("Attach file"), OP_COMPOSE_ATTACH_FILE },
{ N_("Descrip"), OP_COMPOSE_EDIT_DESCRIPTION },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 204 of file compose.c.

const char* AutocryptRecUiFlags[]
static
Initial value:
= {
N_("Off"),
N_("No"),
N_("Discouraged"),
N_("Available"),
N_("Yes"),
}
#define N_(a)
Definition: message.h:32

Definition at line 217 of file compose.c.