NeoMutt  2020-03-20-65-g141838
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/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "compose.h"
#include "alias.h"
#include "browser.h"
#include "commands.h"
#include "context.h"
#include "edit.h"
#include "format_flags.h"
#include "globals.h"
#include "hook.h"
#include "index.h"
#include "init.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "recvattach.h"
#include "rfc3676.h"
#include "sendlib.h"
#include "sort.h"
#include "ncrypt/lib.h"
#include <libintl.h>
#include "remailer.h"
#include "nntp/lib.h"
#include "pop/lib.h"
#include "imap/lib.h"
#include "autocrypt/lib.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   (rd->win->state.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_MIX,
  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 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 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::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 void redraw_mix_line (struct ListHead *chain, struct ComposeRedrawData *rd)
 Redraw the Mixmaster chain. 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, struct ComposeRedrawData *rd)
 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, struct ComposeRedrawData *rd)
 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_custom_redraw (struct Menu *menu)
 Redraw the compose menu - Implements 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...
 
static int mutt_dlg_compose_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the Compose menu - Implements observer_t. More...
 
int mutt_compose_menu (struct Email *e, struct Buffer *fcc, 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

◆ CHECK_COUNT

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

Definition at line 116 of file compose.c.

◆ CUR_ATTACH

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

Definition at line 123 of file compose.c.

◆ HDR_XOFFSET

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 159 of file compose.c.

◆ W

#define W   (rd->win->state.cols - MaxHeaderWidth)

Definition at line 160 of file compose.c.

◆ ALTS_TAG

#define ALTS_TAG   "Alternatives for \"%s\""

◆ LINGUAL_TAG

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

Enumeration Type Documentation

◆ HeaderField

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_MIX 

"Mix:" field (Mixmaster chain)

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

131 {
132  HDR_FROM = 0,
133  HDR_TO,
134  HDR_CC,
135  HDR_BCC,
136  HDR_SUBJECT,
137  HDR_REPLYTO,
138  HDR_FCC,
139 #ifdef MIXMASTER
140  HDR_MIX,
141 #endif
142  HDR_CRYPT,
143  HDR_CRYPTINFO,
144 #ifdef USE_AUTOCRYPT
146 #endif
147 #ifdef USE_NNTP
151 #endif
153  HDR_ATTACH
154 };
"To:" field
Definition: compose.c:133
"Cc:" field
Definition: compose.c:134
"Subject:" field
Definition: compose.c:136
"Sign as:" field (encryption/signing info)
Definition: compose.c:143
"From:" field
Definition: compose.c:132
The "-- Attachments" line.
Definition: compose.c:152
"X-Comment-To:" field
Definition: compose.c:150
"Security:" field (encryption/signing info)
Definition: compose.c:142
"Bcc:" field
Definition: compose.c:135
"Followup-To:" field
Definition: compose.c:149
"Mix:" field (Mixmaster chain)
Definition: compose.c:140
Where to start printing the attachments.
Definition: compose.c:153
"Newsgroups:" field
Definition: compose.c:148
"Fcc:" (save folder) field
Definition: compose.c:138
"Reply-To:" field
Definition: compose.c:137

Function Documentation

◆ compose_status_line()

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

1066 {
1067  mutt_expando_format(buf, buflen, col, cols, src, compose_format_str,
1068  (unsigned long) menu, MUTT_FORMAT_NO_FLAGS);
1069 }
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:863
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:1006
#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:

◆ calc_header_width_padding()

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

263 {
264  int width;
265 
266  HeaderPadding[idx] = mutt_str_strlen(header);
267  width = mutt_strwidth(header);
268  if (calc_max && (MaxHeaderWidth < width))
269  MaxHeaderWidth = width;
270  HeaderPadding[idx] -= width;
271 }
int MaxHeaderWidth
Definition: compose.c:157
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1337
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_header_padding()

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

282 {
283  static bool done = false;
284 
285  if (done)
286  return;
287  done = true;
288 
289  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
290  {
291  if (i == HDR_CRYPTINFO)
292  continue;
293  calc_header_width_padding(i, _(Prompts[i]), true);
294  }
295 
296  /* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
297  * doesn't show up by default, and so can make the indentation of
298  * the other fields look funny. */
300 
301  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
302  {
304  if (HeaderPadding[i] < 0)
305  HeaderPadding[i] = 0;
306  }
307 }
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:262
int MaxHeaderWidth
Definition: compose.c:157
#define _(a)
Definition: message.h:28
"Sign as:" field (encryption/signing info)
Definition: compose.c:143
The "-- Attachments" line.
Definition: compose.c:152
static const char *const Prompts[]
Definition: compose.c:162
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ snd_make_entry()

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::make_entry()

Definition at line 312 of file compose.c.

313 {
314  struct AttachCtx *actx = menu->data;
315 
316  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
318  (unsigned long) (actx->idx[actx->v2r[line]]),
320 }
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:863
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:101
#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
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
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:208
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int const char int line
Definition: acutest.h:602
struct MuttWindow * win_index
Definition: mutt_menu.h:95
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:

◆ autocrypt_compose_menu()

static void autocrypt_compose_menu ( struct Email e)
static

Autocrypt compose settings.

Parameters
eEmail

Definition at line 327 of file compose.c.

328 {
329  /* L10N: The compose menu autocrypt prompt.
330  (e)ncrypt enables encryption via autocrypt.
331  (c)lear sets cleartext.
332  (a)utomatic defers to the recommendation. */
333  const char *prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic?");
334 
336 
337  /* L10N: The letter corresponding to the compose menu autocrypt prompt
338  (e)ncrypt, (c)lear, (a)utomatic */
339  const char *letters = _("eca");
340 
341  int choice = mutt_multi_choice(prompt, letters);
342  switch (choice)
343  {
344  case 1:
347  break;
348  case 2:
349  e->security &= ~SEC_AUTOCRYPT;
351  break;
352  case 3:
355  e->security |= SEC_OPPENCRYPT;
356  break;
357  }
358 }
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
#define _(a)
Definition: message.h:28
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:132
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:911
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:268
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:135
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:133
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ redraw_crypt_lines()

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

366 {
367  struct Email *e = rd->email;
368 
371  _(Prompts[HDR_CRYPT]));
373 
375  {
376  mutt_window_addstr(_("Not supported"));
377  return;
378  }
379 
380  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
381  {
383  mutt_window_addstr(_("Sign, Encrypt"));
384  }
385  else if (e->security & SEC_ENCRYPT)
386  {
388  mutt_window_addstr(_("Encrypt"));
389  }
390  else if (e->security & SEC_SIGN)
391  {
393  mutt_window_addstr(_("Sign"));
394  }
395  else
396  {
397  /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
399  mutt_window_addstr(_("None"));
400  }
402 
403  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
404  {
405  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
406  {
407  if ((e->security & SEC_INLINE))
408  mutt_window_addstr(_(" (inline PGP)"));
409  else
410  mutt_window_addstr(_(" (PGP/MIME)"));
411  }
412  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
413  mutt_window_addstr(_(" (S/MIME)"));
414  }
415 
417  mutt_window_addstr(_(" (OppEnc mode)"));
418 
422 
423  if (((WithCrypto & APPLICATION_PGP) != 0) &&
424  (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
425  {
427  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
429  mutt_window_printf("%s", C_PgpSignAs ? C_PgpSignAs : _("<default>"));
430  }
431 
432  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
433  (e->security & APPLICATION_SMIME) && (e->security & SEC_SIGN))
434  {
436  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
438  mutt_window_printf("%s", C_SmimeSignAs ? C_SmimeSignAs : _("<default>"));
439  }
440 
441  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
443  {
445  mutt_window_mvprintw(rd->win, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
448  }
449 
450 #ifdef USE_AUTOCRYPT
453  if (C_Autocrypt)
454  {
456  mutt_window_printf("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
458  if (e->security & SEC_AUTOCRYPT)
459  {
461  mutt_window_addstr(_("Encrypt"));
462  }
463  else
464  {
466  mutt_window_addstr(_("Off"));
467  }
468 
470  mutt_window_mvprintw(rd->win, HDR_AUTOCRYPT, 40, "%s",
471  /* L10N: The autocrypt compose menu Recommendation field.
472  Displays the output of the recommendation engine
473  (Off, No, Discouraged, Available, Yes) */
474  _("Recommendation: "));
477  }
478 #endif
479 }
Mail will be encrypted.
Definition: color.h:68
#define NONULL(x)
Definition: string2.h:37
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
#define WithCrypto
Definition: lib.h:163
The envelope/body of an email.
Definition: email.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:134
#define _(a)
Definition: message.h:28
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
struct Email * email
Definition: compose.c:107
"Sign as:" field (encryption/signing info)
Definition: compose.c:143
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:132
enum AutocryptRec autocrypt_rec
Definition: compose.c:110
Plain text.
Definition: color.h:78
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:268
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
Header labels, e.g. From:
Definition: color.h:66
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:166
Mail will be signed.
Definition: color.h:70
"Security:" field (encryption/signing info)
Definition: compose.c:142
static const char *const Prompts[]
Definition: compose.c:162
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:133
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
Mail will be encrypted and signed.
Definition: color.h:67
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:458
struct MuttWindow * win
Definition: compose.c:113
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
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:311
Mail will not be encrypted or signed.
Definition: color.h:69
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:430
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:161
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:165
static const char * AutocryptRecUiFlags[]
Definition: compose.c:232
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_crypt_info()

static void update_crypt_info ( struct ComposeRedrawData rd)
static

Update the crypto info.

Parameters
rdEmail and other compose data

Definition at line 485 of file compose.c.

486 {
487  struct Email *e = rd->email;
488 
491 
492 #ifdef USE_AUTOCRYPT
493  if (C_Autocrypt)
494  {
496 
497  /* Anything that enables SEC_ENCRYPT or SEC_SIGN, or turns on SMIME
498  * overrides autocrypt, be it oppenc or the user having turned on
499  * those flags manually. */
502  else
503  {
504  if (!(e->security & SEC_AUTOCRYPT_OVERRIDE))
505  {
506  if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
507  {
510  }
511  else
512  e->security &= ~SEC_AUTOCRYPT;
513  }
514  }
515  }
516 #endif
517 
518  redraw_crypt_lines(rd);
519 }
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
The envelope/body of an email.
Definition: email.h:37
Autocrypt should be used.
Definition: lib.h:107
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
struct Email * email
Definition: compose.c:107
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:132
enum AutocryptRec autocrypt_rec
Definition: compose.c:110
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:268
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:135
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:365
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1036
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:552
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ redraw_mix_line()

static void redraw_mix_line ( struct ListHead *  chain,
struct ComposeRedrawData rd 
)
static

Redraw the Mixmaster chain.

Parameters
chainList of chain links
rdEmail and other compose data

Definition at line 527 of file compose.c.

528 {
529  char *t = NULL;
530 
533  _(Prompts[HDR_MIX]));
535 
536  if (STAILQ_EMPTY(chain))
537  {
538  mutt_window_addstr(_("<no chain defined>"));
540  return;
541  }
542 
543  int c = 12;
544  struct ListNode *np = NULL;
545  STAILQ_FOREACH(np, chain, entries)
546  {
547  t = np->data;
548  if (t && (t[0] == '0') && (t[1] == '\0'))
549  t = "<random>";
550 
551  if (c + mutt_str_strlen(t) + 2 >= rd->win->state.cols)
552  break;
553 
555  if (STAILQ_NEXT(np, entries))
556  mutt_window_addstr(", ");
557 
558  c += mutt_str_strlen(t) + 2;
559  }
560 }
#define NONULL(x)
Definition: string2.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:134
#define _(a)
Definition: message.h:28
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
Plain text.
Definition: color.h:78
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct ListHead chain
Mixmaster chain.
Definition: email.h:99
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
Header labels, e.g. From:
Definition: color.h:66
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
static const char *const Prompts[]
Definition: compose.c:162
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
char * data
String.
Definition: list.h:35
struct MuttWindow * win
Definition: compose.c:113
"Mix:" field (Mixmaster chain)
Definition: compose.c:140
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
#define STAILQ_EMPTY(head)
Definition: queue.h:345
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:311
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:430
A List node for strings.
Definition: list.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_attachments()

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  int rc = -1;
572  struct stat st;
573  struct Buffer *pretty = NULL, *msg = NULL;
574 
575  for (int i = 0; i < actx->idxlen; i++)
576  {
577  if (actx->idx[i]->content->type == TYPE_MULTIPART)
578  continue;
579  if (stat(actx->idx[i]->content->filename, &st) != 0)
580  {
581  if (!pretty)
582  pretty = mutt_buffer_pool_get();
583  mutt_buffer_strcpy(pretty, actx->idx[i]->content->filename);
585  /* L10N: This message is displayed in the compose menu when an attachment
586  doesn't stat. %d is the attachment number and %s is the attachment
587  filename. The filename is located last to avoid a long path hiding
588  the error message. */
589  mutt_error(_("Attachment #%d no longer exists: %s"), i + 1, mutt_b2s(pretty));
590  goto cleanup;
591  }
592 
593  if (actx->idx[i]->content->stamp < st.st_mtime)
594  {
595  if (!pretty)
596  pretty = mutt_buffer_pool_get();
597  mutt_buffer_strcpy(pretty, actx->idx[i]->content->filename);
599 
600  if (!msg)
601  msg = mutt_buffer_pool_get();
602  /* L10N: This message is displayed in the compose menu when an attachment
603  is modified behind the scenes. %d is the attachment number and %s is
604  the attachment filename. The filename is located last to avoid a long
605  path hiding the prompt question. */
606  mutt_buffer_printf(msg, _("Attachment #%d modified. Update encoding for %s?"),
607  i + 1, mutt_b2s(pretty));
608 
609  enum QuadOption ans = mutt_yesorno(mutt_b2s(msg), MUTT_YES);
610  if (ans == MUTT_YES)
611  mutt_update_encoding(actx->idx[i]->content);
612  else if (ans == MUTT_ABORT)
613  goto cleanup;
614  }
615  }
616 
617  rc = 0;
618 
619 cleanup:
620  mutt_buffer_pool_release(&pretty);
622  return rc;
623 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
User aborted the question (with Ctrl-G)
Definition: quad.h:38
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
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:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope_addr()

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

Write addresses to the compose window.

Parameters
lineLine to write to (index into Prompts)
alAddress list to write
rdEmail and other compose data

Definition at line 631 of file compose.c.

632 {
633  char buf[1024];
634 
635  buf[0] = '\0';
636  mutt_addrlist_write(al, buf, sizeof(buf), true);
638  mutt_window_mvprintw(rd->win, line, 0, "%*s", HeaderPadding[line], _(Prompts[line]));
640  mutt_paddstr(W, buf);
641 }
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
#define _(a)
Definition: message.h:28
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1244
Plain text.
Definition: color.h:78
Header labels, e.g. From:
Definition: color.h:66
static const char *const Prompts[]
Definition: compose.c:162
#define W
Definition: compose.c:160
struct MuttWindow * win
Definition: compose.c:113
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
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:311
int const char int line
Definition: acutest.h:602
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope()

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

648 {
649  struct Email *e = rd->email;
650  const char *fcc = mutt_b2s(rd->fcc);
651 
652  draw_envelope_addr(HDR_FROM, &e->env->from, rd);
653 #ifdef USE_NNTP
654  if (!OptNewsSend)
655  {
656 #endif
657  draw_envelope_addr(HDR_TO, &e->env->to, rd);
658  draw_envelope_addr(HDR_CC, &e->env->cc, rd);
659  draw_envelope_addr(HDR_BCC, &e->env->bcc, rd);
660 #ifdef USE_NNTP
661  }
662  else
663  {
664  mutt_window_mvprintw(rd->win, HDR_TO, 0, "%*s",
665  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
667  mutt_window_mvprintw(rd->win, HDR_CC, 0, "%*s",
668  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
670  if (C_XCommentTo)
671  {
672  mutt_window_mvprintw(rd->win, HDR_BCC, 0, "%*s",
673  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
675  }
676  }
677 #endif
678 
680  mutt_window_mvprintw(rd->win, HDR_SUBJECT, 0, "%*s",
681  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
684 
686 
689  _(Prompts[HDR_FCC]));
691  mutt_paddstr(W, fcc);
692 
693  if (WithCrypto)
694  redraw_crypt_lines(rd);
695 
696 #ifdef MIXMASTER
697  redraw_mix_line(&e->chain, rd);
698 #endif
699 
701  mutt_window_mvaddstr(rd->win, HDR_ATTACH_TITLE, 0, _("-- Attachments"));
703 
705 }
#define NONULL(x)
Definition: string2.h:37
#define WithCrypto
Definition: lib.h:163
The envelope/body of an email.
Definition: email.h:37
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
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:134
"To:" field
Definition: compose.c:133
"Cc:" field
Definition: compose.c:134
#define _(a)
Definition: message.h:28
struct Email * email
Definition: compose.c:107
struct Buffer * fcc
Definition: compose.c:108
"Subject:" field
Definition: compose.c:136
"From:" field
Definition: compose.c:132
The "-- Attachments" line.
Definition: compose.c:152
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1244
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
"X-Comment-To:" field
Definition: compose.c:150
Plain text.
Definition: color.h:78
#define mutt_b2s(buf)
Definition: buffer.h:41
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
struct ListHead chain
Mixmaster chain.
Definition: email.h:99
Status bar (takes a pattern)
Definition: color.h:95
Header labels, e.g. From:
Definition: color.h:66
static void redraw_mix_line(struct ListHead *chain, struct ComposeRedrawData *rd)
Redraw the Mixmaster chain.
Definition: compose.c:527
static void draw_envelope_addr(int line, struct AddressList *al, struct ComposeRedrawData *rd)
Write addresses to the compose window.
Definition: compose.c:631
static const char *const Prompts[]
Definition: compose.c:162
#define W
Definition: compose.c:160
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:292
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:365
"Bcc:" field
Definition: compose.c:135
"Followup-To:" field
Definition: compose.c:149
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct MuttWindow * win
Definition: compose.c:113
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:283
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
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:311
"Newsgroups:" field
Definition: compose.c:148
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
"Fcc:" (save folder) field
Definition: compose.c:138
"Reply-To:" field
Definition: compose.c:137
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ edit_address_list()

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

Let the user edit the address list.

Parameters
[in]lineIndex into the Prompts lists
[in,out]alAddressList to edit
rdEmail and other compose data

Definition at line 713 of file compose.c.

714 {
715  char buf[8192] = { 0 }; /* needs to be large for alias expansion */
716  char *err = NULL;
717 
719  mutt_addrlist_write(al, buf, sizeof(buf), false);
720  if (mutt_get_field(_(Prompts[line]), buf, sizeof(buf), MUTT_ALIAS) == 0)
721  {
723  mutt_addrlist_parse2(al, buf);
725  }
726 
727  if (mutt_addrlist_to_intl(al, &err) != 0)
728  {
729  mutt_error(_("Bad IDN: '%s'"), err);
730  mutt_refresh();
731  FREE(&err);
732  }
733 
734  /* redraw the expanded list so the user can see the result */
735  buf[0] = '\0';
736  mutt_addrlist_write(al, buf, sizeof(buf), true);
737  mutt_window_move(rd->win, line, HDR_XOFFSET);
738  mutt_paddstr(W, buf);
739 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1299
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
#define _(a)
Definition: message.h:28
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:607
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1244
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:107
#define HDR_XOFFSET
Definition: compose.c:159
static const char *const Prompts[]
Definition: compose.c:162
#define W
Definition: compose.c:160
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
struct MuttWindow * win
Definition: compose.c:113
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1217
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
int const char int line
Definition: acutest.h:602
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete_attachment()

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

749 {
750  struct AttachPtr **idx = actx->idx;
751  int rindex = actx->v2r[x];
752 
753  if ((rindex == 0) && (actx->idxlen == 1))
754  {
755  mutt_error(_("You may not delete the only attachment"));
756  idx[rindex]->content->tagged = false;
757  return -1;
758  }
759 
760  for (int y = 0; y < actx->idxlen; y++)
761  {
762  if (idx[y]->content->next == idx[rindex]->content)
763  {
764  idx[y]->content->next = idx[rindex]->content->next;
765  break;
766  }
767  }
768 
769  idx[rindex]->content->next = NULL;
770  /* mutt_make_message_attach() creates body->parts, shared by
771  * body->email->content. If we NULL out that, it creates a memory
772  * leak because mutt_free_body() frees body->parts, not
773  * body->email->content.
774  *
775  * Other ci_send_message() message constructors are careful to free
776  * any body->parts, removing depth:
777  * - mutt_prepare_template() used by postponed, resent, and draft files
778  * - mutt_copy_body() used by the recvattach menu and $forward_attachments.
779  *
780  * I believe it is safe to completely remove the "content->parts =
781  * NULL" statement. But for safety, am doing so only for the case
782  * it must be avoided: message attachments.
783  */
784  if (!idx[rindex]->content->email)
785  idx[rindex]->content->parts = NULL;
786  mutt_body_free(&(idx[rindex]->content));
787  FREE(&idx[rindex]->tree);
788  FREE(&idx[rindex]);
789  for (; rindex < actx->idxlen - 1; rindex++)
790  idx[rindex] = idx[rindex + 1];
791  idx[actx->idxlen - 1] = NULL;
792  actx->idxlen--;
793 
794  return 0;
795 }
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
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
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct Email * email
header information for message/rfc822
Definition: body.h:55
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:

◆ mutt_gen_compose_attach_list()

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

806 {
807  for (; m; m = m->next)
808  {
809  if ((m->type == TYPE_MULTIPART) && m->parts &&
811  {
813  }
814  else
815  {
816  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
817  mutt_actx_add_attach(actx, ap);
818  ap->content = m;
819  m->aptr = ap;
820  ap->parent_type = parent_type;
821  ap->level = level;
822 
823  /* We don't support multipart messages in the compose menu yet */
824  }
825  }
826 }
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
#define WithCrypto
Definition: lib.h:163
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:804
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:459
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
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
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
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:

◆ mutt_update_compose_menu()

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

835 {
836  if (init)
837  {
838  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
839  mutt_attach_init(actx);
840  menu->data = actx;
841  }
842 
843  mutt_update_tree(actx);
844 
845  menu->max = actx->vcount;
846  if (menu->max)
847  {
848  if (menu->current >= menu->max)
849  menu->current = menu->max - 1;
850  }
851  else
852  menu->current = 0;
853 
854  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
855 }
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
struct Body * content
List of MIME parts.
Definition: email.h:90
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:804
#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:1330
int max
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:142
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:

◆ update_idx()

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

864 {
865  ap->level = (actx->idxlen > 0) ? actx->idx[actx->idxlen - 1]->level : 0;
866  if (actx->idxlen)
867  actx->idx[actx->idxlen - 1]->content->next = ap->content;
868  ap->content->aptr = ap;
869  mutt_actx_add_attach(actx, ap);
870  mutt_update_compose_menu(actx, menu, false);
871  menu->current = actx->vcount - 1;
872 }
if(!test_colorize_)
Definition: acutest.h:484
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:834
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:

◆ compose_custom_redraw()

static void compose_custom_redraw ( struct Menu menu)
static

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

Definition at line 877 of file compose.c.

878 {
879  struct ComposeRedrawData *rd = menu->redraw_data;
880 
881  if (!rd)
882  return;
883 
884  if (menu->redraw & REDRAW_FULL)
885  {
886  menu_redraw_full(menu);
887 
888  draw_envelope(rd);
889  menu->offset = HDR_ATTACH;
890  menu->pagelen = menu->win_index->state.rows - HDR_ATTACH;
891  }
892 
893  menu_check_recenter(menu);
894 
895  if (menu->redraw & REDRAW_STATUS)
896  {
897  char buf[1024];
898  compose_status_line(buf, sizeof(buf), 0, menu->win_ibar->state.cols, menu,
900  mutt_window_move(menu->win_ibar, 0, 0);
902  mutt_draw_statusline(menu->win_ibar->state.cols, buf, sizeof(buf));
904  menu->redraw &= ~REDRAW_STATUS;
905  }
906 
907 #ifdef USE_SIDEBAR
908  if (menu->redraw & REDRAW_SIDEBAR)
909  menu_redraw_sidebar(menu);
910 #endif
911 
912  if (menu->redraw & REDRAW_INDEX)
913  menu_redraw_index(menu);
914  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNC))
915  menu_redraw_motion(menu);
916  else if (menu->redraw == REDRAW_CURRENT)
917  menu_redraw_current(menu);
918 }
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
#define NONULL(x)
Definition: string2.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
void * redraw_data
Definition: mutt_menu.h:155
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
static void draw_envelope(struct ComposeRedrawData *rd)
Write the email headers to the compose window.
Definition: compose.c:647
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:1064
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:43
Plain text.
Definition: color.h:78
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
Status bar (takes a pattern)
Definition: color.h:95
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
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
Where to start printing the attachments.
Definition: compose.c:153
char * C_ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:93
struct MuttWindow * win_index
Definition: mutt_menu.h:95
Keep track when the compose screen needs redrawing.
Definition: compose.c:105
void mutt_draw_statusline(int cols, const char *buf, size_t buflen)
Draw a highlighted status bar.
Definition: index.c:929
#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:

◆ compose_attach_swap()

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

927 {
928  /* Reorder Body pointers.
929  * Must traverse msg from top since Body has no previous ptr. */
930  for (struct Body *part = msg; part; part = part->next)
931  {
932  if (part->next == idx[first]->content)
933  {
934  idx[first]->content->next = idx[first + 1]->content->next;
935  idx[first + 1]->content->next = idx[first]->content;
936  part->next = idx[first + 1]->content;
937  break;
938  }
939  }
940 
941  /* Reorder index */
942  struct AttachPtr *saved = idx[first];
943  idx[first] = idx[first + 1];
944  idx[first + 1] = saved;
945 
946  /* Swap ptr->num */
947  int i = idx[first]->num;
948  idx[first]->num = idx[first + 1]->num;
949  idx[first + 1]->num = i;
950 }
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:

◆ cum_attachs_size()

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

961 {
962  size_t s = 0;
963  struct AttachCtx *actx = menu->data;
964  struct AttachPtr **idx = actx->idx;
965  struct Content *info = NULL;
966  struct Body *b = NULL;
967 
968  for (unsigned short i = 0; i < actx->idxlen; i++)
969  {
970  b = idx[i]->content;
971 
972  if (!b->content)
974 
975  info = b->content;
976  if (info)
977  {
978  switch (b->encoding)
979  {
981  s += 3 * (info->lobin + info->hibin) + info->ascii + info->crlf;
982  break;
983  case ENC_BASE64:
984  s += (4 * (info->lobin + info->hibin + info->ascii + info->crlf)) / 3;
985  break;
986  default:
987  s += info->lobin + info->hibin + info->ascii + info->crlf;
988  break;
989  }
990  }
991  }
992 
993  return s;
994 }
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:1031
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:

◆ compose_format_str()

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

1010 {
1011  char fmt[128], tmp[128];
1012  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
1013  struct Menu *menu = (struct Menu *) data;
1014 
1015  *buf = '\0';
1016  switch (op)
1017  {
1018  case 'a': /* total number of attachments */
1019  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1020  snprintf(buf, buflen, fmt, menu->max);
1021  break;
1022 
1023  case 'h': /* hostname */
1024  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1025  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
1026  break;
1027 
1028  case 'l': /* approx length of current message in bytes */
1029  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1030  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
1031  snprintf(buf, buflen, fmt, tmp);
1032  break;
1033 
1034  case 'v':
1035  snprintf(buf, buflen, "%s", mutt_make_version());
1036  break;
1037 
1038  case 0:
1039  *buf = '\0';
1040  return src;
1041 
1042  default:
1043  snprintf(buf, buflen, "%%%s%c", prec, op);
1044  break;
1045  }
1046 
1047  if (optional)
1048  compose_status_line(buf, buflen, col, cols, menu, if_str);
1049  else if (flags & MUTT_FORMAT_OPTIONAL)
1050  compose_status_line(buf, buflen, col, cols, menu, else_str);
1051 
1052  return src;
1053 }
#define NONULL(x)
Definition: string2.h:37
GUI selectable list of items.
Definition: mutt_menu.h:82
static int const char * fmt
Definition: acutest.h:473
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:1064
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1751
int max
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:960
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:50
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:1549
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlg_compose_observer()

static int mutt_dlg_compose_observer ( struct NotifyCallback nc)
static

Listen for config changes affecting the Compose menu - Implements observer_t.

Definition at line 1074 of file compose.c.

1075 {
1076  if (!nc->event_data || !nc->global_data)
1077  return -1;
1078  if (nc->event_type != NT_CONFIG)
1079  return 0;
1080 
1081  struct EventConfig *ec = nc->event_data;
1082  struct MuttWindow *dlg = nc->global_data;
1083 
1084  if (mutt_str_strcmp(ec->name, "status_on_top") != 0)
1085  return 0;
1086 
1087  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
1088 
1089  if ((C_StatusOnTop && (win_first->type == WT_INDEX)) ||
1090  (!C_StatusOnTop && (win_first->type != WT_INDEX)))
1091  {
1092  // Swap the Index and the IndexBar Windows
1093  TAILQ_REMOVE(&dlg->children, win_first, entries);
1094  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
1095  }
1096 
1097  mutt_window_reflow(dlg);
1098  return 0;
1099 }
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:252
#define TAILQ_FIRST(head)
Definition: queue.h:716
A config-change event.
Definition: subset.h:70
A division of the screen.
Definition: mutt_window.h:88
An Index Window containing a selection list.
Definition: mutt_window.h:74
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:41
void * global_data
Data from notify_observer_add()
Definition: observer.h:44
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:43
Config has changed.
Definition: notify_type.h:34
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:345
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:101
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:103
const char * name
Name of config item that changed.
Definition: subset.h:73
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_compose_menu()

int mutt_compose_menu ( struct Email e,
struct Buffer fcc,
struct Email e_cur,
int  flags 
)

Allow the user to edit the message envelope.

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

Definition at line 1111 of file compose.c.

1112 {
1113  char helpstr[1024]; // This isn't copied by the help bar
1114  char buf[PATH_MAX];
1115  int rc = -1;
1116  bool loop = true;
1117  bool fcc_set = false; /* has the user edited the Fcc: field ? */
1118  struct ComposeRedrawData redraw = { 0 };
1119  struct ComposeRedrawData *rd = &redraw;
1120 #ifdef USE_NNTP
1121  bool news = OptNewsSend; /* is it a news article ? */
1122 #endif
1123 
1125 
1126  struct MuttWindow *dlg =
1129 #ifdef USE_DEBUG_WINDOW
1130  dlg->name = "compose";
1131 #endif
1132  dlg->type = WT_DIALOG;
1133  struct MuttWindow *index =
1136  index->type = WT_INDEX;
1137  struct MuttWindow *ibar = mutt_window_new(
1139  ibar->type = WT_INDEX_BAR;
1140 
1141  rd->email = e;
1142  rd->fcc = fcc;
1143  rd->win = index;
1144 
1145  if (C_StatusOnTop)
1146  {
1147  mutt_window_add_child(dlg, ibar);
1148  mutt_window_add_child(dlg, index);
1149  }
1150  else
1151  {
1152  mutt_window_add_child(dlg, index);
1153  mutt_window_add_child(dlg, ibar);
1154  }
1155 
1157  dialog_push(dlg);
1158 
1159  struct Menu *menu = mutt_menu_new(MENU_COMPOSE);
1160 
1161  menu->pagelen = index->state.rows;
1162  menu->win_index = index;
1163  menu->win_ibar = ibar;
1164 
1165  menu->offset = HDR_ATTACH;
1166  menu->make_entry = snd_make_entry;
1167  menu->tag = attach_tag;
1168 #ifdef USE_NNTP
1169  if (news)
1170  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeNewsHelp);
1171  else
1172 #endif
1173  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeHelp);
1175  menu->redraw_data = rd;
1176  mutt_menu_push_current(menu);
1177 
1178  struct AttachCtx *actx = mutt_actx_new();
1179  actx->email = e;
1180  mutt_update_compose_menu(actx, menu, true);
1181 
1182  update_crypt_info(rd);
1183 
1184  /* Since this is rather long lived, we don't use the pool */
1185  struct Buffer fname = mutt_buffer_make(PATH_MAX);
1186 
1187  while (loop)
1188  {
1189 #ifdef USE_NNTP
1190  OptNews = false; /* for any case */
1191 #endif
1192  const int op = mutt_menu_loop(menu);
1193  switch (op)
1194  {
1195  case OP_COMPOSE_EDIT_FROM:
1196  edit_address_list(HDR_FROM, &e->env->from, rd);
1197  update_crypt_info(rd);
1199  break;
1200 
1201  case OP_COMPOSE_EDIT_TO:
1202 #ifdef USE_NNTP
1203  if (news)
1204  break;
1205 #endif
1206  edit_address_list(HDR_TO, &e->env->to, rd);
1207  update_crypt_info(rd);
1209  break;
1210 
1211  case OP_COMPOSE_EDIT_BCC:
1212 #ifdef USE_NNTP
1213  if (news)
1214  break;
1215 #endif
1216  edit_address_list(HDR_BCC, &e->env->bcc, rd);
1217  update_crypt_info(rd);
1219  break;
1220 
1221  case OP_COMPOSE_EDIT_CC:
1222 #ifdef USE_NNTP
1223  if (news)
1224  break;
1225 #endif
1226  edit_address_list(HDR_CC, &e->env->cc, rd);
1227  update_crypt_info(rd);
1229  break;
1230 #ifdef USE_NNTP
1231  case OP_COMPOSE_EDIT_NEWSGROUPS:
1232  if (!news)
1233  break;
1234  if (e->env->newsgroups)
1235  mutt_str_strfcpy(buf, e->env->newsgroups, sizeof(buf));
1236  else
1237  buf[0] = '\0';
1238  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1239  {
1240  mutt_str_replace(&e->env->newsgroups, buf);
1242  if (e->env->newsgroups)
1243  mutt_paddstr(W, e->env->newsgroups);
1244  else
1246  }
1247  break;
1248 
1249  case OP_COMPOSE_EDIT_FOLLOWUP_TO:
1250  if (!news)
1251  break;
1252  if (e->env->followup_to)
1253  mutt_str_strfcpy(buf, e->env->followup_to, sizeof(buf));
1254  else
1255  buf[0] = '\0';
1256  if (mutt_get_field("Followup-To: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1257  {
1258  mutt_str_replace(&e->env->followup_to, buf);
1260  if (e->env->followup_to)
1261  mutt_paddstr(W, e->env->followup_to);
1262  else
1264  }
1265  break;
1266 
1267  case OP_COMPOSE_EDIT_X_COMMENT_TO:
1268  if (!(news && C_XCommentTo))
1269  break;
1270  if (e->env->x_comment_to)
1271  mutt_str_strfcpy(buf, e->env->x_comment_to, sizeof(buf));
1272  else
1273  buf[0] = '\0';
1274  if (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1275  {
1276  mutt_str_replace(&e->env->x_comment_to, buf);
1278  if (e->env->x_comment_to)
1280  else
1282  }
1283  break;
1284 #endif
1285 
1286  case OP_COMPOSE_EDIT_SUBJECT:
1287  if (e->env->subject)
1288  mutt_str_strfcpy(buf, e->env->subject, sizeof(buf));
1289  else
1290  buf[0] = '\0';
1291  if (mutt_get_field(_("Subject: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1292  {
1293  mutt_str_replace(&e->env->subject, buf);
1295  if (e->env->subject)
1296  mutt_paddstr(W, e->env->subject);
1297  else
1299  }
1301  break;
1302 
1303  case OP_COMPOSE_EDIT_REPLY_TO:
1306  break;
1307 
1308  case OP_COMPOSE_EDIT_FCC:
1309  mutt_buffer_copy(&fname, fcc);
1310  if (mutt_buffer_get_field(_("Fcc: "), &fname, MUTT_FILE | MUTT_CLEAR) == 0)
1311  {
1312  mutt_buffer_copy(fcc, &fname);
1315  mutt_paddstr(W, mutt_b2s(fcc));
1316  fcc_set = true;
1317  }
1319  break;
1320 
1321  case OP_COMPOSE_EDIT_MESSAGE:
1322  if (C_Editor && (mutt_str_strcmp("builtin", C_Editor) != 0) && !C_EditHeaders)
1323  {
1328  menu->redraw = REDRAW_FULL;
1330  break;
1331  }
1332  /* fallthrough */
1333 
1334  case OP_COMPOSE_EDIT_HEADERS:
1336  if ((mutt_str_strcmp("builtin", C_Editor) != 0) &&
1337  ((op == OP_COMPOSE_EDIT_HEADERS) || ((op == OP_COMPOSE_EDIT_MESSAGE) && C_EditHeaders)))
1338  {
1339  const char *tag = NULL;
1340  char *err = NULL;
1341  mutt_env_to_local(e->env);
1343  if (mutt_env_to_intl(e->env, &tag, &err))
1344  {
1345  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
1346  FREE(&err);
1347  }
1348  update_crypt_info(rd);
1349  }
1350  else
1351  {
1352  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
1353  * attachment list could change if the user invokes ~v to edit
1354  * the message with headers, in which we need to execute the
1355  * code below to regenerate the index array */
1356  mutt_builtin_editor(e->content->filename, e, e_cur);
1357  }
1358 
1361 
1362  /* attachments may have been added */
1363  if (actx->idxlen && actx->idx[actx->idxlen - 1]->content->next)
1364  {
1365  mutt_actx_entries_free(actx);
1366  mutt_update_compose_menu(actx, menu, true);
1367  }
1368 
1369  menu->redraw = REDRAW_FULL;
1371  break;
1372 
1373  case OP_COMPOSE_ATTACH_KEY:
1374  {
1375  if (!(WithCrypto & APPLICATION_PGP))
1376  break;
1377  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1379  if (ap->content)
1380  {
1381  update_idx(menu, actx, ap);
1382  menu->redraw |= REDRAW_INDEX;
1383  }
1384  else
1385  FREE(&ap);
1386 
1387  menu->redraw |= REDRAW_STATUS;
1388 
1390  break;
1391  }
1392 
1393  case OP_COMPOSE_MOVE_UP:
1394  if (menu->current == 0)
1395  {
1396  mutt_error(_("Attachment is already at top"));
1397  break;
1398  }
1399  if (menu->current == 1)
1400  {
1401  mutt_error(_("The fundamental part can't be moved"));
1402  break;
1403  }
1404  compose_attach_swap(e->content, actx->idx, menu->current - 1);
1405  menu->redraw = REDRAW_INDEX;
1406  menu->current--;
1407  break;
1408 
1409  case OP_COMPOSE_MOVE_DOWN:
1410  if (menu->current == (actx->idxlen - 1))
1411  {
1412  mutt_error(_("Attachment is already at bottom"));
1413  break;
1414  }
1415  if (menu->current == 0)
1416  {
1417  mutt_error(_("The fundamental part can't be moved"));
1418  break;
1419  }
1420  compose_attach_swap(e->content, actx->idx, menu->current);
1421  menu->redraw = REDRAW_INDEX;
1422  menu->current++;
1423  break;
1424 
1425  case OP_COMPOSE_GROUP_ALTS:
1426  {
1427  if (menu->tagged < 2)
1428  {
1429  mutt_error(
1430  _("Grouping 'alternatives' requires at least 2 tagged messages"));
1431  break;
1432  }
1433 
1434  struct Body *group = mutt_body_new();
1435  group->type = TYPE_MULTIPART;
1436  group->subtype = mutt_str_strdup("alternative");
1437  group->disposition = DISP_INLINE;
1438 
1439  struct Body *alts = NULL;
1440  /* group tagged message into a multipart/alternative */
1441  struct Body *bptr = e->content;
1442  for (int i = 0; bptr;)
1443  {
1444  if (bptr->tagged)
1445  {
1446  bptr->tagged = false;
1447  bptr->disposition = DISP_INLINE;
1448 
1449  /* for first match, set group desc according to match */
1450 #define ALTS_TAG "Alternatives for \"%s\""
1451  if (!group->description)
1452  {
1453  char *p = bptr->description ? bptr->description : bptr->filename;
1454  if (p)
1455  {
1456  group->description =
1457  mutt_mem_calloc(1, strlen(p) + strlen(ALTS_TAG) + 1);
1458  sprintf(group->description, ALTS_TAG, p);
1459  }
1460  }
1461 
1462  // append bptr to the alts list, and remove from the e->content list
1463  if (alts)
1464  {
1465  alts->next = bptr;
1466  bptr = bptr->next;
1467  alts = alts->next;
1468  alts->next = NULL;
1469  }
1470  else
1471  {
1472  group->parts = bptr;
1473  alts = bptr;
1474  bptr = bptr->next;
1475  alts->next = NULL;
1476  }
1477 
1478  for (int j = i; j < actx->idxlen - 1; j++)
1479  {
1480  actx->idx[j] = actx->idx[j + 1];
1481  actx->idx[j + 1] = NULL; /* for debug reason */
1482  }
1483  actx->idxlen--;
1484  }
1485  else
1486  {
1487  bptr = bptr->next;
1488  i++;
1489  }
1490  }
1491 
1492  group->next = NULL;
1494 
1495  /* if no group desc yet, make one up */
1496  if (!group->description)
1497  group->description = mutt_str_strdup("unknown alternative group");
1498 
1499  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1500  gptr->content = group;
1501  update_idx(menu, actx, gptr);
1502  menu->redraw = REDRAW_INDEX;
1503  break;
1504  }
1505 
1506  case OP_COMPOSE_GROUP_LINGUAL:
1507  {
1508  if (menu->tagged < 2)
1509  {
1510  mutt_error(
1511  _("Grouping 'multilingual' requires at least 2 tagged messages"));
1512  break;
1513  }
1514 
1515  /* traverse to see whether all the parts have Content-Language: set */
1516  int tagged_with_lang_num = 0;
1517  for (struct Body *b = e->content; b; b = b->next)
1518  if (b->tagged && b->language && *b->language)
1519  tagged_with_lang_num++;
1520 
1521  if (menu->tagged != tagged_with_lang_num)
1522  {
1523  if (mutt_yesorno(
1524  _("Not all parts have 'Content-Language' set, continue?"), MUTT_YES) != MUTT_YES)
1525  {
1526  mutt_message(_("Not sending this message"));
1527  break;
1528  }
1529  }
1530 
1531  struct Body *group = mutt_body_new();
1532  group->type = TYPE_MULTIPART;
1533  group->subtype = mutt_str_strdup("multilingual");
1534  group->disposition = DISP_INLINE;
1535 
1536  struct Body *alts = NULL;
1537  /* group tagged message into a multipart/multilingual */
1538  struct Body *bptr = e->content;
1539  for (int i = 0; bptr;)
1540  {
1541  if (bptr->tagged)
1542  {
1543  bptr->tagged = false;
1544  bptr->disposition = DISP_INLINE;
1545 
1546  /* for first match, set group desc according to match */
1547 #define LINGUAL_TAG "Multilingual part for \"%s\""
1548  if (!group->description)
1549  {
1550  char *p = bptr->description ? bptr->description : bptr->filename;
1551  if (p)
1552  {
1553  group->description =
1554  mutt_mem_calloc(1, strlen(p) + strlen(LINGUAL_TAG) + 1);
1555  sprintf(group->description, LINGUAL_TAG, p);
1556  }
1557  }
1558 
1559  // append bptr to the alts list, and remove from the e->content list
1560  if (alts)
1561  {
1562  alts->next = bptr;
1563  bptr = bptr->next;
1564  alts = alts->next;
1565  alts->next = NULL;
1566  }
1567  else
1568  {
1569  group->parts = bptr;
1570  alts = bptr;
1571  bptr = bptr->next;
1572  alts->next = NULL;
1573  }
1574 
1575  for (int j = i; j < actx->idxlen - 1; j++)
1576  {
1577  actx->idx[j] = actx->idx[j + 1];
1578  actx->idx[j + 1] = NULL; /* for debug reason */
1579  }
1580  actx->idxlen--;
1581  }
1582  else
1583  {
1584  bptr = bptr->next;
1585  i++;
1586  }
1587  }
1588 
1589  group->next = NULL;
1591 
1592  /* if no group desc yet, make one up */
1593  if (!group->description)
1594  group->description = mutt_str_strdup("unknown multilingual group");
1595 
1596  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1597  gptr->content = group;
1598  update_idx(menu, actx, gptr);
1599  menu->redraw = REDRAW_INDEX;
1600  break;
1601  }
1602 
1603  case OP_COMPOSE_ATTACH_FILE:
1604  {
1605  char *prompt = _("Attach file");
1606  int numfiles = 0;
1607  char **files = NULL;
1608 
1609  mutt_buffer_reset(&fname);
1610  if ((mutt_buffer_enter_fname_full(prompt, &fname, false, true, &files,
1611  &numfiles, MUTT_SEL_MULTI) == -1) ||
1612  mutt_buffer_is_empty(&fname))
1613  {
1614  break;
1615  }
1616 
1617  bool error = false;
1618  if (numfiles > 1)
1619  {
1620  mutt_message(ngettext("Attaching selected file...",
1621  "Attaching selected files...", numfiles));
1622  }
1623  for (int i = 0; i < numfiles; i++)
1624  {
1625  char *att = files[i];
1626  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1627  ap->unowned = true;
1628  ap->content = mutt_make_file_attach(att);
1629  if (ap->content)
1630  update_idx(menu, actx, ap);
1631  else
1632  {
1633  error = true;
1634  mutt_error(_("Unable to attach %s"), att);
1635  FREE(&ap);
1636  }
1637  FREE(&files[i]);
1638  }
1639 
1640  FREE(&files);
1641  if (!error)
1642  mutt_clear_error();
1643 
1644  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1646  break;
1647  }
1648 
1649  case OP_COMPOSE_ATTACH_MESSAGE:
1650 #ifdef USE_NNTP
1651  case OP_COMPOSE_ATTACH_NEWS_MESSAGE:
1652 #endif
1653  {
1654  mutt_buffer_reset(&fname);
1655  char *prompt = _("Open mailbox to attach message from");
1656 
1657 #ifdef USE_NNTP
1658  OptNews = false;
1659  if (Context && (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE))
1660  {
1662  if (!CurrentNewsSrv)
1663  break;
1664 
1665  prompt = _("Open newsgroup to attach message from");
1666  OptNews = true;
1667  }
1668 #endif
1669 
1670  if (Context)
1671  {
1672 #ifdef USE_NNTP
1673  if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->mailbox->type == MUTT_NNTP))
1674 #endif
1675  {
1678  }
1679  }
1680 
1681  if ((mutt_buffer_enter_fname(prompt, &fname, true) == -1) ||
1682  mutt_buffer_is_empty(&fname))
1683  {
1684  break;
1685  }
1686 
1687 #ifdef USE_NNTP
1688  if (OptNews)
1690  else
1691 #endif
1692  mutt_buffer_expand_path(&fname);
1693 #ifdef USE_IMAP
1694  if (imap_path_probe(mutt_b2s(&fname), NULL) != MUTT_IMAP)
1695 #endif
1696 #ifdef USE_POP
1697  if (pop_path_probe(mutt_b2s(&fname), NULL) != MUTT_POP)
1698 #endif
1699 #ifdef USE_NNTP
1700  if (!OptNews && (nntp_path_probe(mutt_b2s(&fname), NULL) != MUTT_NNTP))
1701 #endif
1702  if (mx_path_probe(mutt_b2s(&fname)) != MUTT_NOTMUCH)
1703  {
1704  /* check to make sure the file exists and is readable */
1705  if (access(mutt_b2s(&fname), R_OK) == -1)
1706  {
1707  mutt_perror(mutt_b2s(&fname));
1708  break;
1709  }
1710  }
1711 
1712  menu->redraw = REDRAW_FULL;
1713 
1714  struct Mailbox *m = mx_path_resolve(mutt_b2s(&fname));
1715  bool old_readonly = m->readonly;
1716  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
1717  if (!ctx)
1718  {
1719  mutt_error(_("Unable to open mailbox %s"), mutt_b2s(&fname));
1721  m = NULL;
1722  break;
1723  }
1724 
1725  if (ctx->mailbox->msg_count == 0)
1726  {
1727  mx_mbox_close(&ctx);
1728  mutt_error(_("No messages in that folder"));
1729  break;
1730  }
1731 
1732  struct Context *ctx_cur = Context; /* remember current folder and sort methods */
1733  int old_sort = C_Sort; /* C_Sort, SortAux could be changed in mutt_index_menu() */
1734  int old_sort_aux = C_SortAux;
1735 
1736  Context = ctx;
1737  OptAttachMsg = true;
1738  mutt_message(_("Tag the messages you want to attach"));
1739  struct MuttWindow *dlg_index = index_pager_init();
1741  dialog_push(dlg_index);
1742  mutt_index_menu(dlg_index);
1743  dialog_pop();
1745  index_pager_shutdown(dlg_index);
1746  mutt_window_free(&dlg_index);
1747  OptAttachMsg = false;
1748 
1749  if (!Context)
1750  {
1751  /* go back to the folder we started from */
1752  Context = ctx_cur;
1753  /* Restore old $sort and $sort_aux */
1754  C_Sort = old_sort;
1755  C_SortAux = old_sort_aux;
1756  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1757  break;
1758  }
1759 
1760  for (int i = 0; i < Context->mailbox->msg_count; i++)
1761  {
1762  if (!Context->mailbox->emails[i])
1763  break;
1765  continue;
1766 
1767  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1769  Context->mailbox->emails[i], true);
1770  if (ap->content)
1771  update_idx(menu, actx, ap);
1772  else
1773  {
1774  mutt_error(_("Unable to attach"));
1775  FREE(&ap);
1776  }
1777  }
1778  menu->redraw |= REDRAW_FULL;
1779 
1780  Context->mailbox->readonly = old_readonly;
1782  ctx_free(&Context);
1783 
1784  /* go back to the folder we started from */
1785  Context = ctx_cur;
1786  /* Restore old $sort and $sort_aux */
1787  C_Sort = old_sort;
1788  C_SortAux = old_sort_aux;
1790  break;
1791  }
1792 
1793  case OP_DELETE:
1794  CHECK_COUNT;
1795  if (CUR_ATTACH->unowned)
1796  CUR_ATTACH->content->unlink = false;
1797  if (delete_attachment(actx, menu->current) == -1)
1798  break;
1799  mutt_update_compose_menu(actx, menu, false);
1800  if (menu->current == 0)
1801  e->content = actx->idx[0]->content;
1802 
1804  break;
1805 
1806  case OP_COMPOSE_TOGGLE_RECODE:
1807  {
1808  CHECK_COUNT;
1809  if (!mutt_is_text_part(CUR_ATTACH->content))
1810  {
1811  mutt_error(_("Recoding only affects text attachments"));
1812  break;
1813  }
1814  CUR_ATTACH->content->noconv = !CUR_ATTACH->content->noconv;
1815  if (CUR_ATTACH->content->noconv)
1816  mutt_message(_("The current attachment won't be converted"));
1817  else
1818  mutt_message(_("The current attachment will be converted"));
1819  menu->redraw = REDRAW_CURRENT;
1821  break;
1822  }
1823 
1824  case OP_COMPOSE_EDIT_DESCRIPTION:
1825  CHECK_COUNT;
1827  buf, CUR_ATTACH->content->description ? CUR_ATTACH->content->description : "",
1828  sizeof(buf));
1829  /* header names should not be translated */
1830  if (mutt_get_field("Description: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1831  {
1832  mutt_str_replace(&CUR_ATTACH->content->description, buf);
1833  menu->redraw = REDRAW_CURRENT;
1834  }
1836  break;
1837 
1838  case OP_COMPOSE_UPDATE_ENCODING:
1839  CHECK_COUNT;
1840  if (menu->tagprefix)
1841  {
1842  struct Body *top = NULL;
1843  for (top = e->content; top; top = top->next)
1844  {
1845  if (top->tagged)
1846  mutt_update_encoding(top);
1847  }
1848  menu->redraw = REDRAW_FULL;
1849  }
1850  else
1851  {
1852  mutt_update_encoding(CUR_ATTACH->content);
1854  }
1856  break;
1857 
1858  case OP_COMPOSE_TOGGLE_DISPOSITION:
1859  /* toggle the content-disposition between inline/attachment */
1860  CUR_ATTACH->content->disposition =
1861  (CUR_ATTACH->content->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
1862  menu->redraw = REDRAW_CURRENT;
1863  break;
1864 
1865  case OP_EDIT_TYPE:
1866  CHECK_COUNT;
1867  {
1868  mutt_edit_content_type(NULL, CUR_ATTACH->content, NULL);
1869 
1870  /* this may have been a change to text/something */
1871  mutt_update_encoding(CUR_ATTACH->content);
1872 
1873  menu->redraw = REDRAW_CURRENT;
1874  }
1876  break;
1877 
1878  case OP_COMPOSE_EDIT_LANGUAGE:
1879  CHECK_COUNT;
1880  buf[0] = '\0'; /* clear buffer first */
1881  if (CUR_ATTACH->content->language)
1882  mutt_str_strfcpy(buf, CUR_ATTACH->content->language, sizeof(buf));
1883  if (mutt_get_field("Content-Language: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) == 0)
1884  {
1885  CUR_ATTACH->content->language = mutt_str_strdup(buf);
1887  mutt_clear_error();
1888  }
1889  else
1890  mutt_warning(_("Empty 'Content-Language'"));
1892  break;
1893 
1894  case OP_COMPOSE_EDIT_ENCODING:
1895  CHECK_COUNT;
1896  mutt_str_strfcpy(buf, ENCODING(CUR_ATTACH->content->encoding), sizeof(buf));
1897  if ((mutt_get_field("Content-Transfer-Encoding: ", buf, sizeof(buf),
1898  MUTT_COMP_NO_FLAGS) == 0) &&
1899  (buf[0] != '\0'))
1900  {
1901  int enc = mutt_check_encoding(buf);
1902  if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1903  {
1904  CUR_ATTACH->content->encoding = enc;
1906  mutt_clear_error();
1907  }
1908  else
1909  mutt_error(_("Invalid encoding"));
1910  }
1912  break;
1913 
1914  case OP_COMPOSE_SEND_MESSAGE:
1915  /* Note: We don't invoke send2-hook here, since we want to leave
1916  * users an opportunity to change settings from the ":" prompt. */
1917  if (check_attachments(actx) != 0)
1918  {
1919  menu->redraw = REDRAW_FULL;
1920  break;
1921  }
1922 
1923 #ifdef MIXMASTER
1924  if (!STAILQ_EMPTY(&e->chain) && (mix_check_message(e) != 0))
1925  break;
1926 #endif
1927 
1928  if (!fcc_set && !mutt_buffer_is_empty(fcc))
1929  {
1930  enum QuadOption ans =
1931  query_quadoption(C_Copy, _("Save a copy of this message?"));
1932  if (ans == MUTT_ABORT)
1933  break;
1934  else if (ans == MUTT_NO)
1935  mutt_buffer_reset(fcc);
1936  }
1937 
1938  loop = false;
1939  rc = 0;
1940  break;
1941 
1942  case OP_COMPOSE_EDIT_FILE:
1943  CHECK_COUNT;
1944  mutt_edit_file(NONULL(C_Editor), CUR_ATTACH->content->filename);
1945  mutt_update_encoding(CUR_ATTACH->content);
1948  break;
1949 
1950  case OP_COMPOSE_TOGGLE_UNLINK:
1951  CHECK_COUNT;
1952  CUR_ATTACH->content->unlink = !CUR_ATTACH->content->unlink;
1953 
1954  menu->redraw = REDRAW_INDEX;
1955  /* No send2hook since this doesn't change the message. */
1956  break;
1957 
1958  case OP_COMPOSE_GET_ATTACHMENT:
1959  CHECK_COUNT;
1960  if (menu->tagprefix)
1961  {
1962  for (struct Body *top = e->content; top; top = top->next)
1963  {
1964  if (top->tagged)
1966  }
1967  menu->redraw = REDRAW_FULL;
1968  }
1969  else if (mutt_get_tmp_attachment(CUR_ATTACH->content) == 0)
1970  menu->redraw = REDRAW_CURRENT;
1971 
1972  /* No send2hook since this doesn't change the message. */
1973  break;
1974 
1975  case OP_COMPOSE_RENAME_ATTACHMENT:
1976  {
1977  CHECK_COUNT;
1978  char *src = NULL;
1979  if (CUR_ATTACH->content->d_filename)
1980  src = CUR_ATTACH->content->d_filename;
1981  else
1982  src = CUR_ATTACH->content->filename;
1984  int ret = mutt_buffer_get_field(_("Send attachment with name: "), &fname, MUTT_FILE);
1985  if (ret == 0)
1986  {
1987  /* As opposed to RENAME_FILE, we don't check buf[0] because it's
1988  * valid to set an empty string here, to erase what was set */
1989  mutt_str_replace(&CUR_ATTACH->content->d_filename, mutt_b2s(&fname));
1990  menu->redraw = REDRAW_CURRENT;
1991  }
1992  break;
1993  }
1994 
1995  case OP_COMPOSE_RENAME_FILE:
1996  CHECK_COUNT;
1997  mutt_buffer_strcpy(&fname, CUR_ATTACH->content->filename);
1999  if ((mutt_buffer_get_field(_("Rename to: "), &fname, MUTT_FILE) == 0) &&
2000  !mutt_buffer_is_empty(&fname))
2001  {
2002  struct stat st;
2003  if (stat(CUR_ATTACH->content->filename, &st) == -1)
2004  {
2005  /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
2006  mutt_error(_("Can't stat %s: %s"), mutt_b2s(&fname), strerror(errno));
2007  break;
2008  }
2009 
2010  mutt_buffer_expand_path(&fname);
2011  if (mutt_file_rename(CUR_ATTACH->content->filename, mutt_b2s(&fname)))
2012  break;
2013 
2014  mutt_str_replace(&CUR_ATTACH->content->filename, mutt_b2s(&fname));
2015  menu->redraw = REDRAW_CURRENT;
2016 
2017  if (CUR_ATTACH->content->stamp >= st.st_mtime)
2019  }
2021  break;
2022 
2023  case OP_COMPOSE_NEW_MIME:
2024  {
2025  mutt_buffer_reset(&fname);
2026  if ((mutt_buffer_get_field(_("New file: "), &fname, MUTT_FILE) != 0) ||
2027  mutt_buffer_is_empty(&fname))
2028  {
2029  continue;
2030  }
2031  mutt_buffer_expand_path(&fname);
2032 
2033  /* Call to lookup_mime_type () ? maybe later */
2034  char type[256] = { 0 };
2035  if ((mutt_get_field("Content-Type: ", type, sizeof(type), MUTT_COMP_NO_FLAGS) != 0) ||
2036  (type[0] == '\0'))
2037  {
2038  continue;
2039  }
2040 
2041  char *p = strchr(type, '/');
2042  if (!p)
2043  {
2044  mutt_error(_("Content-Type is of the form base/sub"));
2045  continue;
2046  }
2047  *p++ = 0;
2048  enum ContentType itype = mutt_check_mime_type(type);
2049  if (itype == TYPE_OTHER)
2050  {
2051  mutt_error(_("Unknown Content-Type %s"), type);
2052  continue;
2053  }
2054  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
2055  /* Touch the file */
2056  FILE *fp = mutt_file_fopen(mutt_b2s(&fname), "w");
2057  if (!fp)
2058  {
2059  mutt_error(_("Can't create file %s"), mutt_b2s(&fname));
2060  FREE(&ap);
2061  continue;
2062  }
2063  mutt_file_fclose(&fp);
2064 
2065  ap->content = mutt_make_file_attach(mutt_b2s(&fname));
2066  if (!ap->content)
2067  {
2068  mutt_error(_("What we have here is a failure to make an attachment"));
2069  FREE(&ap);
2070  continue;
2071  }
2072  update_idx(menu, actx, ap);
2073 
2074  CUR_ATTACH->content->type = itype;
2075  mutt_str_replace(&CUR_ATTACH->content->subtype, p);
2076  CUR_ATTACH->content->unlink = true;
2077  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
2078 
2079  if (mutt_compose_attachment(CUR_ATTACH->content))
2080  {
2081  mutt_update_encoding(CUR_ATTACH->content);
2082  menu->redraw = REDRAW_FULL;
2083  }
2085  break;
2086  }
2087 
2088  case OP_COMPOSE_EDIT_MIME:
2089  CHECK_COUNT;
2090  if (mutt_edit_attachment(CUR_ATTACH->content))
2091  {
2092  mutt_update_encoding(CUR_ATTACH->content);
2093  menu->redraw = REDRAW_FULL;
2094  }
2096  break;
2097 
2098  case OP_VIEW_ATTACH:
2099  case OP_DISPLAY_HEADERS:
2100  CHECK_COUNT;
2101  mutt_attach_display_loop(menu, op, NULL, actx, false);
2102  menu->redraw = REDRAW_FULL;
2103  /* no send2hook, since this doesn't modify the message */
2104  break;
2105 
2106  case OP_SAVE:
2107  CHECK_COUNT;
2108  mutt_save_attachment_list(actx, NULL, menu->tagprefix,
2109  CUR_ATTACH->content, NULL, menu);
2110  /* no send2hook, since this doesn't modify the message */
2111  break;
2112 
2113  case OP_PRINT:
2114  CHECK_COUNT;
2115  mutt_print_attachment_list(actx, NULL, menu->tagprefix, CUR_ATTACH->content);
2116  /* no send2hook, since this doesn't modify the message */
2117  break;
2118 
2119  case OP_PIPE:
2120  case OP_FILTER:
2121  CHECK_COUNT;
2122  mutt_pipe_attachment_list(actx, NULL, menu->tagprefix,
2123  CUR_ATTACH->content, (op == OP_FILTER));
2124  if (op == OP_FILTER) /* cte might have changed */
2125  menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
2126  menu->redraw |= REDRAW_STATUS;
2128  break;
2129 
2130  case OP_EXIT:
2131  {
2132  enum QuadOption ans =
2133  query_quadoption(C_Postpone, _("Save (postpone) draft message?"));
2134  if (ans == MUTT_NO)
2135  {
2136  for (int i = 0; i < actx->idxlen; i++)
2137  if (actx->idx[i]->unowned)
2138  actx->idx[i]->content->unlink = false;
2139 
2140  if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
2141  {
2142  for (int i = 0; i < actx->idxlen; i++)
2143  {
2144  /* avoid freeing other attachments */
2145  actx->idx[i]->content->next = NULL;
2146  /* See the comment in delete_attachment() */
2147  if (!actx->idx[i]->content->email)
2148  actx->idx[i]->content->parts = NULL;
2149  mutt_body_free(&actx->idx[i]->content);
2150  }
2151  }
2152  rc = -1;
2153  loop = false;
2154  break;
2155  }
2156  else if (ans == MUTT_ABORT)
2157  break; /* abort */
2158  }
2159  /* fallthrough */
2160 
2161  case OP_COMPOSE_POSTPONE_MESSAGE:
2162  if (check_attachments(actx) != 0)
2163  {
2164  menu->redraw = REDRAW_FULL;
2165  break;
2166  }
2167 
2168  loop = false;
2169  rc = 1;
2170  break;
2171 
2172  case OP_COMPOSE_ISPELL:
2173  endwin();
2174  snprintf(buf, sizeof(buf), "%s -x %s", NONULL(C_Ispell), e->content->filename);
2175  if (mutt_system(buf) == -1)
2176  mutt_error(_("Error running \"%s\""), buf);
2177  else
2178  {
2180  menu->redraw |= REDRAW_STATUS;
2181  }
2182  break;
2183 
2184  case OP_COMPOSE_WRITE_MESSAGE:
2185  mutt_buffer_reset(&fname);
2186  if (Context)
2187  {
2190  }
2191  if (actx->idxlen)
2192  e->content = actx->idx[0]->content;
2193  if ((mutt_buffer_enter_fname(_("Write message to mailbox"), &fname, true) != -1) &&
2194  !mutt_buffer_is_empty(&fname))
2195  {
2196  mutt_message(_("Writing message to %s ..."), mutt_b2s(&fname));
2197  mutt_buffer_expand_path(&fname);
2198 
2199  if (e->content->next)
2201 
2202  if (mutt_write_fcc(mutt_b2s(&fname), e, NULL, false, NULL, NULL) == 0)
2203  mutt_message(_("Message written"));
2204 
2206  }
2207  break;
2208 
2209  case OP_COMPOSE_PGP_MENU:
2210  if (!(WithCrypto & APPLICATION_PGP))
2211  break;
2212  if (!crypt_has_module_backend(APPLICATION_PGP))
2213  {
2214  mutt_error(_("No PGP backend configured"));
2215  break;
2216  }
2217  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
2218  {
2219  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2220  {
2221  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2222  {
2223  mutt_clear_error();
2224  break;
2225  }
2226  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2227  }
2228  e->security &= ~APPLICATION_SMIME;
2229  e->security |= APPLICATION_PGP;
2230  update_crypt_info(rd);
2231  }
2232  e->security = crypt_pgp_send_menu(e);
2233  update_crypt_info(rd);
2235  break;
2236 
2237  case OP_FORGET_PASSPHRASE:
2239  break;
2240 
2241  case OP_COMPOSE_SMIME_MENU:
2242  if (!(WithCrypto & APPLICATION_SMIME))
2243  break;
2244  if (!crypt_has_module_backend(APPLICATION_SMIME))
2245  {
2246  mutt_error(_("No S/MIME backend configured"));
2247  break;
2248  }
2249 
2250  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
2251  {
2252  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2253  {
2254  if (mutt_yesorno(_("PGP already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2255  {
2256  mutt_clear_error();
2257  break;
2258  }
2259  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2260  }
2261  e->security &= ~APPLICATION_PGP;
2263  update_crypt_info(rd);
2264  }
2266  update_crypt_info(rd);
2268  break;
2269 
2270 #ifdef MIXMASTER
2271  case OP_COMPOSE_MIX:
2272  mix_make_chain(menu->win_index, &e->chain, menu->win_index->state.cols);
2274  break;
2275 #endif
2276 #ifdef USE_AUTOCRYPT
2277  case OP_COMPOSE_AUTOCRYPT_MENU:
2278  if (!C_Autocrypt)
2279  break;
2280 
2281  if ((WithCrypto & APPLICATION_SMIME) && (e->security & APPLICATION_SMIME))
2282  {
2283  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2284  {
2285  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2286  {
2287  mutt_clear_error();
2288  break;
2289  }
2290  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2291  }
2292  e->security &= ~APPLICATION_SMIME;
2293  e->security |= APPLICATION_PGP;
2294  update_crypt_info(rd);
2295  }
2297  update_crypt_info(rd);
2299  break;
2300 #endif
2301  }
2302  }
2303 
2304  mutt_buffer_dealloc(&fname);
2305 
2306 #ifdef USE_AUTOCRYPT
2307  /* This is a fail-safe to make sure the bit isn't somehow turned
2308  * on. The user could have disabled the option after setting SEC_AUTOCRYPT,
2309  * or perhaps resuming or replying to an autocrypt message. */
2310  if (!C_Autocrypt)
2311  e->security &= ~SEC_AUTOCRYPT;
2312 #endif
2313 
2314  mutt_menu_pop_current(menu);
2315  mutt_menu_free(&menu);
2316  dialog_pop();
2318  mutt_window_free(&dlg);
2319 
2320  if (actx->idxlen)
2321  e->content = actx->idx[0]->content;
2322  else
2323  e->content = NULL;
2324 
2325  mutt_actx_free(&actx);
2326 
2327  return rc;
2328 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:252
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1511
static int delete_attachment(struct AttachCtx *actx, int x)
Delete an attachment.
Definition: compose.c:748
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1443
Unknown Content-Type.
Definition: mime.h:31
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
void mutt_actx_free(struct AttachCtx **ptr)
Free an Attachment Context.
Definition: attach.c:140
void mix_make_chain(struct MuttWindow *win, struct ListHead *chainhead, int cols)
Create a Mixmaster chain.
Definition: remailer.c:601
bool message_is_tagged(struct Context *ctx, struct Email *e)
Is a message in the index tagged (and within limit)
Definition: context.c:351
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
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:1145
int msg_count
Total number of messages.
Definition: mailbox.h:91
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1767
#define WithCrypto
Definition: lib.h:163
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
#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:2516
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:593
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:329
Dialog (nested Windows) displayed to the user.
Definition: mutt_window.h:70
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
#define mutt_message(...)
Definition: logging.h:83
Window uses all available vertical space.
Definition: mutt_window.h:35
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:1341
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
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::custom_redraw()
Definition: compose.c:877
void dialog_pop(void)
Hide a Window from the user.
Definition: mutt_window.c:628
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
static void edit_address_list(int line, struct AddressList *al, struct ComposeRedrawData *rd)
Let the user edit the address list.
Definition: compose.c:713
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
Definition: recvattach.c:651
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:134
"To:" field
Definition: compose.c:133
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: mutt_window.c:605
struct Body * content
List of MIME parts.
Definition: email.h:90
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:104
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
"Cc:" field
Definition: compose.c:134
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:257
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
static void update_crypt_info(struct ComposeRedrawData *rd)
Update the crypto info.
Definition: compose.c:485
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:255
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:180
A division of the screen.
Definition: mutt_window.h:88
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
struct Email * email
Definition: compose.c:107
char * C_Ispell
Config: External command to perform spell-checking.
Definition: compose.c:94
struct Buffer * fcc
Definition: compose.c:108
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:55
"Subject:" field
Definition: compose.c:136
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:309
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:132
struct NntpAccountData * nntp_select_server(struct Mailbox *m, char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:1014
Container for Accounts, Notifications.
Definition: neomutt.h:35
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3253
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1244
An Index Window containing a selection list.
Definition: mutt_window.h:74
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::make_entry()
Definition: compose.c:312
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:74
#define CUR_ATTACH
Definition: compose.c:123
int mutt_dlg_index_observer(struct NotifyCallback *nc)
Listen for config changes affecting the Index/Pager - Implements observer_t.
Definition: index.c:4129
size_t dsize
Length of data.
Definition: buffer.h:37
void * redraw_data
Definition: mutt_menu.h:155
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1026
int mutt_get_tmp_attachment(struct Body *a)
Get a temporary copy of an attachment.
Definition: mutt_attach.c:68
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:212
struct Mailbox * mailbox
Definition: context.h:51
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: sendlib.c:636
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1645
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
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
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:521
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
#define ENCODING(x)
Definition: mime.h:85
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:414
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
Content is attached.
Definition: mime.h:63
static void compose_attach_swap(struct Body *msg, struct AttachPtr **idx, short first)
Swap two adjacent entries in the attachment list.
Definition: compose.c:926
void mutt_rfc3676_space_unstuff(struct Email *e)
Remove RFC3676 space stuffing.
Definition: rfc3676.c:481
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition: attach.c:131
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
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:1741
Window has a fixed size.
Definition: mutt_window.h:44
const char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
char * subtype
content-type subtype
Definition: body.h:37
int mutt_buffer_enter_fname_full(const char *prompt, struct Buffer *fname, bool mailbox, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:746
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
WHERE char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: globals.h:130
static const struct Mapping ComposeHelp[]
Definition: compose.c:203
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
struct ListHead chain
Mixmaster chain.
Definition: email.h:99
WHERE short C_SortAux
Config: Secondary sort method for the index.
Definition: sort.h:59
#define HDR_XOFFSET
Definition: compose.c:159
WHERE struct Context * Context
Definition: globals.h:42
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag()
Definition: recvattach.c:450
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
#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
struct MuttWindow * mutt_window_new(enum MuttWindowOrientation orient, enum MuttWindowSize size, int rows, int cols)
Create a new Window.
Definition: mutt_window.c:56
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:44
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
bool tagprefix
Definition: mutt_menu.h:93
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2836
char * data
Pointer to data.
Definition: buffer.h:35
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:773
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:375
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:834
void(* custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:153
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:139
char * description
content-description
Definition: body.h:40
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:438
struct Notify * notify
Notifications handler.
Definition: neomutt.h:37
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
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
#define W
Definition: compose.c:160
int mutt_index_menu(struct MuttWindow *dlg)
Display a list of emails.
Definition: index.c:1116
#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:219
int tagged
Number of tagged entries.
Definition: mutt_menu.h:111
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
unsigned int type
content-type primary type
Definition: body.h:65
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:473
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
"Bcc:" field
Definition: compose.c:135
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
#define LINGUAL_TAG
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:160
static void update_idx(struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
Add a new attchment to the message.
Definition: compose.c:863
struct Connection * conn
Definition: lib.h:104
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:876
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:271
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, struct Buffer *fcc)
Let the user edit the message header and body.
Definition: mutt_header.c:168
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1318
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:296
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
int offset
Row offset within the window to start the index.
Definition: mutt_menu.h:91
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct MuttWindow * win
Definition: compose.c:113
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
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:283
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:401
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
void mutt_rfc3676_space_stuff(struct Email *e)
Perform RFC3676 space stuffing on an Email.
Definition: rfc3676.c:463
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:327
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:111
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1655
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:35
#define STAILQ_EMPTY(head)
Definition: queue.h:345
Where to start printing the attachments.
Definition: compose.c:153
void index_pager_shutdown(struct MuttWindow *dlg)
Clear up any non-Window parts.
Definition: index.c:4114
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: compose.c:281
struct MuttWindow * index_pager_init(void)
Allocate the Windows for the Index/Pager.
Definition: index.c:4021
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:48
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1239
int current
Current entry.
Definition: mutt_menu.h:87
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
"Fcc:" (save folder) field
Definition: compose.c:138
#define CHECK_COUNT
Definition: compose.c:116
struct MuttWindow * win_index
Definition: mutt_menu.h:95
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:116
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:563
Window wants as much space as possible.
Definition: mutt_window.h:45
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
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:53
struct Email * email
header information for message/rfc822
Definition: body.h:55
Index Bar containing status info about the Index.
Definition: mutt_window.h:75
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:103
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(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:354
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
Keep track when the compose screen needs redrawing.
Definition: compose.c:105
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:87
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
UUEncoded text.
Definition: mime.h:54
#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:118
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:854
static int mutt_dlg_compose_observer(struct NotifyCallback *nc)
Listen for config changes affecting the Compose menu - Implements observer_t.
Definition: compose.c:1074
ContentType
Content-Type.
Definition: mime.h:29
"Reply-To:" field
Definition: compose.c:137
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ComposeFormat

char* C_ComposeFormat

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

Definition at line 93 of file compose.c.

◆ C_Ispell

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 94 of file compose.c.

◆ C_Postpone

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 95 of file compose.c.

◆ There_are_no_attachments

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

Definition at line 97 of file compose.c.

◆ HeaderPadding

int HeaderPadding[HDR_ATTACH_TITLE] = { 0 }

Definition at line 156 of file compose.c.

◆ MaxHeaderWidth

int MaxHeaderWidth = 0

Definition at line 157 of file compose.c.

◆ Prompts

const char* const Prompts[]
static

Definition at line 162 of file compose.c.

◆ ComposeHelp

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

◆ ComposeNewsHelp

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

◆ AutocryptRecUiFlags

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