NeoMutt  2019-12-07-60-g0cfa53
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 "gui/lib.h"
#include "mutt.h"
#include "compose.h"
#include "alias.h"
#include "browser.h"
#include "commands.h"
#include "context.h"
#include "edit.h"
#include "format_flags.h"
#include "globals.h"
#include "hook.h"
#include "index.h"
#include "keymap.h"
#include "main.h"
#include "mutt_attach.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_menu.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->state.cols - MaxHeaderWidth)
 
#define ALTS_TAG   "Alternatives for \"%s\""
 
#define LINGUAL_TAG   "Multilingual part for \"%s\""
 

Enumerations

enum  HeaderField {
  HDR_FROM = 0, HDR_TO, HDR_CC, HDR_BCC,
  HDR_SUBJECT, HDR_REPLYTO, HDR_FCC, HDR_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_dlg_compose_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the Compose menu - Implements observer_t() More...
 
int mutt_compose_menu (struct Email *e, struct Buffer *fcc, struct Email *e_cur, int flags)
 Allow the user to edit the message envelope. More...
 

Variables

char * C_ComposeFormat
 Config: printf-like format string for the Compose panel's status bar. More...
 
char * C_Ispell
 Config: External command to perform spell-checking. More...
 
unsigned char C_Postpone
 Config: Save messages to the C_Postponed folder. More...
 
static const char * There_are_no_attachments = N_("There are no attachments")
 
int HeaderPadding [HDR_ATTACH_TITLE] = { 0 }
 
int MaxHeaderWidth = 0
 
static const char *const Prompts []
 
static const struct Mapping ComposeHelp []
 
static struct Mapping ComposeNewsHelp []
 
static const char * AutocryptRecUiFlags []
 

Detailed Description

GUI editor for an email's headers.

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

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

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

Definition in file compose.c.

Macro Definition Documentation

◆ CHECK_COUNT

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

Definition at line 116 of file compose.c.

◆ CUR_ATTACH

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

Definition at line 123 of file compose.c.

◆ HDR_XOFFSET

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 159 of file compose.c.

◆ W

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

Definition at line 160 of file compose.c.

◆ ALTS_TAG

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

◆ LINGUAL_TAG

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

Enumeration Type Documentation

◆ HeaderField

Ordered list of headers for the compose screen.

The position of various fields on the compose screen.

Enumerator
HDR_FROM 

"From:" field

HDR_TO 

"To:" field

HDR_CC 

"Cc:" field

HDR_BCC 

"Bcc:" field

HDR_SUBJECT 

"Subject:" field

HDR_REPLYTO 

"Reply-To:" field

HDR_FCC 

"Fcc:" (save folder) field

HDR_CRYPT 

"Security:" field (encryption/signing info)

HDR_CRYPTINFO 

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

HDR_AUTOCRYPT 
HDR_NEWSGROUPS 

"Newsgroups:" field

HDR_FOLLOWUPTO 

"Followup-To:" field

HDR_XCOMMENTTO 

"X-Comment-To:" field

HDR_ATTACH_TITLE 

The "-- Attachments" line.

HDR_ATTACH 

Where to start printing the attachments.

Definition at line 130 of file compose.c.

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

Function Documentation

◆ compose_status_line()

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

Compose the string for the status bar.

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

Definition at line 1078 of file compose.c.

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

265 {
266  int width;
267 
268  HeaderPadding[idx] = mutt_str_strlen(header);
269  width = mutt_strwidth(header);
270  if (calc_max && (MaxHeaderWidth < width))
271  MaxHeaderWidth = width;
272  HeaderPadding[idx] -= width;
273 }
int MaxHeaderWidth
Definition: compose.c:157
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:1359
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_header_padding()

static void init_header_padding ( void  )
static

Calculate how much padding the compose table will need.

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

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

Definition at line 283 of file compose.c.

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

◆ snd_make_entry()

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

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

Definition at line 314 of file compose.c.

315 {
316  struct AttachCtx *actx = menu->data;
317 
318  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
320  (unsigned long) (actx->idx[actx->v2r[line]]),
322 }
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:877
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:99
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
const char * line
Definition: common.c:36
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
const char * attach_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:208
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
struct MuttWindow * win_index
Definition: mutt_menu.h:95
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ autocrypt_compose_menu()

static void autocrypt_compose_menu ( struct Email e)
static

Autocrypt compose settings.

Parameters
eEmail

Definition at line 329 of file compose.c.

330 {
331  /* L10N:
332  The compose menu autocrypt prompt.
333  (e)ncrypt enables encryption via autocrypt.
334  (c)lear sets cleartext.
335  (a)utomatic defers to the recommendation.
336  */
337  const char *prompt = _("Autocrypt: (e)ncrypt, (c)lear, (a)utomatic?");
338 
340 
341  /* L10N:
342  The letter corresponding to the compose menu autocrypt prompt
343  (e)ncrypt, (c)lear, (a)utomatic
344  */
345  const char *letters = _("eca");
346 
347  int choice = mutt_multi_choice(prompt, letters);
348  switch (choice)
349  {
350  case 1:
353  break;
354  case 2:
355  e->security &= ~SEC_AUTOCRYPT;
357  break;
358  case 3:
361  e->security |= SEC_OPPENCRYPT;
362  break;
363  }
364 }
#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:933
#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:269
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 371 of file compose.c.

372 {
373  struct Email *e = rd->email;
374 
377  _(Prompts[HDR_CRYPT]));
379 
381  {
382  mutt_window_addstr(_("Not supported"));
383  return;
384  }
385 
386  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
387  {
389  mutt_window_addstr(_("Sign, Encrypt"));
390  }
391  else if (e->security & SEC_ENCRYPT)
392  {
394  mutt_window_addstr(_("Encrypt"));
395  }
396  else if (e->security & SEC_SIGN)
397  {
399  mutt_window_addstr(_("Sign"));
400  }
401  else
402  {
403  /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
405  mutt_window_addstr(_("None"));
406  }
408 
409  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
410  {
411  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
412  {
413  if ((e->security & SEC_INLINE))
414  mutt_window_addstr(_(" (inline PGP)"));
415  else
416  mutt_window_addstr(_(" (PGP/MIME)"));
417  }
418  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
419  mutt_window_addstr(_(" (S/MIME)"));
420  }
421 
423  mutt_window_addstr(_(" (OppEnc mode)"));
424 
428 
429  if (((WithCrypto & APPLICATION_PGP) != 0) &&
430  (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
431  {
433  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
435  mutt_window_printf("%s", C_PgpSignAs ? C_PgpSignAs : _("<default>"));
436  }
437 
438  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
439  (e->security & APPLICATION_SMIME) && (e->security & SEC_SIGN))
440  {
442  mutt_window_printf("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
444  mutt_window_printf("%s", C_SmimeSignAs ? C_SmimeSignAs : _("<default>"));
445  }
446 
447  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
449  {
451  mutt_window_mvprintw(rd->win, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
454  }
455 
456 #ifdef USE_AUTOCRYPT
459  if (C_Autocrypt)
460  {
462  mutt_window_printf("%*s", HeaderPadding[HDR_AUTOCRYPT], _(Prompts[HDR_AUTOCRYPT]));
464  if (e->security & SEC_AUTOCRYPT)
465  {
467  mutt_window_addstr(_("Encrypt"));
468  }
469  else
470  {
472  mutt_window_addstr(_("Off"));
473  }
474 
476  mutt_window_mvprintw(rd->win, HDR_AUTOCRYPT, 40, "%s",
477  /* L10N:
478  The autocrypt compose menu Recommendation field.
479  Displays the output of the recommendation engine
480  (Off, No, Discouraged, Available, Yes)
481  */
482  _("Recommendation: "));
485  }
486 #endif
487 }
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:198
The envelope/body of an email.
Definition: email.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:135
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
struct Email * email
Definition: compose.c:107
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
"Sign as:" field (encryption/signing info)
Definition: compose.c:143
enum AutocryptRec autocrypt_rec
Definition: compose.c:110
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:269
Header labels, e.g. From:
Definition: color.h:66
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:165
Mail will be signed.
Definition: color.h:70
"Security:" field (encryption/signing info)
Definition: compose.c:142
static const char *const Prompts[]
Definition: compose.c:162
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/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:279
#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:456
struct MuttWindow * win
Definition: compose.c:113
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:312
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:428
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:160
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:164
static const char * AutocryptRecUiFlags[]
Definition: compose.c:234
#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 493 of file compose.c.

494 {
495  struct Email *e = rd->email;
496 
499 
500 #ifdef USE_AUTOCRYPT
501  if (C_Autocrypt)
502  {
504 
505  /* Anything that enables SEC_ENCRYPT or SEC_SIGN, or turns on SMIME
506  * overrides autocrypt, be it oppenc or the user having turned on
507  * those flags manually. */
510  else
511  {
512  if (!(e->security & SEC_AUTOCRYPT_OVERRIDE))
513  {
514  if (rd->autocrypt_rec == AUTOCRYPT_REC_YES)
515  {
518  }
519  else
520  e->security &= ~SEC_AUTOCRYPT;
521  }
522  }
523  }
524 #endif
525 
526  redraw_crypt_lines(rd);
527 }
#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:198
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:107
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
enum AutocryptRec autocrypt_rec
Definition: compose.c:110
#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:269
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:371
#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:1028
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 577 of file compose.c.

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

◆ draw_envelope_addr()

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

Write addresses to the compose window.

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

Definition at line 645 of file compose.c.

646 {
647  char buf[1024];
648 
649  buf[0] = '\0';
650  mutt_addrlist_write(al, buf, sizeof(buf), true);
652  mutt_window_mvprintw(rd->win, line, 0, "%*s", HeaderPadding[line], _(Prompts[line]));
654  mutt_paddstr(W, buf);
655 }
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
#define _(a)
Definition: message.h:28
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1266
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:162
#define W
Definition: compose.c:160
struct MuttWindow * win
Definition: compose.c:113
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:312
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_envelope()

static void draw_envelope ( struct ComposeRedrawData rd)
static

Write the email headers to the compose window.

Parameters
rdEmail and other compose data

Definition at line 661 of file compose.c.

662 {
663  struct Email *e = rd->email;
664  const char *fcc = mutt_b2s(rd->fcc);
665 
666  draw_envelope_addr(HDR_FROM, &e->env->from, rd);
667 #ifdef USE_NNTP
668  if (!OptNewsSend)
669  {
670 #endif
671  draw_envelope_addr(HDR_TO, &e->env->to, rd);
672  draw_envelope_addr(HDR_CC, &e->env->cc, rd);
673  draw_envelope_addr(HDR_BCC, &e->env->bcc, rd);
674 #ifdef USE_NNTP
675  }
676  else
677  {
678  mutt_window_mvprintw(rd->win, HDR_TO, 0, "%*s",
679  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
681  mutt_window_mvprintw(rd->win, HDR_CC, 0, "%*s",
682  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
684  if (C_XCommentTo)
685  {
686  mutt_window_mvprintw(rd->win, HDR_BCC, 0, "%*s",
687  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
689  }
690  }
691 #endif
692 
694  mutt_window_mvprintw(rd->win, HDR_SUBJECT, 0, "%*s",
695  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
698 
700 
703  _(Prompts[HDR_FCC]));
705  mutt_paddstr(W, fcc);
706 
707  if (WithCrypto)
708  redraw_crypt_lines(rd);
709 
710 #ifdef MIXMASTER
711  redraw_mix_line(&e->chain, rd);
712 #endif
713 
715  mutt_window_mvaddstr(rd->win, HDR_ATTACH_TITLE, 0, _("-- Attachments"));
717 
719 }
#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:55
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:135
"To:" field
Definition: compose.c:133
"Cc:" field
Definition: compose.c:134
#define _(a)
Definition: message.h:28
struct Email * email
Definition: compose.c:107
struct Buffer * fcc
Definition: compose.c:108
"Subject:" field
Definition: compose.c:136
"From:" field
Definition: compose.c:132
The "-- Attachments" line.
Definition: compose.c:152
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1266
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
"X-Comment-To:" field
Definition: compose.c:150
Plain text.
Definition: color.h:78
#define mutt_b2s(buf)
Definition: buffer.h:41
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
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:645
static const char *const Prompts[]
Definition: compose.c:162
#define W
Definition: compose.c:160
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:293
static void redraw_crypt_lines(struct ComposeRedrawData *rd)
Update the encryption info in the compose window.
Definition: compose.c:371
"Bcc:" field
Definition: compose.c:135
"Followup-To:" field
Definition: compose.c:149
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct MuttWindow * win
Definition: compose.c:113
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:283
int HeaderPadding[HDR_ATTACH_TITLE]
Definition: compose.c:156
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:312
"Newsgroups:" field
Definition: compose.c:148
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
"Fcc:" (save folder) field
Definition: compose.c:138
#define WithCrypto
Definition: ncrypt.h:160
"Reply-To:" field
Definition: compose.c:137
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ edit_address_list()

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

Let the user edit the address list.

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

Definition at line 727 of file compose.c.

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

◆ delete_attachment()

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

Delete an attachment.

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

Definition at line 762 of file compose.c.

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

820 {
821  for (; m; m = m->next)
822  {
823  if ((m->type == TYPE_MULTIPART) && m->parts &&
825  {
827  }
828  else
829  {
830  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
831  mutt_actx_add_attach(actx, ap);
832  ap->content = m;
833  m->aptr = ap;
834  ap->parent_type = parent_type;
835  ap->level = level;
836 
837  /* We don't support multipart messages in the compose menu yet */
838  }
839  }
840 }
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:818
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:451
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 848 of file compose.c.

849 {
850  if (init)
851  {
852  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
853  mutt_attach_init(actx);
854  menu->data = actx;
855  }
856 
857  mutt_update_tree(actx);
858 
859  menu->max = actx->vcount;
860  if (menu->max)
861  {
862  if (menu->current >= menu->max)
863  menu->current = menu->max - 1;
864  }
865  else
866  menu->current = 0;
867 
868  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
869 }
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:818
#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:1326
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:142
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int current
Current entry.
Definition: mutt_menu.h:87
short vcount
The number of virtual attachments.
Definition: attach.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_idx()

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

Add a new attchment to the message.

Parameters
menuCurrent menu
actxAttachment context
apAttachment to add

Definition at line 877 of file compose.c.

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

892 {
893  struct ComposeRedrawData *rd = menu->redraw_data;
894 
895  if (!rd)
896  return;
897 
898  if (menu->redraw & REDRAW_FULL)
899  {
900  menu_redraw_full(menu);
901 
902  draw_envelope(rd);
903  menu->offset = HDR_ATTACH;
904  menu->pagelen = menu->win_index->state.rows - HDR_ATTACH;
905  }
906 
907  menu_check_recenter(menu);
908 
909  if (menu->redraw & REDRAW_STATUS)
910  {
911  char buf[1024];
912  compose_status_line(buf, sizeof(buf), 0, menu->win_ibar->state.cols, menu,
914  mutt_window_move(menu->win_ibar, 0, 0);
916  mutt_draw_statusline(menu->win_ibar->state.cols, buf, sizeof(buf));
918  menu->redraw &= ~REDRAW_STATUS;
919  }
920 
921 #ifdef USE_SIDEBAR
922  if (menu->redraw & REDRAW_SIDEBAR)
923  menu_redraw_sidebar(menu);
924 #endif
925 
926  if (menu->redraw & REDRAW_INDEX)
927  menu_redraw_index(menu);
928  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNC))
929  menu_redraw_motion(menu);
930  else if (menu->redraw == REDRAW_CURRENT)
931  menu_redraw_current(menu);
932 }
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
#define NONULL(x)
Definition: string2.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
void * redraw_data
Definition: mutt_menu.h:150
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
static void draw_envelope(struct ComposeRedrawData *rd)
Write the email headers to the compose window.
Definition: compose.c:661
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:1078
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:43
Plain text.
Definition: color.h:78
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
Status bar (takes a pattern)
Definition: color.h:95
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:55
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:279
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
int offset
Row offset within the window to start the index.
Definition: mutt_menu.h:91
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
Where to start printing the attachments.
Definition: compose.c:153
char * C_ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:93
struct MuttWindow * win_index
Definition: mutt_menu.h:95
Keep track when the compose screen needs redrawing.
Definition: compose.c:105
void mutt_draw_statusline(int cols, const char *buf, size_t buflen)
Draw a highlighted status bar.
Definition: index.c:927
#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 940 of file compose.c.

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

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

1024 {
1025  char fmt[128], tmp[128];
1026  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
1027  struct Menu *menu = (struct Menu *) data;
1028 
1029  *buf = '\0';
1030  switch (op)
1031  {
1032  case 'a': /* total number of attachments */
1033  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1034  snprintf(buf, buflen, fmt, menu->max);
1035  break;
1036 
1037  case 'h': /* hostname */
1038  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1039  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
1040  break;
1041 
1042  case 'l': /* approx length of current message in bytes */
1043  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1044  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
1045  snprintf(buf, buflen, fmt, tmp);
1046  break;
1047 
1048  case 'v':
1049  snprintf(buf, buflen, "%s", mutt_make_version());
1050  break;
1051 
1052  case 0:
1053  *buf = '\0';
1054  return src;
1055 
1056  default:
1057  snprintf(buf, buflen, "%%%s%c", prec, op);
1058  break;
1059  }
1060 
1061  if (optional)
1062  compose_status_line(buf, buflen, col, cols, menu, if_str);
1063  else if (flags & MUTT_FORMAT_OPTIONAL)
1064  compose_status_line(buf, buflen, col, cols, menu, else_str);
1065 
1066  return src;
1067 }
#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:1078
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1778
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:974
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:50
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1559
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlg_compose_observer()

int mutt_dlg_compose_observer ( struct NotifyCallback nc)

Listen for config changes affecting the Compose menu - Implements observer_t()

Definition at line 1088 of file compose.c.

1089 {
1090  if (!nc->event_data || !nc->global_data)
1091  return -1;
1092  if (nc->event_type != NT_CONFIG)
1093  return 0;
1094 
1095  struct EventConfig *ec = nc->event_data;
1096  struct MuttWindow *dlg = nc->global_data;
1097 
1098  if (mutt_str_strcmp(ec->name, "status_on_top") != 0)
1099  return 0;
1100 
1101  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
1102 
1103  if ((C_StatusOnTop && (win_first->type == WT_INDEX)) ||
1104  (!C_StatusOnTop && (win_first->type != WT_INDEX)))
1105  {
1106  // Swap the Index and the IndexBar Windows
1107  TAILQ_REMOVE(&dlg->children, win_first, entries);
1108  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
1109  }
1110 
1111  mutt_window_reflow(dlg);
1112  return 0;
1113 }
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:255
#define TAILQ_FIRST(head)
Definition: queue.h:716
A config-change event.
Definition: subset.h:68
A division of the screen.
Definition: mutt_window.h:86
An Index Window containing a selection list.
Definition: mutt_window.h:72
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed.
Definition: notify_type.h:34
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:346
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:99
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:101
const char * name
Name of config item that changed.
Definition: subset.h:71
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ 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 1125 of file compose.c.

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

Variable Documentation

◆ C_ComposeFormat

char* C_ComposeFormat

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

Definition at line 93 of file compose.c.

◆ C_Ispell

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 94 of file compose.c.

◆ C_Postpone

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 95 of file compose.c.

◆ There_are_no_attachments

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

Definition at line 97 of file compose.c.

◆ HeaderPadding

int HeaderPadding[HDR_ATTACH_TITLE] = { 0 }

Definition at line 156 of file compose.c.

◆ MaxHeaderWidth

int MaxHeaderWidth = 0

Definition at line 157 of file compose.c.

◆ Prompts

const char* const Prompts[]
static

Definition at line 162 of file compose.c.

◆ ComposeHelp

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

Definition at line 205 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 221 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 234 of file compose.c.