NeoMutt  2019-11-11
Teaching an old dog new tricks
DOXYGEN
compose.c File Reference

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

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

static void 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::menu_make_entry() More...
 
static void autocrypt_compose_menu (struct Email *e)
 Autocrypt compose settings. More...
 
static void redraw_crypt_lines (struct ComposeRedrawData *rd)
 Update the encryption info in the compose window. More...
 
static void update_crypt_info (struct ComposeRedrawData *rd)
 Update the crypto info. More...
 
static int check_attachments (struct AttachCtx *actx)
 Check if any attachments have changed or been deleted. More...
 
static void draw_envelope_addr (int line, struct AddressList *al, 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::menu_custom_redraw() More...
 
static void compose_attach_swap (struct Body *msg, struct AttachPtr **idx, short first)
 Swap two adjacent entries in the attachment list. More...
 
static unsigned long cum_attachs_size (struct Menu *menu)
 Cumulative Attachments Size. More...
 
static const char * compose_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
 Create the status bar string for compose mode - Implements format_t. More...
 
int mutt_compose_menu (struct Email *e, 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:99
#define _(a)
Definition: message.h:28

Definition at line 118 of file compose.c.

◆ CUR_ATTACH

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

Definition at line 125 of file compose.c.

◆ HDR_XOFFSET

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 161 of file compose.c.

◆ W

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

Definition at line 162 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_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 132 of file compose.c.

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

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

1081 {
1082  mutt_expando_format(buf, buflen, col, cols, src, compose_format_str,
1083  (unsigned long) menu, MUTT_FORMAT_NO_FLAGS);
1084 }
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:878
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:1021
#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 266 of file compose.c.

267 {
268  int width;
269 
270  HeaderPadding[idx] = mutt_str_strlen(header);
271  width = mutt_strwidth(header);
272  if (calc_max && (MaxHeaderWidth < width))
273  MaxHeaderWidth = width;
274  HeaderPadding[idx] -= width;
275 }
int MaxHeaderWidth
Definition: compose.c:159
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1287
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:158
+ 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 285 of file compose.c.

286 {
287  static bool done = false;
288 
289  if (done)
290  return;
291  done = true;
292 
293  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
294  {
295  if (i == HDR_CRYPTINFO)
296  continue;
297  calc_header_width_padding(i, _(Prompts[i]), true);
298  }
299 
300  /* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
301  * doesn't show up by default, and so can make the indentation of
302  * the other fields look funny. */
304 
305  for (int i = 0; i < HDR_ATTACH_TITLE; i++)
306  {
308  if (HeaderPadding[i] < 0)
309  HeaderPadding[i] = 0;
310  }
311 }
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:266
int MaxHeaderWidth
Definition: compose.c:159
#define _(a)
Definition: message.h:28
"Sign as:" field (encryption/signing info)
Definition: compose.c:145
The "-- Attachments" line.
Definition: compose.c:154
static const char *const Prompts[]
Definition: compose.c:164
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:158
+ 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::menu_make_entry()

Definition at line 316 of file compose.c.

317 {
318  struct AttachCtx *actx = menu->data;
319 
320  mutt_expando_format(buf, buflen, 0, menu->indexwin->cols, NONULL(C_AttachFormat),
321  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
323 }
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:878
#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
const char * line
Definition: common.c:36
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
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:209
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:

◆ autocrypt_compose_menu()

static void autocrypt_compose_menu ( struct Email e)
static

Autocrypt compose settings.

Parameters
eEmail

Definition at line 330 of file compose.c.

331 {
332  /* L10N:
333  The compose menu autocrypt prompt.
334  (e)ncrypt enables encryption via autocrypt.
335  (c)lear sets cleartext.
336  (a)utomatic defers to the recommendation.
337  */
338  const char *prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic?");
339 
341 
342  /* L10N:
343  The letter corresponding to the compose menu autocrypt prompt
344  (e)ncrypt, (c)lear, (a)utomatic
345  */
346  const char *letters = _("eca");
347 
348  int choice = mutt_multi_choice(prompt, letters);
349  switch (choice)
350  {
351  case 1:
354  break;
355  case 2:
356  e->security &= ~SEC_AUTOCRYPT;
358  break;
359  case 3:
362  e->security |= SEC_OPPENCRYPT;
363  break;
364  }
365 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:862
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:278
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
+ 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 372 of file compose.c.

373 {
374  struct Email *e = rd->email;
375 
378  _(Prompts[HDR_CRYPT]));
380 
382  {
383  mutt_window_addstr(_("Not supported"));
384  return;
385  }
386 
387  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
388  {
390  mutt_window_addstr(_("Sign, Encrypt"));
391  }
392  else if (e->security & SEC_ENCRYPT)
393  {
395  mutt_window_addstr(_("Encrypt"));
396  }
397  else if (e->security & SEC_SIGN)
398  {
400  mutt_window_addstr(_("Sign"));
401  }
402  else
403  {
404  /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
406  mutt_window_addstr(_("None"));
407  }
409 
410  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
411  {
412  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
413  {
414  if ((e->security & SEC_INLINE))
415  mutt_window_addstr(_(" (inline PGP)"));
416  else
417  mutt_window_addstr(_(" (PGP/MIME)"));
418  }
419  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
420  mutt_window_addstr(_(" (S/MIME)"));
421  }
422 
424  mutt_window_addstr(_(" (OppEnc mode)"));
425 
429 
430  if (((WithCrypto & APPLICATION_PGP) != 0) &&
431  (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
432  {
434  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
436  mutt_window_printf("%s", C_PgpSignAs ? C_PgpSignAs : _("<default>"));
437  }
438 
439  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
440  (e->security & APPLICATION_SMIME) && (e->security & SEC_SIGN))
441  {
443  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
445  mutt_window_printf("%s", C_SmimeSignAs ? C_SmimeSignAs : _("<default>"));
446  }
447 
448  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
450  {
452  mutt_window_mvprintw(rd->win, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
455  }
456 
457 #ifdef USE_AUTOCRYPT
460  if (C_Autocrypt)
461  {
463  mutt_window_printf("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
465  if (e->security & SEC_AUTOCRYPT)
466  {
468  mutt_window_addstr(_("Encrypt"));
469  }
470  else
471  {
473  mutt_window_addstr(_("Off"));
474  }
475 
477  mutt_window_mvprintw(rd->win, HDR_AUTOCRYPT, 40, "%s",
478  /* L10N:
479  The autocrypt compose menu Recommendation field.
480  Displays the output of the recommendation engine
481  (Off, No, Discouraged, Available, Yes)
482  */
483  _("Recommendation: "));
486  }
487 #endif
488 }
Mail will be encrypted.
Definition: color.h:68
#define NONULL(x)
Definition: string2.h:37
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:203
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:49
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
struct Email * email
Definition: compose.c:109
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
"Sign as:" field (encryption/signing info)
Definition: compose.c:145
enum AutocryptRec autocrypt_rec
Definition: compose.c:112
Plain text.
Definition: color.h:78
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:278
Header labels, e.g. From:
Definition: color.h:66
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:170
Mail will be signed.
Definition: color.h:70
"Security:" field (encryption/signing info)
Definition: compose.c:144
static const char *const Prompts[]
Definition: compose.c:164
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
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:424
struct MuttWindow * win
Definition: compose.c:115
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:158
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:231
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:396
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:165
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:169
static const char * AutocryptRecUiFlags[]
Definition: compose.c:236
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

495 {
496  struct Email *e = rd->email;
497 
500 
501 #ifdef USE_AUTOCRYPT
502  if (C_Autocrypt)
503  {
505 
506  /* Anything that enables SEC_ENCRYPT or SEC_SIGN, or turns on SMIME
507  * overrides autocrypt, be it oppenc or the user having turned on
508  * those flags manually. */
511  else
512  {
513  if (!(e->security & SEC_AUTOCRYPT_OVERRIDE))
514  {
515  if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
516  {
519  }
520  else
521  e->security &= ~SEC_AUTOCRYPT;
522  }
523  }
524  }
525 #endif
526 
527  redraw_crypt_lines(rd);
528 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:203
The envelope/body of an email.
Definition: email.h:37
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
struct Email * email
Definition: compose.c:109
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
enum AutocryptRec autocrypt_rec
Definition: compose.c:112
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:278
Autocrypt should be used.
Definition: autocrypt.h:107
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:372
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1030
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:561
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

579 {
580  int rc = -1;
581  struct stat st;
582  struct Buffer *pretty = NULL, *msg = NULL;
583 
584  for (int i = 0; i < actx->idxlen; i++)
585  {
586  if (actx->idx[i]->content->type == TYPE_MULTIPART)
587  continue;
588  if (stat(actx->idx[i]->content->filename, &st) != 0)
589  {
590  if (!pretty)
591  pretty = mutt_buffer_pool_get();
592  mutt_buffer_strcpy(pretty, actx->idx[i]->content->filename);
594  /* L10N:
595  This message is displayed in the compose menu when an attachment
596  doesn't stat. %d is the attachment number and %s is the
597  attachment filename.
598  The filename is located last to avoid a long path hiding the
599  error message.
600  */
601  mutt_error(_("Attachment #%d no longer exists: %s"), i + 1, mutt_b2s(pretty));
602  goto cleanup;
603  }
604 
605  if (actx->idx[i]->content->stamp < st.st_mtime)
606  {
607  if (!pretty)
608  pretty = mutt_buffer_pool_get();
609  mutt_buffer_strcpy(pretty, actx->idx[i]->content->filename);
611 
612  if (!msg)
613  msg = mutt_buffer_pool_get();
614  /* L10N:
615  This message is displayed in the compose menu when an attachment
616  is modified behind the scenes. %d is the attachment number
617  and %s is the attachment filename.
618  The filename is located last to avoid a long path hiding the
619  prompt question.
620  */
621  mutt_buffer_printf(msg, _("Attachment #%d modified. Update encoding for %s?"),
622  i + 1, mutt_b2s(pretty));
623 
624  enum QuadOption ans = mutt_yesorno(mutt_b2s(msg), MUTT_YES);
625  if (ans == MUTT_YES)
626  mutt_update_encoding(actx->idx[i]->content);
627  else if (ans == MUTT_ABORT)
628  goto cleanup;
629  }
630  }
631 
632  rc = 0;
633 
634 cleanup:
635  mutt_buffer_pool_release(&pretty);
637  return rc;
638 }
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:100
User aborted the question (with Ctrl-G)
Definition: quad.h:37
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
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:704
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:375
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1486
#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:35
+ 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 646 of file compose.c.

647 {
648  char buf[1024];
649 
650  buf[0] = '\0';
651  mutt_addrlist_write(buf, sizeof(buf), al, true);
653  mutt_window_mvprintw(rd->win, line, 0, "%*s", HeaderPadding[line], _(Prompts[line]));
655  mutt_paddstr(W, buf);
656 }
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:49
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1137
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1194
Plain text.
Definition: color.h:78
const char * line
Definition: common.c:36
Header labels, e.g. From:
Definition: color.h:66
static const char *const Prompts[]
Definition: compose.c:164
#define W
Definition: compose.c:162
struct MuttWindow * win
Definition: compose.c:115
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:158
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:231
+ 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 662 of file compose.c.

663 {
664  struct Email *e = rd->email;
665  const char *fcc = mutt_b2s(rd->fcc);
666 
667  draw_envelope_addr(HDR_FROM, &e->env->from, rd);
668 #ifdef USE_NNTP
669  if (!OptNewsSend)
670  {
671 #endif
672  draw_envelope_addr(HDR_TO, &e->env->to, rd);
673  draw_envelope_addr(HDR_CC, &e->env->cc, rd);
674  draw_envelope_addr(HDR_BCC, &e->env->bcc, rd);
675 #ifdef USE_NNTP
676  }
677  else
678  {
679  mutt_window_mvprintw(rd->win, HDR_TO, 0, "%*s",
680  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
682  mutt_window_mvprintw(rd->win, HDR_CC, 0, "%*s",
683  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
685  if (C_XCommentTo)
686  {
687  mutt_window_mvprintw(rd->win, HDR_BCC, 0, "%*s",
688  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
690  }
691  }
692 #endif
693 
695  mutt_window_mvprintw(rd->win, HDR_SUBJECT, 0, "%*s",
696  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
699 
701 
704  _(Prompts[HDR_FCC]));
706  mutt_paddstr(W, fcc);
707 
708  if (WithCrypto)
709  redraw_crypt_lines(rd);
710 
711 #ifdef MIXMASTER
712  redraw_mix_line(&e->chain, rd);
713 #endif
714 
716  mutt_window_mvaddstr(rd->win, HDR_ATTACH_TITLE, 0, _("-- Attachments"));
718 
720 }
#define NONULL(x)
Definition: string2.h:37
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:49
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
"To:" field
Definition: compose.c:135
"Cc:" field
Definition: compose.c:136
#define _(a)
Definition: message.h:28
struct Email * email
Definition: compose.c:109
struct Buffer * fcc
Definition: compose.c:110
"Subject:" field
Definition: compose.c:138
"From:" field
Definition: compose.c:134
The "-- Attachments" line.
Definition: compose.c:154
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1194
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:152
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
Status bar (takes a pattern)
Definition: color.h:95
Header labels, e.g. From:
Definition: color.h:66
static void draw_envelope_addr(int line, struct AddressList *al, struct ComposeRedrawData *rd)
Write addresses to the compose window.
Definition: compose.c:646
static const char *const Prompts[]
Definition: compose.c:164
#define W
Definition: compose.c:162
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:212
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:372
"Bcc:" field
Definition: compose.c:137
"Followup-To:" field
Definition: compose.c:151
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct MuttWindow * win
Definition: compose.c:115
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:292
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:158
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:231
"Newsgroups:" field
Definition: compose.c:150
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
"Fcc:" (save folder) field
Definition: compose.c:140
#define WithCrypto
Definition: ncrypt.h:160
"Reply-To:" field
Definition: compose.c:139
+ 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 728 of file compose.c.

729 {
730  char buf[8192] = { 0 }; /* needs to be large for alias expansion */
731  char *err = NULL;
732 
734  mutt_addrlist_write(buf, sizeof(buf), al, false);
735  if (mutt_get_field(_(Prompts[line]), buf, sizeof(buf), MUTT_ALIAS) == 0)
736  {
738  mutt_addrlist_parse2(al, buf);
740  }
741 
742  if (mutt_addrlist_to_intl(al, &err) != 0)
743  {
744  mutt_error(_("Bad IDN: '%s'"), err);
745  mutt_refresh();
746  FREE(&err);
747  }
748 
749  /* redraw the expanded list so the user can see the result */
750  buf[0] = '\0';
751  mutt_addrlist_write(buf, sizeof(buf), al, true);
752  mutt_window_move(rd->win, line, HDR_XOFFSET);
753  mutt_paddstr(W, buf);
754 }
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:63
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1298
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1381
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1137
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:606
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1194
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:105
const char * line
Definition: common.c:36
#define HDR_XOFFSET
Definition: compose.c:161
static const char *const Prompts[]
Definition: compose.c:164
#define W
Definition: compose.c:162
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
struct MuttWindow * win
Definition: compose.c:115
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1216
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

764 {
765  struct AttachPtr **idx = actx->idx;
766  int rindex = actx->v2r[x];
767 
768  if ((rindex == 0) && (actx->idxlen == 1))
769  {
770  mutt_error(_("You may not delete the only attachment"));
771  idx[rindex]->content->tagged = false;
772  return -1;
773  }
774 
775  for (int y = 0; y < actx->idxlen; y++)
776  {
777  if (idx[y]->content->next == idx[rindex]->content)
778  {
779  idx[y]->content->next = idx[rindex]->content->next;
780  break;
781  }
782  }
783 
784  idx[rindex]->content->next = NULL;
785  /* mutt_make_message_attach() creates body->parts, shared by
786  * body->email->content. If we NULL out that, it creates a memory
787  * leak because mutt_free_body() frees body->parts, not
788  * body->email->content.
789  *
790  * Other ci_send_message() message constructors are careful to free
791  * any body->parts, removing depth:
792  * - mutt_prepare_template() used by postponed, resent, and draft files
793  * - mutt_copy_body() used by the recvattach menu and $forward_attachments.
794  *
795  * I believe it is safe to completely remove the "content->parts =
796  * NULL" statement. But for safety, am doing so only for the case
797  * it must be avoided: message attachments.
798  */
799  if (!idx[rindex]->content->email)
800  idx[rindex]->content->parts = NULL;
801  mutt_body_free(&(idx[rindex]->content));
802  FREE(&idx[rindex]->tree);
803  FREE(&idx[rindex]);
804  for (; rindex < actx->idxlen - 1; rindex++)
805  idx[rindex] = idx[rindex + 1];
806  idx[actx->idxlen - 1] = NULL;
807  actx->idxlen--;
808 
809  return 0;
810 }
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 819 of file compose.c.

821 {
822  for (; m; m = m->next)
823  {
824  if ((m->type == TYPE_MULTIPART) && m->parts &&
826  {
828  }
829  else
830  {
831  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
832  mutt_actx_add_attach(actx, ap);
833  ap->content = m;
834  m->aptr = ap;
835  ap->parent_type = parent_type;
836  ap->level = level;
837 
838  /* We don't support multipart messages in the compose menu yet */
839  }
840  }
841 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
An email to which things will be attached.
Definition: attach.h:34
struct Body * next
next attachment in the list
Definition: body.h:53
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
static void mutt_gen_compose_attach_list(struct AttachCtx *actx, struct Body *m, int parent_type, int level)
Generate the attachment list for the compose screen.
Definition: compose.c:819
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define WithCrypto
Definition: ncrypt.h:160
int level
Nesting depth of attachment.
Definition: attach.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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

850 {
851  if (init)
852  {
853  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
854  mutt_attach_init(actx);
855  menu->data = actx;
856  }
857 
858  mutt_update_tree(actx);
859 
860  menu->max = actx->vcount;
861  if (menu->max)
862  {
863  if (menu->current >= menu->max)
864  menu->current = menu->max - 1;
865  }
866  else
867  menu->current = 0;
868 
869  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
870 }
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:819
#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:1327
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:143
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 878 of file compose.c.

879 {
880  ap->level = (actx->idxlen > 0) ? actx->idx[actx->idxlen - 1]->level : 0;
881  if (actx->idxlen)
882  actx->idx[actx->idxlen - 1]->content->next = ap->content;
883  ap->content->aptr = ap;
884  mutt_actx_add_attach(actx, ap);
885  mutt_update_compose_menu(actx, menu, false);
886  menu->current = actx->vcount - 1;
887 }
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:849
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::menu_custom_redraw()

Definition at line 892 of file compose.c.

893 {
894  struct ComposeRedrawData *rd = menu->redraw_data;
895 
896  if (!rd)
897  return;
898 
899  if (menu->redraw & REDRAW_FULL)
900  {
901  menu_redraw_full(menu);
902 
903  draw_envelope(rd);
904  menu->offset = HDR_ATTACH;
905  menu->pagelen = menu->indexwin->rows - HDR_ATTACH;
906  }
907 
908  menu_check_recenter(menu);
909 
910  if (menu->redraw & REDRAW_STATUS)
911  {
912  char buf[1024];
913  compose_status_line(buf, sizeof(buf), 0, menu->statuswin->cols, menu,
915  mutt_window_move(menu->statuswin, 0, 0);
917  mutt_paddstr(menu->statuswin->cols, buf);
919  menu->redraw &= ~REDRAW_STATUS;
920  }
921 
922 #ifdef USE_SIDEBAR
923  if (menu->redraw & REDRAW_SIDEBAR)
924  menu_redraw_sidebar(menu);
925 #endif
926 
927  if (menu->redraw & REDRAW_INDEX)
928  menu_redraw_index(menu);
929  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNC))
930  menu_redraw_motion(menu);
931  else if (menu->redraw == REDRAW_CURRENT)
932  menu_redraw_current(menu);
933 }
#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:49
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1194
void * redraw_data
Definition: mutt_menu.h:150
static void draw_envelope(struct ComposeRedrawData *rd)
Write the email headers to the compose window.
Definition: compose.c:662
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:1079
#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
struct MuttWindow * statuswin
Definition: mutt_menu.h:96
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
Status bar (takes a pattern)
Definition: color.h:95
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
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:198
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:155
char * C_ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:95
Keep track when the compose screen needs redrawing.
Definition: compose.c:107
#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 941 of file compose.c.

942 {
943  /* Reorder Body pointers.
944  * Must traverse msg from top since Body has no previous ptr. */
945  for (struct Body *part = msg; part; part = part->next)
946  {
947  if (part->next == idx[first]->content)
948  {
949  idx[first]->content->next = idx[first + 1]->content->next;
950  idx[first + 1]->content->next = idx[first]->content;
951  part->next = idx[first + 1]->content;
952  break;
953  }
954  }
955 
956  /* Reorder index */
957  struct AttachPtr *saved = idx[first];
958  idx[first] = idx[first + 1];
959  idx[first + 1] = saved;
960 
961  /* Swap ptr->num */
962  int i = idx[first]->num;
963  idx[first]->num = idx[first + 1]->num;
964  idx[first + 1]->num = i;
965 }
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 975 of file compose.c.

976 {
977  size_t s = 0;
978  struct AttachCtx *actx = menu->data;
979  struct AttachPtr **idx = actx->idx;
980  struct Content *info = NULL;
981  struct Body *b = NULL;
982 
983  for (unsigned short i = 0; i < actx->idxlen; i++)
984  {
985  b = idx[i]->content;
986 
987  if (!b->content)
989 
990  info = b->content;
991  if (info)
992  {
993  switch (b->encoding)
994  {
996  s += 3 * (info->lobin + info->hibin) + info->ascii + info->crlf;
997  break;
998  case ENC_BASE64:
999  s += (4 * (info->lobin + info->hibin + info->ascii + info->crlf)) / 3;
1000  break;
1001  default:
1002  s += info->lobin + info->hibin + info->ascii + info->crlf;
1003  break;
1004  }
1005  }
1006  }
1007 
1008  return s;
1009 }
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:1034
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 1021 of file compose.c.

1025 {
1026  char fmt[128], tmp[128];
1027  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
1028  struct Menu *menu = (struct Menu *) data;
1029 
1030  *buf = '\0';
1031  switch (op)
1032  {
1033  case 'a': /* total number of attachments */
1034  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1035  snprintf(buf, buflen, fmt, menu->max);
1036  break;
1037 
1038  case 'h': /* hostname */
1039  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1040  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
1041  break;
1042 
1043  case 'l': /* approx length of current message in bytes */
1044  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1045  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
1046  snprintf(buf, buflen, fmt, tmp);
1047  break;
1048 
1049  case 'v':
1050  snprintf(buf, buflen, "%s", mutt_make_version());
1051  break;
1052 
1053  case 0:
1054  *buf = '\0';
1055  return src;
1056 
1057  default:
1058  snprintf(buf, buflen, "%%%s%c", prec, op);
1059  break;
1060  }
1061 
1062  if (optional)
1063  compose_status_line(buf, buflen, col, cols, menu, if_str);
1064  else if (flags & MUTT_FORMAT_OPTIONAL)
1065  compose_status_line(buf, buflen, col, cols, menu, else_str);
1066 
1067  return src;
1068 }
#define NONULL(x)
Definition: string2.h:37
GUI selectable list of items.
Definition: mutt_menu.h:82
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:1079
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1779
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:975
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:52
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:1560
+ 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 1096 of file compose.c.

1097 {
1098  char helpstr[1024]; // This isn't copied by the help bar
1099  char buf[PATH_MAX];
1100  int op_close = OP_NULL;
1101  int rc = -1;
1102  bool loop = true;
1103  bool fcc_set = false; /* has the user edited the Fcc: field ? */
1104  struct ComposeRedrawData redraw = { 0 };
1105  struct ComposeRedrawData *rd = &redraw;
1106 #ifdef USE_NNTP
1107  bool news = OptNewsSend; /* is it a news article ? */
1108 #endif
1109 
1111 
1112  rd->email = e;
1113  rd->fcc = fcc;
1114  rd->win = MuttIndexWindow;
1115 
1116  struct Menu *menu = mutt_menu_new(MENU_COMPOSE);
1117  menu->offset = HDR_ATTACH;
1119  menu->menu_tag = attach_tag;
1120 #ifdef USE_NNTP
1121  if (news)
1122  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeNewsHelp);
1123  else
1124 #endif
1125  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeHelp);
1127  menu->redraw_data = rd;
1128  mutt_menu_push_current(menu);
1129 
1130  struct AttachCtx *actx = mutt_actx_new();
1131  actx->email = e;
1132  mutt_update_compose_menu(actx, menu, true);
1133 
1134  update_crypt_info(rd);
1135 
1136  /* Since this is rather long lived, we don't use the pool */
1137  struct Buffer fname = mutt_buffer_make(PATH_MAX);
1138 
1139  while (loop)
1140  {
1141 #ifdef USE_NNTP
1142  OptNews = false; /* for any case */
1143 #endif
1144  const int op = mutt_menu_loop(menu);
1145  switch (op)
1146  {
1147  case OP_COMPOSE_EDIT_FROM:
1148  edit_address_list(HDR_FROM, &e->env->from, rd);
1149  update_crypt_info(rd);
1151  break;
1152 
1153  case OP_COMPOSE_EDIT_TO:
1154 #ifdef USE_NNTP
1155  if (news)
1156  break;
1157 #endif
1158  edit_address_list(HDR_TO, &e->env->to, rd);
1159  update_crypt_info(rd);
1161  break;
1162 
1163  case OP_COMPOSE_EDIT_BCC:
1164 #ifdef USE_NNTP
1165  if (news)
1166  break;
1167 #endif
1168  edit_address_list(HDR_BCC, &e->env->bcc, rd);
1169  update_crypt_info(rd);
1171  break;
1172 
1173  case OP_COMPOSE_EDIT_CC:
1174 #ifdef USE_NNTP
1175  if (news)
1176  break;
1177 #endif
1178  edit_address_list(HDR_CC, &e->env->cc, rd);
1179  update_crypt_info(rd);
1181  break;
1182 #ifdef USE_NNTP
1183  case OP_COMPOSE_EDIT_NEWSGROUPS:
1184  if (!news)
1185  break;
1186  if (e->env->newsgroups)
1187  mutt_str_strfcpy(buf, e->env->newsgroups, sizeof(buf));
1188  else
1189  buf[0] = '\0';
1190  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) == 0)
1191  {
1192  mutt_str_replace(&e->env->newsgroups, buf);
1194  if (e->env->newsgroups)
1195  mutt_paddstr(W, e->env->newsgroups);
1196  else
1198  }
1199  break;
1200 
1201  case OP_COMPOSE_EDIT_FOLLOWUP_TO:
1202  if (!news)
1203  break;
1204  if (e->env->followup_to)
1205  mutt_str_strfcpy(buf, e->env->followup_to, sizeof(buf));
1206  else
1207  buf[0] = '\0';
1208  if (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) == 0)
1209  {
1210  mutt_str_replace(&e->env->followup_to, buf);
1212  if (e->env->followup_to)
1213  mutt_paddstr(W, e->env->followup_to);
1214  else
1216  }
1217  break;
1218 
1219  case OP_COMPOSE_EDIT_X_COMMENT_TO:
1220  if (!(news && C_XCommentTo))
1221  break;
1222  if (e->env->x_comment_to)
1223  mutt_str_strfcpy(buf, e->env->x_comment_to, sizeof(buf));
1224  else
1225  buf[0] = '\0';
1226  if (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) == 0)
1227  {
1228  mutt_str_replace(&e->env->x_comment_to, buf);
1230  if (e->env->x_comment_to)
1232  else
1234  }
1235  break;
1236 #endif
1237 
1238  case OP_COMPOSE_EDIT_SUBJECT:
1239  if (e->env->subject)
1240  mutt_str_strfcpy(buf, e->env->subject, sizeof(buf));
1241  else
1242  buf[0] = '\0';
1243  if (mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) == 0)
1244  {
1245  mutt_str_replace(&e->env->subject, buf);
1247  if (e->env->subject)
1248  mutt_paddstr(W, e->env->subject);
1249  else
1251  }
1253  break;
1254 
1255  case OP_COMPOSE_EDIT_REPLY_TO:
1258  break;
1259 
1260  case OP_COMPOSE_EDIT_FCC:
1261  mutt_buffer_copy(&fname, fcc);
1262  if (mutt_buffer_get_field(_("Fcc: "), &fname, MUTT_FILE | MUTT_CLEAR) == 0)
1263  {
1264  mutt_buffer_copy(fcc, &fname);
1267  mutt_paddstr(W, mutt_b2s(fcc));
1268  fcc_set = true;
1269  }
1271  break;
1272 
1273  case OP_COMPOSE_EDIT_MESSAGE:
1274  if (C_Editor && (mutt_str_strcmp("builtin", C_Editor) != 0) && !C_EditHeaders)
1275  {
1280  menu->redraw = REDRAW_FULL;
1282  break;
1283  }
1284  /* fallthrough */
1285 
1286  case OP_COMPOSE_EDIT_HEADERS:
1288  if ((mutt_str_strcmp("builtin", C_Editor) != 0) &&
1289  ((op == OP_COMPOSE_EDIT_HEADERS) || ((op == OP_COMPOSE_EDIT_MESSAGE) && C_EditHeaders)))
1290  {
1291  const char *tag = NULL;
1292  char *err = NULL;
1293  mutt_env_to_local(e->env);
1295  if (mutt_env_to_intl(e->env, &tag, &err))
1296  {
1297  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
1298  FREE(&err);
1299  }
1300  update_crypt_info(rd);
1301  }
1302  else
1303  {
1304  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
1305  * attachment list could change if the user invokes ~v to edit
1306  * the message with headers, in which we need to execute the
1307  * code below to regenerate the index array */
1308  mutt_builtin_editor(e->content->filename, e, e_cur);
1309  }
1310 
1313 
1314  /* attachments may have been added */
1315  if (actx->idxlen && actx->idx[actx->idxlen - 1]->content->next)
1316  {
1317  mutt_actx_entries_free(actx);
1318  mutt_update_compose_menu(actx, menu, true);
1319  }
1320 
1321  menu->redraw = REDRAW_FULL;
1323  break;
1324 
1325  case OP_COMPOSE_ATTACH_KEY:
1326  {
1327  if (!(WithCrypto & APPLICATION_PGP))
1328  break;
1329  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1331  if (ap->content)
1332  {
1333  update_idx(menu, actx, ap);
1334  menu->redraw |= REDRAW_INDEX;
1335  }
1336  else
1337  FREE(&ap);
1338 
1339  menu->redraw |= REDRAW_STATUS;
1340 
1342  break;
1343  }
1344 
1345  case OP_COMPOSE_MOVE_UP:
1346  if (menu->current == 0)
1347  {
1348  mutt_error(_("Attachment is already at top"));
1349  break;
1350  }
1351  if (menu->current == 1)
1352  {
1353  mutt_error(_("The fundamental part can't be moved"));
1354  break;
1355  }
1356  compose_attach_swap(e->content, actx->idx, menu->current - 1);
1357  menu->redraw = REDRAW_INDEX;
1358  menu->current--;
1359  break;
1360 
1361  case OP_COMPOSE_MOVE_DOWN:
1362  if (menu->current == (actx->idxlen - 1))
1363  {
1364  mutt_error(_("Attachment is already at bottom"));
1365  break;
1366  }
1367  if (menu->current == 0)
1368  {
1369  mutt_error(_("The fundamental part can't be moved"));
1370  break;
1371  }
1372  compose_attach_swap(e->content, actx->idx, menu->current);
1373  menu->redraw = REDRAW_INDEX;
1374  menu->current++;
1375  break;
1376 
1377  case OP_COMPOSE_GROUP_ALTS:
1378  {
1379  if (menu->tagged < 2)
1380  {
1381  mutt_error(
1382  _("Grouping 'alternatives' requires at least 2 tagged messages"));
1383  break;
1384  }
1385 
1386  struct Body *group = mutt_body_new();
1387  group->type = TYPE_MULTIPART;
1388  group->subtype = mutt_str_strdup("alternative");
1389  group->disposition = DISP_INLINE;
1390 
1391  struct Body *alts = NULL;
1392  /* group tagged message into a multipart/alternative */
1393  struct Body *bptr = e->content;
1394  for (int i = 0; bptr;)
1395  {
1396  if (bptr->tagged)
1397  {
1398  bptr->tagged = false;
1399  bptr->disposition = DISP_INLINE;
1400 
1401  /* for first match, set group desc according to match */
1402 #define ALTS_TAG "Alternatives for \"%s\""
1403  if (!group->description)
1404  {
1405  char *p = bptr->description ? bptr->description : bptr->filename;
1406  if (p)
1407  {
1408  group->description =
1409  mutt_mem_calloc(1, strlen(p) + strlen(ALTS_TAG) + 1);
1410  sprintf(group->description, ALTS_TAG, p);
1411  }
1412  }
1413 
1414  // append bptr to the alts list, and remove from the e->content list
1415  if (alts)
1416  {
1417  alts->next = bptr;
1418  bptr = bptr->next;
1419  alts = alts->next;
1420  alts->next = NULL;
1421  }
1422  else
1423  {
1424  group->parts = bptr;
1425  alts = bptr;
1426  bptr = bptr->next;
1427  alts->next = NULL;
1428  }
1429 
1430  for (int j = i; j < actx->idxlen - 1; j++)
1431  {
1432  actx->idx[j] = actx->idx[j + 1];
1433  actx->idx[j + 1] = NULL; /* for debug reason */
1434  }
1435  actx->idxlen--;
1436  }
1437  else
1438  {
1439  bptr = bptr->next;
1440  i++;
1441  }
1442  }
1443 
1444  group->next = NULL;
1446 
1447  /* if no group desc yet, make one up */
1448  if (!group->description)
1449  group->description = mutt_str_strdup("unknown alternative group");
1450 
1451  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1452  gptr->content = group;
1453  update_idx(menu, actx, gptr);
1454  menu->redraw = REDRAW_INDEX;
1455  break;
1456  }
1457 
1458  case OP_COMPOSE_GROUP_LINGUAL:
1459  {
1460  if (menu->tagged < 2)
1461  {
1462  mutt_error(
1463  _("Grouping 'multilingual' requires at least 2 tagged messages"));
1464  break;
1465  }
1466 
1467  /* traverse to see whether all the parts have Content-Language: set */
1468  int tagged_with_lang_num = 0;
1469  for (struct Body *b = e->content; b; b = b->next)
1470  if (b->tagged && b->language && *b->language)
1471  tagged_with_lang_num++;
1472 
1473  if (menu->tagged != tagged_with_lang_num)
1474  {
1475  if (mutt_yesorno(
1476  _("Not all parts have 'Content-Language' set, continue?"), MUTT_YES) != MUTT_YES)
1477  {
1478  mutt_message(_("Not sending this message"));
1479  break;
1480  }
1481  }
1482 
1483  struct Body *group = mutt_body_new();
1484  group->type = TYPE_MULTIPART;
1485  group->subtype = mutt_str_strdup("multilingual");
1486  group->disposition = DISP_INLINE;
1487 
1488  struct Body *alts = NULL;
1489  /* group tagged message into a multipart/multilingual */
1490  struct Body *bptr = e->content;
1491  for (int i = 0; bptr;)
1492  {
1493  if (bptr->tagged)
1494  {
1495  bptr->tagged = false;
1496  bptr->disposition = DISP_INLINE;
1497 
1498  /* for first match, set group desc according to match */
1499 #define LINGUAL_TAG "Multilingual part for \"%s\""
1500  if (!group->description)
1501  {
1502  char *p = bptr->description ? bptr->description : bptr->filename;
1503  if (p)
1504  {
1505  group->description =
1506  mutt_mem_calloc(1, strlen(p) + strlen(LINGUAL_TAG) + 1);
1507  sprintf(group->description, LINGUAL_TAG, p);
1508  }
1509  }
1510 
1511  // append bptr to the alts list, and remove from the e->content list
1512  if (alts)
1513  {
1514  alts->next = bptr;
1515  bptr = bptr->next;
1516  alts = alts->next;
1517  alts->next = NULL;
1518  }
1519  else
1520  {
1521  group->parts = bptr;
1522  alts = bptr;
1523  bptr = bptr->next;
1524  alts->next = NULL;
1525  }
1526 
1527  for (int j = i; j < actx->idxlen - 1; j++)
1528  {
1529  actx->idx[j] = actx->idx[j + 1];
1530  actx->idx[j + 1] = NULL; /* for debug reason */
1531  }
1532  actx->idxlen--;
1533  }
1534  else
1535  {
1536  bptr = bptr->next;
1537  i++;
1538  }
1539  }
1540 
1541  group->next = NULL;
1543 
1544  /* if no group desc yet, make one up */
1545  if (!group->description)
1546  group->description = mutt_str_strdup("unknown multilingual group");
1547 
1548  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1549  gptr->content = group;
1550  update_idx(menu, actx, gptr);
1551  menu->redraw = REDRAW_INDEX;
1552  break;
1553  }
1554 
1555  case OP_COMPOSE_ATTACH_FILE:
1556  {
1557  char *prompt = _("Attach file");
1558  int numfiles = 0;
1559  char **files = NULL;
1560 
1561  mutt_buffer_reset(&fname);
1562  if ((mutt_buffer_enter_fname_full(prompt, &fname, false, true, &files,
1563  &numfiles, MUTT_SEL_MULTI) == -1) ||
1564  mutt_buffer_is_empty(&fname))
1565  {
1566  break;
1567  }
1568 
1569  bool error = false;
1570  if (numfiles > 1)
1571  {
1572  mutt_message(ngettext("Attaching selected file...",
1573  "Attaching selected files...", numfiles));
1574  }
1575  for (int i = 0; i < numfiles; i++)
1576  {
1577  char *att = files[i];
1578  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1579  ap->unowned = true;
1580  ap->content = mutt_make_file_attach(att);
1581  if (ap->content)
1582  update_idx(menu, actx, ap);
1583  else
1584  {
1585  error = true;
1586  mutt_error(_("Unable to attach %s"), att);
1587  FREE(&ap);
1588  }
1589  FREE(&files[i]);
1590  }
1591 
1592  FREE(&files);
1593  if (!error)
1594  mutt_clear_error();
1595 
1596  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1598  break;
1599  }
1600 
1601  case OP_COMPOSE_ATTACH_MESSAGE:
1602 #ifdef USE_NNTP
1603  case OP_COMPOSE_ATTACH_NEWS_MESSAGE:
1604 #endif
1605  {
1606  mutt_buffer_reset(&fname);
1607  char *prompt = _("Open mailbox to attach message from");
1608 
1609 #ifdef USE_NNTP
1610  OptNews = false;
1611  if (Context && (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE))
1612  {
1614  if (!CurrentNewsSrv)
1615  break;
1616 
1617  prompt = _("Open newsgroup to attach message from");
1618  OptNews = true;
1619  }
1620 #endif
1621 
1622  if (Context)
1623 #ifdef USE_NNTP
1624  if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->mailbox->magic == MUTT_NNTP))
1625 #endif
1626  {
1629  }
1630 
1631  if ((mutt_buffer_enter_fname(prompt, &fname, true) == -1) ||
1632  mutt_buffer_is_empty(&fname))
1633  {
1634  break;
1635  }
1636 
1637 #ifdef USE_NNTP
1638  if (OptNews)
1640  else
1641 #endif
1642  mutt_buffer_expand_path(&fname);
1643 #ifdef USE_IMAP
1644  if (imap_path_probe(mutt_b2s(&fname), NULL) != MUTT_IMAP)
1645 #endif
1646 #ifdef USE_POP
1647  if (pop_path_probe(mutt_b2s(&fname), NULL) != MUTT_POP)
1648 #endif
1649 #ifdef USE_NNTP
1650  if (!OptNews && (nntp_path_probe(mutt_b2s(&fname), NULL) != MUTT_NNTP))
1651 #endif
1652  /* check to make sure the file exists and is readable */
1653  if (access(mutt_b2s(&fname), R_OK) == -1)
1654  {
1655  mutt_perror(mutt_b2s(&fname));
1656  break;
1657  }
1658 
1659  menu->redraw = REDRAW_FULL;
1660 
1661  struct Mailbox *m = mx_path_resolve(mutt_b2s(&fname));
1662  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
1663  if (!ctx)
1664  {
1665  mutt_error(_("Unable to open mailbox %s"), mutt_b2s(&fname));
1666  mailbox_free(&m);
1667  break;
1668  }
1669 
1670  if (ctx->mailbox->msg_count == 0)
1671  {
1672  mx_mbox_close(&ctx);
1673  mutt_error(_("No messages in that folder"));
1674  break;
1675  }
1676 
1677  struct Context *ctx_cur = Context; /* remember current folder and sort methods */
1678  int old_sort = C_Sort; /* C_Sort, SortAux could be changed in mutt_index_menu() */
1679  int old_sort_aux = C_SortAux;
1680 
1681  Context = ctx;
1682  OptAttachMsg = true;
1683  mutt_message(_("Tag the messages you want to attach"));
1684  op_close = mutt_index_menu();
1685  OptAttachMsg = false;
1686 
1687  if (!Context)
1688  {
1689  /* go back to the folder we started from */
1690  Context = ctx_cur;
1691  /* Restore old $sort and $sort_aux */
1692  C_Sort = old_sort;
1693  C_SortAux = old_sort_aux;
1694  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1695  break;
1696  }
1697 
1698  for (int i = 0; i < Context->mailbox->msg_count; i++)
1699  {
1700  if (!message_is_tagged(Context, i))
1701  continue;
1702 
1703  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1705  Context->mailbox->emails[i], true);
1706  if (ap->content)
1707  update_idx(menu, actx, ap);
1708  else
1709  {
1710  mutt_error(_("Unable to attach"));
1711  FREE(&ap);
1712  }
1713  }
1714  menu->redraw |= REDRAW_FULL;
1715 
1716  if (op_close == OP_QUIT)
1718  else
1719  {
1721  ctx_free(&Context);
1722  }
1723 
1724  /* go back to the folder we started from */
1725  Context = ctx_cur;
1726  /* Restore old $sort and $sort_aux */
1727  C_Sort = old_sort;
1728  C_SortAux = old_sort_aux;
1730  break;
1731  }
1732 
1733  case OP_DELETE:
1734  CHECK_COUNT;
1735  if (CUR_ATTACH->unowned)
1736  CUR_ATTACH->content->unlink = false;
1737  if (delete_attachment(actx, menu->current) == -1)
1738  break;
1739  mutt_update_compose_menu(actx, menu, false);
1740  if (menu->current == 0)
1741  e->content = actx->idx[0]->content;
1742 
1744  break;
1745 
1746  case OP_COMPOSE_TOGGLE_RECODE:
1747  {
1748  CHECK_COUNT;
1749  if (!mutt_is_text_part(CUR_ATTACH->content))
1750  {
1751  mutt_error(_("Recoding only affects text attachments"));
1752  break;
1753  }
1754  CUR_ATTACH->content->noconv = !CUR_ATTACH->content->noconv;
1755  if (CUR_ATTACH->content->noconv)
1756  mutt_message(_("The current attachment won't be converted"));
1757  else
1758  mutt_message(_("The current attachment will be converted"));
1759  menu->redraw = REDRAW_CURRENT;
1761  break;
1762  }
1763 
1764  case OP_COMPOSE_EDIT_DESCRIPTION:
1765  CHECK_COUNT;
1767  buf, CUR_ATTACH->content->description ? CUR_ATTACH->content->description : "",
1768  sizeof(buf));
1769  /* header names should not be translated */
1770  if (mutt_get_field("Description: ", buf, sizeof(buf), 0) == 0)
1771  {
1772  mutt_str_replace(&CUR_ATTACH->content->description, buf);
1773  menu->redraw = REDRAW_CURRENT;
1774  }
1776  break;
1777 
1778  case OP_COMPOSE_UPDATE_ENCODING:
1779  CHECK_COUNT;
1780  if (menu->tagprefix)
1781  {
1782  struct Body *top = NULL;
1783  for (top = e->content; top; top = top->next)
1784  {
1785  if (top->tagged)
1786  mutt_update_encoding(top);
1787  }
1788  menu->redraw = REDRAW_FULL;
1789  }
1790  else
1791  {
1792  mutt_update_encoding(CUR_ATTACH->content);
1794  }
1796  break;
1797 
1798  case OP_COMPOSE_TOGGLE_DISPOSITION:
1799  /* toggle the content-disposition between inline/attachment */
1800  CUR_ATTACH->content->disposition =
1801  (CUR_ATTACH->content->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
1802  menu->redraw = REDRAW_CURRENT;
1803  break;
1804 
1805  case OP_EDIT_TYPE:
1806  CHECK_COUNT;
1807  {
1808  mutt_edit_content_type(NULL, CUR_ATTACH->content, NULL);
1809 
1810  /* this may have been a change to text/something */
1811  mutt_update_encoding(CUR_ATTACH->content);
1812 
1813  menu->redraw = REDRAW_CURRENT;
1814  }
1816  break;
1817 
1818  case OP_COMPOSE_EDIT_LANGUAGE:
1819  CHECK_COUNT;
1820  buf[0] = '\0'; /* clear buffer first */
1821  if (CUR_ATTACH->content->language)
1822  mutt_str_strfcpy(buf, CUR_ATTACH->content->language, sizeof(buf));
1823  if (mutt_get_field("Content-Language: ", buf, sizeof(buf), 0) == 0)
1824  {
1825  CUR_ATTACH->content->language = mutt_str_strdup(buf);
1827  mutt_clear_error();
1828  }
1829  else
1830  mutt_warning(_("Empty 'Content-Language'"));
1832  break;
1833 
1834  case OP_COMPOSE_EDIT_ENCODING:
1835  CHECK_COUNT;
1836  mutt_str_strfcpy(buf, ENCODING(CUR_ATTACH->content->encoding), sizeof(buf));
1837  if ((mutt_get_field("Content-Transfer-Encoding: ", buf, sizeof(buf), 0) == 0) &&
1838  (buf[0] != '\0'))
1839  {
1840  int enc = mutt_check_encoding(buf);
1841  if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1842  {
1843  CUR_ATTACH->content->encoding = enc;
1845  mutt_clear_error();
1846  }
1847  else
1848  mutt_error(_("Invalid encoding"));
1849  }
1851  break;
1852 
1853  case OP_COMPOSE_SEND_MESSAGE:
1854  /* Note: We don't invoke send2-hook here, since we want to leave
1855  * users an opportunity to change settings from the ":" prompt. */
1856  if (check_attachments(actx) != 0)
1857  {
1858  menu->redraw = REDRAW_FULL;
1859  break;
1860  }
1861 
1862 #ifdef MIXMASTER
1863  if (!STAILQ_EMPTY(&e->chain) && (mix_check_message(e) != 0))
1864  break;
1865 #endif
1866 
1867  if (!fcc_set && !mutt_buffer_is_empty(fcc))
1868  {
1869  enum QuadOption ans =
1870  query_quadoption(C_Copy, _("Save a copy of this message?"));
1871  if (ans == MUTT_ABORT)
1872  break;
1873  else if (ans == MUTT_NO)
1874  mutt_buffer_reset(fcc);
1875  }
1876 
1877  loop = false;
1878  rc = 0;
1879  break;
1880 
1881  case OP_COMPOSE_EDIT_FILE:
1882  CHECK_COUNT;
1883  mutt_edit_file(NONULL(C_Editor), CUR_ATTACH->content->filename);
1884  mutt_update_encoding(CUR_ATTACH->content);
1887  break;
1888 
1889  case OP_COMPOSE_TOGGLE_UNLINK:
1890  CHECK_COUNT;
1891  CUR_ATTACH->content->unlink = !CUR_ATTACH->content->unlink;
1892 
1893  menu->redraw = REDRAW_INDEX;
1894  /* No send2hook since this doesn't change the message. */
1895  break;
1896 
1897  case OP_COMPOSE_GET_ATTACHMENT:
1898  CHECK_COUNT;
1899  if (menu->tagprefix)
1900  {
1901  for (struct Body *top = e->content; top; top = top->next)
1902  {
1903  if (top->tagged)
1905  }
1906  menu->redraw = REDRAW_FULL;
1907  }
1908  else if (mutt_get_tmp_attachment(CUR_ATTACH->content) == 0)
1909  menu->redraw = REDRAW_CURRENT;
1910 
1911  /* No send2hook since this doesn't change the message. */
1912  break;
1913 
1914  case OP_COMPOSE_RENAME_ATTACHMENT:
1915  {
1916  CHECK_COUNT;
1917  char *src = NULL;
1918  if (CUR_ATTACH->content->d_filename)
1919  src = CUR_ATTACH->content->d_filename;
1920  else
1921  src = CUR_ATTACH->content->filename;
1923  int ret = mutt_buffer_get_field(_("Send attachment with name: "), &fname, MUTT_FILE);
1924  if (ret == 0)
1925  {
1926  /* As opposed to RENAME_FILE, we don't check buf[0] because it's
1927  * valid to set an empty string here, to erase what was set */
1928  mutt_str_replace(&CUR_ATTACH->content->d_filename, mutt_b2s(&fname));
1929  menu->redraw = REDRAW_CURRENT;
1930  }
1931  break;
1932  }
1933 
1934  case OP_COMPOSE_RENAME_FILE:
1935  CHECK_COUNT;
1936  mutt_buffer_strcpy(&fname, CUR_ATTACH->content->filename);
1938  if ((mutt_buffer_get_field(_("Rename to: "), &fname, MUTT_FILE) == 0) &&
1939  !mutt_buffer_is_empty(&fname))
1940  {
1941  struct stat st;
1942  if (stat(CUR_ATTACH->content->filename, &st) == -1)
1943  {
1944  /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
1945  mutt_error(_("Can't stat %s: %s"), mutt_b2s(&fname), strerror(errno));
1946  break;
1947  }
1948 
1949  mutt_buffer_expand_path(&fname);
1950  if (mutt_file_rename(CUR_ATTACH->content->filename, mutt_b2s(&fname)))
1951  break;
1952 
1953  mutt_str_replace(&CUR_ATTACH->content->filename, mutt_b2s(&fname));
1954  menu->redraw = REDRAW_CURRENT;
1955 
1956  if (CUR_ATTACH->content->stamp >= st.st_mtime)
1958  }
1960  break;
1961 
1962  case OP_COMPOSE_NEW_MIME:
1963  {
1964  mutt_buffer_reset(&fname);
1965  if ((mutt_buffer_get_field(_("New file: "), &fname, MUTT_FILE) != 0) ||
1966  mutt_buffer_is_empty(&fname))
1967  {
1968  continue;
1969  }
1970  mutt_buffer_expand_path(&fname);
1971 
1972  /* Call to lookup_mime_type () ? maybe later */
1973  char type[256] = { 0 };
1974  if ((mutt_get_field("Content-Type: ", type, sizeof(type), 0) != 0) ||
1975  (type[0] == '\0'))
1976  {
1977  continue;
1978  }
1979 
1980  char *p = strchr(type, '/');
1981  if (!p)
1982  {
1983  mutt_error(_("Content-Type is of the form base/sub"));
1984  continue;
1985  }
1986  *p++ = 0;
1987  enum ContentType itype = mutt_check_mime_type(type);
1988  if (itype == TYPE_OTHER)
1989  {
1990  mutt_error(_("Unknown Content-Type %s"), type);
1991  continue;
1992  }
1993  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1994  /* Touch the file */
1995  FILE *fp = mutt_file_fopen(mutt_b2s(&fname), "w");
1996  if (!fp)
1997  {
1998  mutt_error(_("Can't create file %s"), mutt_b2s(&fname));
1999  FREE(&ap);
2000  continue;
2001  }
2002  mutt_file_fclose(&fp);
2003 
2004  ap->content = mutt_make_file_attach(mutt_b2s(&fname));
2005  if (!ap->content)
2006  {
2007  mutt_error(_("What we have here is a failure to make an attachment"));
2008  FREE(&ap);
2009  continue;
2010  }
2011  update_idx(menu, actx, ap);
2012 
2013  CUR_ATTACH->content->type = itype;
2014  mutt_str_replace(&CUR_ATTACH->content->subtype, p);
2015  CUR_ATTACH->content->unlink = true;
2016  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
2017 
2018  if (mutt_compose_attachment(CUR_ATTACH->content))
2019  {
2020  mutt_update_encoding(CUR_ATTACH->content);
2021  menu->redraw = REDRAW_FULL;
2022  }
2024  break;
2025  }
2026 
2027  case OP_COMPOSE_EDIT_MIME:
2028  CHECK_COUNT;
2029  if (mutt_edit_attachment(CUR_ATTACH->content))
2030  {
2031  mutt_update_encoding(CUR_ATTACH->content);
2032  menu->redraw = REDRAW_FULL;
2033  }
2035  break;
2036 
2037  case OP_VIEW_ATTACH:
2038  case OP_DISPLAY_HEADERS:
2039  CHECK_COUNT;
2040  mutt_attach_display_loop(menu, op, NULL, actx, false);
2041  menu->redraw = REDRAW_FULL;
2042  /* no send2hook, since this doesn't modify the message */
2043  break;
2044 
2045  case OP_SAVE:
2046  CHECK_COUNT;
2047  mutt_save_attachment_list(actx, NULL, menu->tagprefix,
2048  CUR_ATTACH->content, NULL, menu);
2049  /* no send2hook, since this doesn't modify the message */
2050  break;
2051 
2052  case OP_PRINT:
2053  CHECK_COUNT;
2054  mutt_print_attachment_list(actx, NULL, menu->tagprefix, CUR_ATTACH->content);
2055  /* no send2hook, since this doesn't modify the message */
2056  break;
2057 
2058  case OP_PIPE:
2059  case OP_FILTER:
2060  CHECK_COUNT;
2061  mutt_pipe_attachment_list(actx, NULL, menu->tagprefix,
2062  CUR_ATTACH->content, (op == OP_FILTER));
2063  if (op == OP_FILTER) /* cte might have changed */
2064  menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
2065  menu->redraw |= REDRAW_STATUS;
2067  break;
2068 
2069  case OP_EXIT:
2070  {
2071  enum QuadOption ans =
2072  query_quadoption(C_Postpone, _("Save (postpone) draft message?"));
2073  if (ans == MUTT_NO)
2074  {
2075  for (int i = 0; i < actx->idxlen; i++)
2076  if (actx->idx[i]->unowned)
2077  actx->idx[i]->content->unlink = false;
2078 
2079  if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
2080  {
2081  for (int i = 0; i < actx->idxlen; i++)
2082  {
2083  /* avoid freeing other attachments */
2084  actx->idx[i]->content->next = NULL;
2085  /* See the comment in delete_attachment() */
2086  if (!actx->idx[i]->content->email)
2087  actx->idx[i]->content->parts = NULL;
2088  mutt_body_free(&actx->idx[i]->content);
2089  }
2090  }
2091  rc = -1;
2092  loop = false;
2093  break;
2094  }
2095  else if (ans == MUTT_ABORT)
2096  break; /* abort */
2097  }
2098  /* fallthrough */
2099 
2100  case OP_COMPOSE_POSTPONE_MESSAGE:
2101  if (check_attachments(actx) != 0)
2102  {
2103  menu->redraw = REDRAW_FULL;
2104  break;
2105  }
2106 
2107  loop = false;
2108  rc = 1;
2109  break;
2110 
2111  case OP_COMPOSE_ISPELL:
2112  endwin();
2113  snprintf(buf, sizeof(buf), "%s -x %s", NONULL(C_Ispell), e->content->filename);
2114  if (mutt_system(buf) == -1)
2115  mutt_error(_("Error running \"%s\""), buf);
2116  else
2117  {
2119  menu->redraw |= REDRAW_STATUS;
2120  }
2121  break;
2122 
2123  case OP_COMPOSE_WRITE_MESSAGE:
2124  mutt_buffer_reset(&fname);
2125  if (Context)
2126  {
2129  }
2130  if (actx->idxlen)
2131  e->content = actx->idx[0]->content;
2132  if ((mutt_buffer_enter_fname(_("Write message to mailbox"), &fname, true) != -1) &&
2133  !mutt_buffer_is_empty(&fname))
2134  {
2135  mutt_message(_("Writing message to %s ..."), mutt_b2s(&fname));
2136  mutt_buffer_expand_path(&fname);
2137 
2138  if (e->content->next)
2140 
2141  if (mutt_write_fcc(mutt_b2s(&fname), e, NULL, false, NULL, NULL) == 0)
2142  mutt_message(_("Message written"));
2143 
2145  }
2146  break;
2147 
2148  case OP_COMPOSE_PGP_MENU:
2149  if (!(WithCrypto & APPLICATION_PGP))
2150  break;
2151  if (!crypt_has_module_backend(APPLICATION_PGP))
2152  {
2153  mutt_error(_("No PGP backend configured"));
2154  break;
2155  }
2156  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
2157  {
2158  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2159  {
2160  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2161  {
2162  mutt_clear_error();
2163  break;
2164  }
2165  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2166  }
2167  e->security &= ~APPLICATION_SMIME;
2168  e->security |= APPLICATION_PGP;
2169  update_crypt_info(rd);
2170  }
2171  e->security = crypt_pgp_send_menu(e);
2172  update_crypt_info(rd);
2174  break;
2175 
2176  case OP_FORGET_PASSPHRASE:
2178  break;
2179 
2180  case OP_COMPOSE_SMIME_MENU:
2181  if (!(WithCrypto & APPLICATION_SMIME))
2182  break;
2183  if (!crypt_has_module_backend(APPLICATION_SMIME))
2184  {
2185  mutt_error(_("No S/MIME backend configured"));
2186  break;
2187  }
2188 
2189  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
2190  {
2191  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2192  {
2193  if (mutt_yesorno(_("PGP already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2194  {
2195  mutt_clear_error();
2196  break;
2197  }
2198  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2199  }
2200  e->security &= ~APPLICATION_PGP;
2202  update_crypt_info(rd);
2203  }
2205  update_crypt_info(rd);
2207  break;
2208 
2209 #ifdef MIXMASTER
2210  case OP_COMPOSE_MIX:
2211  mix_make_chain(menu->indexwin, &e->chain, menu->indexwin->cols);
2213  break;
2214 #endif
2215 #ifdef USE_AUTOCRYPT
2216  case OP_COMPOSE_AUTOCRYPT_MENU:
2217  if (!C_Autocrypt)
2218  break;
2219 
2220  if ((WithCrypto & APPLICATION_SMIME) && (e->security & APPLICATION_SMIME))
2221  {
2222  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
2223  {
2224  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
2225  {
2226  mutt_clear_error();
2227  break;
2228  }
2229  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2230  }
2231  e->security &= ~APPLICATION_SMIME;
2232  e->security |= APPLICATION_PGP;
2233  update_crypt_info(rd);
2234  }
2236  update_crypt_info(rd);
2238  break;
2239 #endif
2240  }
2241  }
2242 
2243  mutt_buffer_dealloc(&fname);
2244 
2245 #ifdef USE_AUTOCRYPT
2246  /* This is a fail-safe to make sure the bit isn't somehow turned
2247  * on. The user could have disabled the option after setting SEC_AUTOCRYPT,
2248  * or perhaps resuming or replying to an autocrypt message. */
2249  if (!C_Autocrypt)
2250  e->security &= ~SEC_AUTOCRYPT;
2251 #endif
2252 
2253  mutt_menu_pop_current(menu);
2254  mutt_menu_free(&menu);
2255 
2256  if (actx->idxlen)
2257  e->content = actx->idx[0]->content;
2258  else
2259  e->content = NULL;
2260 
2261  mutt_actx_free(&actx);
2262 
2263  return rc;
2264 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
struct NntpAccountData * nntp_select_server(struct Mailbox *m, char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:982
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1517
static int delete_attachment(struct AttachCtx *actx, int x)
Delete an attachment.
Definition: compose.c:763
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1449
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:569
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:203
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:1142
int msg_count
Total number of messages.
Definition: mailbox.h:102
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:1773
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
#define mutt_perror(...)
Definition: logging.h:85
GUI selectable list of items.
Definition: mutt_menu.h:82
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2430
struct ConnAccount account
Definition: connection.h:36
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:561
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
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3340
#define mutt_message(...)
Definition: logging.h:83
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1334
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
static void compose_custom_redraw(struct Menu *menu)
Redraw the compose menu - Implements Menu::menu_custom_redraw()
Definition: compose.c:892
static void edit_address_list(int line, struct AddressList *al, struct ComposeRedrawData *rd)
Let the user edit the address list.
Definition: compose.c:728
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:648
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:117
"To:" field
Definition: compose.c:135
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:105
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
"Cc:" field
Definition: compose.c:136
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:255
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:494
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:253
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:184
struct Email * email
Definition: compose.c:109
char * C_Ispell
Config: External command to perform spell-checking.
Definition: compose.c:96
struct Buffer * fcc
Definition: compose.c:110
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:53
"Subject:" field
Definition: compose.c:138
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
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
static int check_attachments(struct AttachCtx *actx)
Check if any attachments have changed or been deleted.
Definition: compose.c:578
"From:" field
Definition: compose.c:134
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:704
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
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:3258
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
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:1194
static void snd_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the attachment list - Implements Menu::menu_make_entry()
Definition: compose.c:316
#define CUR_ATTACH
Definition: compose.c:125
size_t dsize
Length of data.
Definition: buffer.h:37
void * redraw_data
Definition: mutt_menu.h:150
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1023
int mutt_get_tmp_attachment(struct Body *a)
Get a temporary copy of an attachment.
Definition: mutt_attach.c:66
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:375
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:215
struct Mailbox * mailbox
Definition: context.h:50
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:639
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1651
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:55
enum ContentType mutt_check_mime_type(const char *s)
Check a MIME type string.
Definition: parse.c:317
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:529
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1486
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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:395
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
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:307
static void compose_attach_swap(struct Body *msg, struct AttachPtr **idx, short first)
Swap two adjacent entries in the attachment list.
Definition: compose.c:941
void mutt_rfc3676_space_unstuff(struct Email *e)
Remove RFC3676 space stuffing.
Definition: rfc3676.c:486
void(* menu_custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:149
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition: attach.c:131
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:115
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:1747
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:697
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: globals.h:131
static const struct Mapping ComposeHelp[]
Definition: compose.c:207
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
WHERE short C_SortAux
Config: Secondary sort method for the index.
Definition: sort.h:59
#define HDR_XOFFSET
Definition: compose.c:161
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE struct Context * Context
Definition: globals.h:44
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:447
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:54
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
int mutt_check_encoding(const char *c)
Check the encoding type.
Definition: parse.c:426
#define ALTS_TAG
A mailbox.
Definition: mailbox.h:92
#define PATH_MAX
Definition: mutt.h:50
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
bool tagprefix
Definition: mutt_menu.h:93
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:750
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:374
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:849
char * description
content-description
Definition: body.h:40
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:453
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
#define W
Definition: compose.c:162
#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:223
int tagged
Number of tagged entries.
Definition: mutt_menu.h:111
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:551
#define MUTT_FILE
Do file completion.
Definition: mutt.h:64
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:198
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
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:137
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
"Bcc:" field
Definition: compose.c:137
#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
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:878
struct Connection * conn
Definition: nntp.h:102
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
Definition: recvattach.c:873
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:167
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:115
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:343
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:292
struct Body * content
Attachment.
Definition: attach.h:36
unsigned char C_Postpone
Config: Save messages to the C_Postponed folder.
Definition: compose.c:97
#define mutt_error(...)
Definition: logging.h:84
int mutt_builtin_editor(const char *path, struct Email *e_new, struct Email *e_cur)
Show the user the built-in editor.
Definition: edit.c:402
enum MailboxType pop_path_probe(const char *path, const struct stat *st)
Is this a POP Mailbox? - Implements MxOps::path_probe()
Definition: pop.c:1245
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:468
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:330
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)
XXX.
Definition: mx.c:1552
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:36
#define STAILQ_EMPTY(head)
Definition: queue.h:346
Where to start printing the attachments.
Definition: compose.c:155
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: compose.c:285
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:49
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2824
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1229
int current
Current entry.
Definition: mutt_menu.h:87
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
"Fcc:" (save folder) field
Definition: compose.c:140
#define CHECK_COUNT
Definition: compose.c:118
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
int mutt_index_menu(void)
Display a list of emails.
Definition: index.c:1067
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
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:52
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
A set of attachments.
Definition: attach.h:49
Encoding unknown.
Definition: mime.h:48
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:351
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
Keep track when the compose screen needs redrawing.
Definition: compose.c:107
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:87
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
UUEncoded text.
Definition: mime.h:54
bool message_is_tagged(struct Context *ctx, int index)
Is a message in the index tagged (and within limit)
Definition: context.c:348
#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:116
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:786
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:75
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
ContentType
Content-Type.
Definition: mime.h:29
"Reply-To:" field
Definition: compose.c:139
+ 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 95 of file compose.c.

◆ C_Ispell

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 96 of file compose.c.

◆ C_Postpone

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 97 of file compose.c.

◆ There_are_no_attachments

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

Definition at line 99 of file compose.c.

◆ HeaderPadding

int HeaderPadding[HDR_ATTACH_TITLE] = { 0 }

Definition at line 158 of file compose.c.

◆ MaxHeaderWidth

int MaxHeaderWidth = 0

Definition at line 159 of file compose.c.

◆ Prompts

const char* const Prompts[]
static

Definition at line 164 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 207 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 223 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 236 of file compose.c.