NeoMutt  2018-07-16 +2225-8687db
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 "conn/conn.h"
#include "mutt.h"
#include "compose.h"
#include "alias.h"
#include "browser.h"
#include "commands.h"
#include "context.h"
#include "core/lib.h"
#include "curs_lib.h"
#include "edit.h"
#include "format_flags.h"
#include "globals.h"
#include "hook.h"
#include "index.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_curses.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "recvattach.h"
#include "sendlib.h"
#include "sort.h"
#include <libintl.h>
#include "nntp/nntp.h"
#include "pop/pop.h"
#include "imap/imap.h"

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

static void calc_header_width_padding (int idx, const char *header, bool calc_max)
 Calculate the width needed for the compose labels. More...
 
static void init_header_padding (void)
 Calculate how much padding the compose table will need. More...
 
static void snd_make_entry (char *buf, size_t buflen, struct Menu *menu, int line)
 Format a menu item for the attachment list - Implements Menu::menu_make_entry() More...
 
static void redraw_crypt_lines (struct Email *e)
 Update the encryption info in the compose window. More...
 
static int check_attachments (struct AttachCtx *actx)
 Check if any attachments have changed or been deleted. More...
 
static void draw_envelope_addr (int line, struct AddressList *al)
 Write addresses to the compose window. More...
 
static void draw_envelope (struct Email *e, char *fcc)
 Write the email headers to the compose window. More...
 
static void edit_address_list (int line, struct AddressList *al)
 Let the user edit the address list. More...
 
static int delete_attachment (struct AttachCtx *actx, int x)
 Delete an attachment. More...
 
static void mutt_gen_compose_attach_list (struct AttachCtx *actx, struct Body *m, int parent_type, int level)
 Generate the attachment list for the compose screen. More...
 
static void mutt_update_compose_menu (struct AttachCtx *actx, struct Menu *menu, bool init)
 Redraw the compose window. More...
 
static void update_idx (struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
 Add a new attchment to the message. More...
 
static void compose_status_line (char *buf, size_t buflen, size_t col, int cols, struct Menu *menu, const char *src)
 Compose the string for the status bar. More...
 
static void compose_custom_redraw (struct Menu *menu)
 Redraw the compose menu - Implements Menu::menu_custom_redraw() More...
 
static void compose_attach_swap (struct Body *msg, struct AttachPtr **idx, short first)
 Swap two adjacent entries in the attachment list. More...
 
static unsigned long cum_attachs_size (struct Menu *menu)
 Cumulative Attachments Size. More...
 
static const char * compose_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
 Create the status bar string for compose mode - Implements format_t. More...
 
int mutt_compose_menu (struct Email *e, char *fcc, size_t fcclen, struct Email *e_cur, int flags)
 Allow the user to edit the message envelope. More...
 

Variables

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

Detailed Description

GUI editor for an email's headers.

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

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

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

Definition in file compose.c.

Macro Definition Documentation

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

Definition at line 96 of file compose.c.

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

Definition at line 103 of file compose.c.

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 135 of file compose.c.

#define W   (MuttIndexWindow->cols - MaxHeaderWidth)

Definition at line 136 of file compose.c.

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

Enumeration Type Documentation

Ordered list of headers for the compose screen.

The position of various fields on the compose screen.

Enumerator
HDR_FROM 

"From:" field

HDR_TO 

"To:" field

HDR_CC 

"Cc:" field

HDR_BCC 

"Bcc:" field

HDR_SUBJECT 

"Subject:" field

HDR_REPLYTO 

"Reply-To:" field

HDR_FCC 

"Fcc:" (save folder) field

HDR_CRYPT 

"Security:" field (encryption/signing info)

HDR_CRYPTINFO 

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

HDR_NEWSGROUPS 

"Newsgroups:" field

HDR_FOLLOWUPTO 

"Followup-To:" field

HDR_XCOMMENTTO 

"X-Comment-To:" field

HDR_ATTACH 

Position to start printing the attachments.

Definition at line 110 of file compose.c.

111 {
112  HDR_FROM = 0,
113  HDR_TO,
114  HDR_CC,
115  HDR_BCC,
116  HDR_SUBJECT,
117  HDR_REPLYTO,
118  HDR_FCC,
119 #ifdef MIXMASTER
120  HDR_MIX,
121 #endif
122  HDR_CRYPT,
123  HDR_CRYPTINFO,
124 #ifdef USE_NNTP
128 #endif
129  HDR_ATTACH = (HDR_FCC + 5),
130 };
"To:" field
Definition: compose.c:113
"Cc:" field
Definition: compose.c:114
"Subject:" field
Definition: compose.c:116
"Sign as:" field (encryption/signing info)
Definition: compose.c:123
"From:" field
Definition: compose.c:112
"X-Comment-To:" field
Definition: compose.c:127
"Security:" field (encryption/signing info)
Definition: compose.c:122
"Bcc:" field
Definition: compose.c:115
"Followup-To:" field
Definition: compose.c:126
Position to start printing the attachments.
Definition: compose.c:129
"Newsgroups:" field
Definition: compose.c:125
"Fcc:" (save folder) field
Definition: compose.c:118
"Reply-To:" field
Definition: compose.c:117

Function Documentation

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

Calculate the width needed for the compose labels.

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

Definition at line 211 of file compose.c.

212 {
213  int width;
214 
215  HeaderPadding[idx] = mutt_str_strlen(header);
216  width = mutt_strwidth(header);
217  if (calc_max && (MaxHeaderWidth < width))
218  MaxHeaderWidth = width;
219  HeaderPadding[idx] -= width;
220 }
int MaxHeaderWidth
Definition: compose.c:133
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:1254
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:132
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 230 of file compose.c.

231 {
232  static bool done = false;
233 
234  if (done)
235  return;
236  done = true;
237 
238  for (int i = 0; i <= HDR_XCOMMENTTO; i++)
239  calc_header_width_padding(i, _(Prompts[i]), true);
240 
241  /* Don't include "Sign as: " in the MaxHeaderWidth calculation. It
242  * doesn't show up by default, and so can make the indentation of
243  * the other fields look funny. */
245 
246  for (int i = 0; i <= HDR_XCOMMENTTO; i++)
247  {
249  if (HeaderPadding[i] < 0)
250  HeaderPadding[i] = 0;
251  }
252 }
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:211
int MaxHeaderWidth
Definition: compose.c:133
#define _(a)
Definition: message.h:28
"Sign as:" field (encryption/signing info)
Definition: compose.c:123
"X-Comment-To:" field
Definition: compose.c:127
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:132
static const char *const Prompts[]
Definition: compose.c:138
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 257 of file compose.c.

258 {
259  struct AttachCtx *actx = menu->data;
260 
262  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
264 }
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:841
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:98
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
const char * line
Definition: common.c:36
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
const char * attach_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:210
void * data
extra data for the current menu
Definition: mutt_menu.h:86
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
static void redraw_crypt_lines ( struct Email e)
static

Update the encryption info in the compose window.

Parameters
eEmail

Definition at line 270 of file compose.c.

271 {
274  HeaderPadding[HDR_CRYPT], _(Prompts[HDR_CRYPT]));
275  NORMAL_COLOR;
276 
278  {
279  addstr(_("Not supported"));
280  return;
281  }
282 
283  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)) == (SEC_ENCRYPT | SEC_SIGN))
284  {
286  addstr(_("Sign, Encrypt"));
287  }
288  else if (e->security & SEC_ENCRYPT)
289  {
291  addstr(_("Encrypt"));
292  }
293  else if (e->security & SEC_SIGN)
294  {
296  addstr(_("Sign"));
297  }
298  else
299  {
300  /* L10N: This refers to the encryption of the email, e.g. "Security: None" */
302  addstr(_("None"));
303  }
304  NORMAL_COLOR;
305 
306  if ((e->security & (SEC_ENCRYPT | SEC_SIGN)))
307  {
308  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
309  {
310  if ((e->security & SEC_INLINE))
311  addstr(_(" (inline PGP)"));
312  else
313  addstr(_(" (PGP/MIME)"));
314  }
315  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
316  addstr(_(" (S/MIME)"));
317  }
318 
320  addstr(_(" (OppEnc mode)"));
321 
325 
326  if (((WithCrypto & APPLICATION_PGP) != 0) &&
327  (e->security & APPLICATION_PGP) && (e->security & SEC_SIGN))
328  {
330  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
331  NORMAL_COLOR;
332  printw("%s", C_PgpSignAs ? C_PgpSignAs : _("<default>"));
333  }
334 
335  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
336  (e->security & APPLICATION_SMIME) && (e->security & SEC_SIGN))
337  {
339  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
340  NORMAL_COLOR;
341  printw("%s", C_SmimeSignAs ? C_SmimeSignAs : _("<default>"));
342  }
343 
344  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME) &&
346  {
348  mutt_window_mvprintw(MuttIndexWindow, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
349  NORMAL_COLOR;
350  printw("%s", NONULL(C_SmimeEncryptWith));
351  }
352 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#define NONULL(x)
Definition: string2.h:37
Mail will not be encrypted or signed.
Definition: mutt_curses.h:172
#define NORMAL_COLOR
Definition: mutt_curses.h:239
Mail will be encrypted.
Definition: mutt_curses.h:169
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:128
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:121
"Sign as:" field (encryption/signing info)
Definition: compose.c:123
Mail will be signed.
Definition: mutt_curses.h:170
Mail will be encrypted and signed.
Definition: mutt_curses.h:171
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:122
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:267
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:168
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:132
"Security:" field (encryption/signing info)
Definition: compose.c:122
static const char *const Prompts[]
Definition: compose.c:138
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
#define SET_COLOR(X)
Definition: mutt_curses.h:224
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:129
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:130
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:220
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:163
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:167
#define WithCrypto
Definition: ncrypt.h:156
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:131
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 401 of file compose.c.

402 {
403  struct stat st;
404  char pretty[PATH_MAX], msg[PATH_MAX + 128];
405 
406  for (int i = 0; i < actx->idxlen; i++)
407  {
408  if (actx->idx[i]->content->type == TYPE_MULTIPART)
409  continue;
410  mutt_str_strfcpy(pretty, actx->idx[i]->content->filename, sizeof(pretty));
411  if (stat(actx->idx[i]->content->filename, &st) != 0)
412  {
413  mutt_pretty_mailbox(pretty, sizeof(pretty));
414  mutt_error(_("%s [#%d] no longer exists"), pretty, i + 1);
415  return -1;
416  }
417 
418  if (actx->idx[i]->content->stamp < st.st_mtime)
419  {
420  mutt_pretty_mailbox(pretty, sizeof(pretty));
421  snprintf(msg, sizeof(msg), _("%s [#%d] modified. Update encoding?"), pretty, i + 1);
422 
423  enum QuadOption ans = mutt_yesorno(msg, MUTT_YES);
424  if (ans == MUTT_YES)
425  mutt_update_encoding(actx->idx[i]->content);
426  else if (ans == MUTT_ABORT)
427  return -1;
428  }
429  }
430 
431  return 0;
432 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
User aborted the question (with Ctrl-G)
Definition: quad.h:37
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1446
#define PATH_MAX
Definition: mutt.h:50
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:615
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
time_t stamp
Time stamp of last encoding update.
Definition: body.h:61
#define mutt_error(...)
Definition: logging.h:84
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
static void draw_envelope_addr ( int  line,
struct AddressList *  al 
)
static

Write addresses to the compose window.

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

Definition at line 439 of file compose.c.

440 {
441  char buf[1024];
442 
443  buf[0] = '\0';
444  mutt_addrlist_write(buf, sizeof(buf), al, true);
447  _(Prompts[line]));
448  NORMAL_COLOR;
449  mutt_paddstr(W, buf);
450 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#define NORMAL_COLOR
Definition: mutt_curses.h:239
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1161
const char * line
Definition: common.c:36
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:132
static const char *const Prompts[]
Definition: compose.c:138
#define W
Definition: compose.c:136
#define SET_COLOR(X)
Definition: mutt_curses.h:224
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:220
static void draw_envelope ( struct Email e,
char *  fcc 
)
static

Write the email headers to the compose window.

Parameters
eEmail
fccFcc field

Definition at line 457 of file compose.c.

458 {
460 #ifdef USE_NNTP
461  if (!OptNewsSend)
462  {
463 #endif
467 #ifdef USE_NNTP
468  }
469  else
470  {
472  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
475  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
477  if (C_XCommentTo)
478  {
480  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
482  }
483  }
484 #endif
485 
488  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
489  NORMAL_COLOR;
491 
493 
496  HeaderPadding[HDR_FCC], _(Prompts[HDR_FCC]));
497  NORMAL_COLOR;
498  mutt_paddstr(W, fcc);
499 
500  if (WithCrypto)
502 
503 #ifdef MIXMASTER
504  redraw_mix_line(&e->chain);
505 #endif
506 
508  mutt_window_mvaddstr(MuttIndexWindow, HDR_ATTACH - 1, 0, _("-- Attachments"));
510 
511  NORMAL_COLOR;
512 }
Header labels, e.g. From:
Definition: mutt_curses.h:168
#define NONULL(x)
Definition: string2.h:37
static void redraw_crypt_lines(struct Email *e)
Update the encryption info in the compose window.
Definition: compose.c:270
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:48
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:46
#define NORMAL_COLOR
Definition: mutt_curses.h:239
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
"To:" field
Definition: compose.c:113
"Cc:" field
Definition: compose.c:114
#define _(a)
Definition: message.h:28
"Subject:" field
Definition: compose.c:116
"From:" field
Definition: compose.c:112
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1161
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:43
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:45
"X-Comment-To:" field
Definition: compose.c:127
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:64
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
static void draw_envelope_addr(int line, struct AddressList *al)
Write addresses to the compose window.
Definition: compose.c:439
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:132
static const char *const Prompts[]
Definition: compose.c:138
#define SET_COLOR(X)
Definition: mutt_curses.h:224
#define W
Definition: compose.c:136
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:190
"Bcc:" field
Definition: compose.c:115
"Followup-To:" field
Definition: compose.c:126
char * subject
Email&#39;s subject.
Definition: envelope.h:52
char * newsgroups
List of newsgroups.
Definition: envelope.h:61
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:281
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:63
Status bar.
Definition: mutt_curses.h:129
Position to start printing the attachments.
Definition: compose.c:129
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:44
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:220
"Newsgroups:" field
Definition: compose.c:125
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
"Fcc:" (save folder) field
Definition: compose.c:118
#define WithCrypto
Definition: ncrypt.h:156
"Reply-To:" field
Definition: compose.c:117
static void edit_address_list ( int  line,
struct AddressList *  al 
)
static

Let the user edit the address list.

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

Definition at line 519 of file compose.c.

520 {
521  char buf[8192] = { 0 }; /* needs to be large for alias expansion */
522  char *err = NULL;
523 
525  mutt_addrlist_write(buf, sizeof(buf), al, false);
526  if (mutt_get_field(_(Prompts[line]), buf, sizeof(buf), MUTT_ALIAS) == 0)
527  {
529  mutt_addrlist_parse2(al, buf);
531  }
532 
533  if (mutt_addrlist_to_intl(al, &err) != 0)
534  {
535  mutt_error(_("Bad IDN: '%s'"), err);
536  mutt_refresh();
537  FREE(&err);
538  }
539 
540  /* redraw the expanded list so the user can see the result */
541  buf[0] = '\0';
542  mutt_addrlist_write(buf, sizeof(buf), al, true);
544  mutt_paddstr(W, buf);
545 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:290
#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:1268
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1351
#define _(a)
Definition: message.h:28
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:603
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1161
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:99
const char * line
Definition: common.c:36
#define HDR_XOFFSET
Definition: compose.c:135
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
static const char *const Prompts[]
Definition: compose.c:138
#define W
Definition: compose.c:136
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1186
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
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 554 of file compose.c.

555 {
556  struct AttachPtr **idx = actx->idx;
557  int rindex = actx->v2r[x];
558 
559  if ((rindex == 0) && (actx->idxlen == 1))
560  {
561  mutt_error(_("You may not delete the only attachment"));
562  idx[rindex]->content->tagged = false;
563  return -1;
564  }
565 
566  for (int y = 0; y < actx->idxlen; y++)
567  {
568  if (idx[y]->content->next == idx[rindex]->content)
569  {
570  idx[y]->content->next = idx[rindex]->content->next;
571  break;
572  }
573  }
574 
575  idx[rindex]->content->next = NULL;
576  idx[rindex]->content->parts = NULL;
577  mutt_body_free(&(idx[rindex]->content));
578  FREE(&idx[rindex]->tree);
579  FREE(&idx[rindex]);
580  for (; rindex < actx->idxlen - 1; rindex++)
581  idx[rindex] = idx[rindex + 1];
582  idx[actx->idxlen - 1] = NULL;
583  actx->idxlen--;
584 
585  return 0;
586 }
An email to which things will be attached.
Definition: attach.h:34
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
short idxlen
Number of attachmentes.
Definition: attach.h:55
char * tree
Tree characters to display.
Definition: attach.h:39
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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 595 of file compose.c.

597 {
598  for (; m; m = m->next)
599  {
600  if ((m->type == TYPE_MULTIPART) && m->parts &&
602  {
604  }
605  else
606  {
607  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
608  mutt_actx_add_attach(actx, ap);
609  ap->content = m;
610  m->aptr = ap;
611  ap->parent_type = parent_type;
612  ap->level = level;
613 
614  /* We don't support multipart messages in the compose menu yet */
615  }
616  }
617 }
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:595
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:420
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:130
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define WithCrypto
Definition: ncrypt.h:156
int level
Nesting depth of attachment.
Definition: attach.h:40
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 625 of file compose.c.

626 {
627  if (init)
628  {
629  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
630  mutt_attach_init(actx);
631  menu->data = actx;
632  }
633 
634  mutt_update_tree(actx);
635 
636  menu->max = actx->vcount;
637  if (menu->max)
638  {
639  if (menu->current >= menu->max)
640  menu->current = menu->max - 1;
641  }
642  else
643  menu->current = 0;
644 
645  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
646 }
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:595
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1321
int max
the number of entries in the menu
Definition: mutt_menu.h:88
MuttRedrawFlags redraw
when to redraw the screen
Definition: mutt_menu.h:89
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:144
void * data
extra data for the current menu
Definition: mutt_menu.h:86
int current
current entry
Definition: mutt_menu.h:87
short vcount
The number of virtual attachments.
Definition: attach.h:59
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 654 of file compose.c.

655 {
656  ap->level = (actx->idxlen > 0) ? actx->idx[actx->idxlen - 1]->level : 0;
657  if (actx->idxlen)
658  actx->idx[actx->idxlen - 1]->content->next = ap->content;
659  ap->content->aptr = ap;
660  mutt_actx_add_attach(actx, ap);
661  mutt_update_compose_menu(actx, menu, false);
662  menu->current = actx->vcount - 1;
663 }
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:625
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
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 867 of file compose.c.

869 {
870  mutt_expando_format(buf, buflen, col, cols, src, compose_format_str,
871  (unsigned long) menu, MUTT_FORMAT_NO_FLAGS);
872 }
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:841
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:809
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
static void compose_custom_redraw ( struct Menu menu)
static

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

Definition at line 680 of file compose.c.

681 {
682  struct ComposeRedrawData *rd = menu->redraw_data;
683 
684  if (!rd)
685  return;
686 
687  if (menu->redraw & REDRAW_FULL)
688  {
689  menu_redraw_full(menu);
690 
691  draw_envelope(rd->email, rd->fcc);
692  menu->offset = HDR_ATTACH;
694  }
695 
696  menu_check_recenter(menu);
697 
698  if (menu->redraw & REDRAW_STATUS)
699  {
700  char buf[1024];
701  compose_status_line(buf, sizeof(buf), 0, MuttStatusWindow->cols, menu,
706  NORMAL_COLOR;
707  menu->redraw &= ~REDRAW_STATUS;
708  }
709 
710 #ifdef USE_SIDEBAR
711  if (menu->redraw & REDRAW_SIDEBAR)
712  menu_redraw_sidebar(menu);
713 #endif
714 
715  if (menu->redraw & REDRAW_INDEX)
716  menu_redraw_index(menu);
717  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNC))
718  menu_redraw_motion(menu);
719  else if (menu->redraw == REDRAW_CURRENT)
720  menu_redraw_current(menu);
721 }
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
#define NONULL(x)
Definition: string2.h:37
struct MuttWindow * MuttStatusWindow
Status Window.
Definition: mutt_window.c:40
#define NORMAL_COLOR
Definition: mutt_curses.h:239
struct Email * email
Definition: compose.c:670
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1161
void * redraw_data
Definition: mutt_menu.h:152
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:867
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:43
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int pagelen
number of entries per screen
Definition: mutt_menu.h:92
#define SET_COLOR(X)
Definition: mutt_curses.h:224
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
MuttRedrawFlags redraw
when to redraw the screen
Definition: mutt_menu.h:89
static void draw_envelope(struct Email *e, char *fcc)
Write the email headers to the compose window.
Definition: compose.c:457
int offset
row offset within the window to start the index
Definition: mutt_menu.h:91
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
Status bar.
Definition: mutt_curses.h:129
Position to start printing the attachments.
Definition: compose.c:129
char * C_ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:90
Keep track when the compose screen needs redrawing.
Definition: compose.c:668
#define REDRAW_CURRENT
Redraw the current line of the menu.
Definition: mutt_menu.h:45
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 729 of file compose.c.

730 {
731  /* Reorder Body pointers.
732  * Must traverse msg from top since Body has no previous ptr. */
733  for (struct Body *part = msg; part; part = part->next)
734  {
735  if (part->next == idx[first]->content)
736  {
737  idx[first]->content->next = idx[first + 1]->content->next;
738  idx[first + 1]->content->next = idx[first]->content;
739  part->next = idx[first + 1]->content;
740  break;
741  }
742  }
743 
744  /* Reorder index */
745  struct AttachPtr *saved = idx[first];
746  idx[first] = idx[first + 1];
747  idx[first + 1] = saved;
748 
749  /* Swap ptr->num */
750  int i = idx[first]->num;
751  idx[first]->num = idx[first + 1]->num;
752  idx[first + 1]->num = i;
753 }
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
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 763 of file compose.c.

764 {
765  size_t s = 0;
766  struct AttachCtx *actx = menu->data;
767  struct AttachPtr **idx = actx->idx;
768  struct Content *info = NULL;
769  struct Body *b = NULL;
770 
771  for (unsigned short i = 0; i < actx->idxlen; i++)
772  {
773  b = idx[i]->content;
774 
775  if (!b->content)
777 
778  info = b->content;
779  if (info)
780  {
781  switch (b->encoding)
782  {
784  s += 3 * (info->lobin + info->hibin) + info->ascii + info->crlf;
785  break;
786  case ENC_BASE64:
787  s += (4 * (info->lobin + info->hibin + info->ascii + info->crlf)) / 3;
788  break;
789  default:
790  s += info->lobin + info->hibin + info->ascii + info->crlf;
791  break;
792  }
793  }
794  }
795 
796  return s;
797 }
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:1003
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
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 809 of file compose.c.

813 {
814  char fmt[128], tmp[128];
815  int optional = (flags & MUTT_FORMAT_OPTIONAL);
816  struct Menu *menu = (struct Menu *) data;
817 
818  *buf = '\0';
819  switch (op)
820  {
821  case 'a': /* total number of attachments */
822  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
823  snprintf(buf, buflen, fmt, menu->max);
824  break;
825 
826  case 'h': /* hostname */
827  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
828  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
829  break;
830 
831  case 'l': /* approx length of current message in bytes */
832  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
833  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
834  snprintf(buf, buflen, fmt, tmp);
835  break;
836 
837  case 'v':
838  snprintf(buf, buflen, "%s", mutt_make_version());
839  break;
840 
841  case 0:
842  *buf = '\0';
843  return src;
844 
845  default:
846  snprintf(buf, buflen, "%%%s%c", prec, op);
847  break;
848  }
849 
850  if (optional)
851  compose_status_line(buf, buflen, col, cols, menu, if_str);
852  else if (flags & MUTT_FORMAT_OPTIONAL)
853  compose_status_line(buf, buflen, col, cols, menu, else_str);
854 
855  return src;
856 }
#define NONULL(x)
Definition: string2.h:37
GUI selectable list of items.
Definition: mutt_menu.h:82
int menu
menu definition for keymap entries.
Definition: mutt_menu.h:90
static void compose_status_line(char *buf, size_t buflen, size_t col, int cols, struct Menu *menu, const char *p)
Compose the string for the status bar.
Definition: compose.c:867
int max
the number of entries in the menu
Definition: mutt_menu.h:88
static unsigned long cum_attachs_size(struct Menu *menu)
Cumulative Attachments Size.
Definition: compose.c:763
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:49
void * data
extra data for the current menu
Definition: mutt_menu.h:86
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1047
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1519
int mutt_compose_menu ( struct Email e,
char *  fcc,
size_t  fcclen,
struct Email e_cur,
int  flags 
)

Allow the user to edit the message envelope.

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

Definition at line 885 of file compose.c.

886 {
887  char helpstr[1024]; // This isn't copied by the help bar
888  char buf[PATH_MAX];
889  int op_close = OP_NULL;
890  int rc = -1;
891  bool loop = true;
892  bool fcc_set = false; /* has the user edited the Fcc: field ? */
893  struct ComposeRedrawData rd;
894 #ifdef USE_NNTP
895  bool news = OptNewsSend; /* is it a news article ? */
896 #endif
897 
899 
900  rd.email = e;
901  rd.fcc = fcc;
902 
903  struct Menu *menu = mutt_menu_new(MENU_COMPOSE);
904  menu->offset = HDR_ATTACH;
906  menu->menu_tag = attach_tag;
907 #ifdef USE_NNTP
908  if (news)
909  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeNewsHelp);
910  else
911 #endif
912  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_COMPOSE, ComposeHelp);
914  menu->redraw_data = &rd;
916 
917  struct AttachCtx *actx = mutt_mem_calloc(sizeof(struct AttachCtx), 1);
918  actx->email = e;
919  mutt_update_compose_menu(actx, menu, true);
920 
921  while (loop)
922  {
923 #ifdef USE_NNTP
924  OptNews = false; /* for any case */
925 #endif
926  const int op = mutt_menu_loop(menu);
927  switch (op)
928  {
929  case OP_COMPOSE_EDIT_FROM:
932  break;
933 
934  case OP_COMPOSE_EDIT_TO:
935 #ifdef USE_NNTP
936  if (news)
937  break;
938 #endif
941  {
944  }
946  break;
947 
948  case OP_COMPOSE_EDIT_BCC:
949 #ifdef USE_NNTP
950  if (news)
951  break;
952 #endif
955  {
958  }
960  break;
961 
962  case OP_COMPOSE_EDIT_CC:
963 #ifdef USE_NNTP
964  if (news)
965  break;
966 #endif
969  {
972  }
974  break;
975 #ifdef USE_NNTP
976  case OP_COMPOSE_EDIT_NEWSGROUPS:
977  if (!news)
978  break;
979  if (e->env->newsgroups)
980  mutt_str_strfcpy(buf, e->env->newsgroups, sizeof(buf));
981  else
982  buf[0] = '\0';
983  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) == 0)
984  {
985  mutt_str_replace(&e->env->newsgroups, buf);
987  if (e->env->newsgroups)
989  else
990  clrtoeol();
991  }
992  break;
993 
994  case OP_COMPOSE_EDIT_FOLLOWUP_TO:
995  if (!news)
996  break;
997  if (e->env->followup_to)
998  mutt_str_strfcpy(buf, e->env->followup_to, sizeof(buf));
999  else
1000  buf[0] = '\0';
1001  if (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) == 0)
1002  {
1003  mutt_str_replace(&e->env->followup_to, buf);
1005  if (e->env->followup_to)
1006  mutt_paddstr(W, e->env->followup_to);
1007  else
1008  clrtoeol();
1009  }
1010  break;
1011 
1012  case OP_COMPOSE_EDIT_X_COMMENT_TO:
1013  if (!(news && C_XCommentTo))
1014  break;
1015  if (e->env->x_comment_to)
1016  mutt_str_strfcpy(buf, e->env->x_comment_to, sizeof(buf));
1017  else
1018  buf[0] = '\0';
1019  if (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) == 0)
1020  {
1021  mutt_str_replace(&e->env->x_comment_to, buf);
1023  if (e->env->x_comment_to)
1025  else
1026  clrtoeol();
1027  }
1028  break;
1029 #endif
1030 
1031  case OP_COMPOSE_EDIT_SUBJECT:
1032  if (e->env->subject)
1033  mutt_str_strfcpy(buf, e->env->subject, sizeof(buf));
1034  else
1035  buf[0] = '\0';
1036  if (mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) == 0)
1037  {
1038  mutt_str_replace(&e->env->subject, buf);
1040  if (e->env->subject)
1041  mutt_paddstr(W, e->env->subject);
1042  else
1044  }
1046  break;
1047 
1048  case OP_COMPOSE_EDIT_REPLY_TO:
1051  break;
1052 
1053  case OP_COMPOSE_EDIT_FCC:
1054  mutt_str_strfcpy(buf, fcc, sizeof(buf));
1055  if (mutt_get_field(_("Fcc: "), buf, sizeof(buf), MUTT_FILE | MUTT_CLEAR) == 0)
1056  {
1057  mutt_str_strfcpy(fcc, buf, fcclen);
1058  mutt_pretty_mailbox(fcc, fcclen);
1060  mutt_paddstr(W, fcc);
1061  fcc_set = true;
1062  }
1064  break;
1065 
1066  case OP_COMPOSE_EDIT_MESSAGE:
1067  if (C_Editor && (mutt_str_strcmp("builtin", C_Editor) != 0) && !C_EditHeaders)
1068  {
1071  menu->redraw = REDRAW_FULL;
1073  break;
1074  }
1075  /* fallthrough */
1076 
1077  case OP_COMPOSE_EDIT_HEADERS:
1078  if ((mutt_str_strcmp("builtin", C_Editor) != 0) &&
1079  ((op == OP_COMPOSE_EDIT_HEADERS) || ((op == OP_COMPOSE_EDIT_MESSAGE) && C_EditHeaders)))
1080  {
1081  const char *tag = NULL;
1082  char *err = NULL;
1083  mutt_env_to_local(e->env);
1084  mutt_edit_headers(NONULL(C_Editor), e->content->filename, e, fcc, fcclen);
1085  if (mutt_env_to_intl(e->env, &tag, &err))
1086  {
1087  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
1088  FREE(&err);
1089  }
1092  }
1093  else
1094  {
1095  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
1096  * attachment list could change if the user invokes ~v to edit
1097  * the message with headers, in which we need to execute the
1098  * code below to regenerate the index array */
1099  mutt_builtin_editor(e->content->filename, e, e_cur);
1100  }
1102 
1103  /* attachments may have been added */
1104  if (actx->idxlen && actx->idx[actx->idxlen - 1]->content->next)
1105  {
1106  mutt_actx_free_entries(actx);
1107  mutt_update_compose_menu(actx, menu, true);
1108  }
1109 
1110  menu->redraw = REDRAW_FULL;
1112  break;
1113 
1114  case OP_COMPOSE_ATTACH_KEY:
1115  {
1116  if (!(WithCrypto & APPLICATION_PGP))
1117  break;
1118  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1120  if (ap->content)
1121  {
1122  update_idx(menu, actx, ap);
1123  menu->redraw |= REDRAW_INDEX;
1124  }
1125  else
1126  FREE(&ap);
1127 
1128  menu->redraw |= REDRAW_STATUS;
1129 
1131  break;
1132  }
1133 
1134  case OP_COMPOSE_MOVE_UP:
1135  if (menu->current == 0)
1136  {
1137  mutt_error(_("Attachment is already at top"));
1138  break;
1139  }
1140  if (menu->current == 1)
1141  {
1142  mutt_error(_("The fundamental part can't be moved"));
1143  break;
1144  }
1145  compose_attach_swap(e->content, actx->idx, menu->current - 1);
1146  menu->redraw = REDRAW_INDEX;
1147  menu->current--;
1148  break;
1149 
1150  case OP_COMPOSE_MOVE_DOWN:
1151  if (menu->current == (actx->idxlen - 1))
1152  {
1153  mutt_error(_("Attachment is already at bottom"));
1154  break;
1155  }
1156  if (menu->current == 0)
1157  {
1158  mutt_error(_("The fundamental part can't be moved"));
1159  break;
1160  }
1161  compose_attach_swap(e->content, actx->idx, menu->current);
1162  menu->redraw = REDRAW_INDEX;
1163  menu->current++;
1164  break;
1165 
1166  case OP_COMPOSE_GROUP_ALTS:
1167  {
1168  if (menu->tagged < 2)
1169  {
1170  mutt_error(
1171  _("Grouping 'alternatives' requires at least 2 tagged messages"));
1172  break;
1173  }
1174 
1175  struct Body *group = mutt_body_new();
1176  group->type = TYPE_MULTIPART;
1177  group->subtype = mutt_str_strdup("alternative");
1178  group->disposition = DISP_INLINE;
1179 
1180  struct Body *alts = NULL;
1181  /* group tagged message into a multipart/alternative */
1182  struct Body *bptr = e->content;
1183  for (int i = 0; bptr;)
1184  {
1185  if (bptr->tagged)
1186  {
1187  bptr->tagged = false;
1188  bptr->disposition = DISP_INLINE;
1189 
1190  /* for first match, set group desc according to match */
1191 #define ALTS_TAG "Alternatives for \"%s\""
1192  if (!group->description)
1193  {
1194  char *p = bptr->description ? bptr->description : bptr->filename;
1195  if (p)
1196  {
1197  group->description =
1198  mutt_mem_calloc(1, strlen(p) + strlen(ALTS_TAG) + 1);
1199  sprintf(group->description, ALTS_TAG, p);
1200  }
1201  }
1202 
1203  /* append bptr to the alts list,
1204  * and remove from the e->content list */
1205  if (!alts)
1206  {
1207  group->parts = bptr;
1208  alts = bptr;
1209  bptr = bptr->next;
1210  alts->next = NULL;
1211  }
1212  else
1213  {
1214  alts->next = bptr;
1215  bptr = bptr->next;
1216  alts = alts->next;
1217  alts->next = NULL;
1218  }
1219 
1220  for (int j = i; j < actx->idxlen - 1; j++)
1221  {
1222  actx->idx[j] = actx->idx[j + 1];
1223  actx->idx[j + 1] = NULL; /* for debug reason */
1224  }
1225  actx->idxlen--;
1226  }
1227  else
1228  {
1229  bptr = bptr->next;
1230  i++;
1231  }
1232  }
1233 
1234  group->next = NULL;
1236 
1237  /* if no group desc yet, make one up */
1238  if (!group->description)
1239  group->description = mutt_str_strdup("unknown alternative group");
1240 
1241  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1242  gptr->content = group;
1243  update_idx(menu, actx, gptr);
1244  menu->redraw = REDRAW_INDEX;
1245  break;
1246  }
1247 
1248  case OP_COMPOSE_GROUP_LINGUAL:
1249  {
1250  if (menu->tagged < 2)
1251  {
1252  mutt_error(
1253  _("Grouping 'multilingual' requires at least 2 tagged messages"));
1254  break;
1255  }
1256 
1257  /* traverse to see whether all the parts have Content-Language: set */
1258  int tagged_with_lang_num = 0;
1259  for (struct Body *b = e->content; b; b = b->next)
1260  if (b->tagged && b->language && *b->language)
1261  tagged_with_lang_num++;
1262 
1263  if (menu->tagged != tagged_with_lang_num)
1264  {
1265  if (mutt_yesorno(
1266  _("Not all parts have 'Content-Language' set, continue?"), MUTT_YES) != MUTT_YES)
1267  {
1268  mutt_message(_("Not sending this message"));
1269  break;
1270  }
1271  }
1272 
1273  struct Body *group = mutt_body_new();
1274  group->type = TYPE_MULTIPART;
1275  group->subtype = mutt_str_strdup("multilingual");
1276  group->disposition = DISP_INLINE;
1277 
1278  struct Body *alts = NULL;
1279  /* group tagged message into a multipart/multilingual */
1280  struct Body *bptr = e->content;
1281  for (int i = 0; bptr;)
1282  {
1283  if (bptr->tagged)
1284  {
1285  bptr->tagged = false;
1286  bptr->disposition = DISP_INLINE;
1287 
1288  /* for first match, set group desc according to match */
1289 #define LINGUAL_TAG "Multilingual part for \"%s\""
1290  if (!group->description)
1291  {
1292  char *p = bptr->description ? bptr->description : bptr->filename;
1293  if (p)
1294  {
1295  group->description =
1296  mutt_mem_calloc(1, strlen(p) + strlen(LINGUAL_TAG) + 1);
1297  sprintf(group->description, LINGUAL_TAG, p);
1298  }
1299  }
1300 
1301  /* append bptr to the alts list,
1302  * and remove from the e->content list */
1303  if (!alts)
1304  {
1305  group->parts = bptr;
1306  alts = bptr;
1307  bptr = bptr->next;
1308  alts->next = NULL;
1309  }
1310  else
1311  {
1312  alts->next = bptr;
1313  bptr = bptr->next;
1314  alts = alts->next;
1315  alts->next = NULL;
1316  }
1317 
1318  for (int j = i; j < actx->idxlen - 1; j++)
1319  {
1320  actx->idx[j] = actx->idx[j + 1];
1321  actx->idx[j + 1] = NULL; /* for debug reason */
1322  }
1323  actx->idxlen--;
1324  }
1325  else
1326  {
1327  bptr = bptr->next;
1328  i++;
1329  }
1330  }
1331 
1332  group->next = NULL;
1334 
1335  /* if no group desc yet, make one up */
1336  if (!group->description)
1337  group->description = mutt_str_strdup("unknown multilingual group");
1338 
1339  struct AttachPtr *gptr = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1340  gptr->content = group;
1341  update_idx(menu, actx, gptr);
1342  menu->redraw = REDRAW_INDEX;
1343  break;
1344  }
1345 
1346  case OP_COMPOSE_ATTACH_FILE:
1347  {
1348  char *prompt = _("Attach file");
1349  int numfiles = 0;
1350  char **files = NULL;
1351  buf[0] = '\0';
1352 
1353  if ((mutt_enter_fname_full(prompt, buf, sizeof(buf), false, true,
1354  &files, &numfiles, MUTT_SEL_MULTI) == -1) ||
1355  (*buf == '\0'))
1356  {
1357  break;
1358  }
1359 
1360  bool error = false;
1361  if (numfiles > 1)
1362  {
1363  mutt_message(ngettext("Attaching selected file...",
1364  "Attaching selected files...", numfiles));
1365  }
1366  for (int i = 0; i < numfiles; i++)
1367  {
1368  char *att = files[i];
1369  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1370  ap->unowned = true;
1371  ap->content = mutt_make_file_attach(att);
1372  if (ap->content)
1373  update_idx(menu, actx, ap);
1374  else
1375  {
1376  error = true;
1377  mutt_error(_("Unable to attach %s"), att);
1378  FREE(&ap);
1379  }
1380  FREE(&files[i]);
1381  }
1382 
1383  FREE(&files);
1384  if (!error)
1385  mutt_clear_error();
1386 
1387  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1389  break;
1390  }
1391 
1392  case OP_COMPOSE_ATTACH_MESSAGE:
1393 #ifdef USE_NNTP
1394  case OP_COMPOSE_ATTACH_NEWS_MESSAGE:
1395 #endif
1396  {
1397  char *prompt = _("Open mailbox to attach message from");
1398  buf[0] = '\0';
1399 
1400 #ifdef USE_NNTP
1401  OptNews = false;
1402  if (Context && (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE))
1403  {
1405  if (!CurrentNewsSrv)
1406  break;
1407 
1408  prompt = _("Open newsgroup to attach message from");
1409  OptNews = true;
1410  }
1411 #endif
1412 
1413  if (Context)
1414 #ifdef USE_NNTP
1415  if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->mailbox->magic == MUTT_NNTP))
1416 #endif
1417  {
1418  mutt_str_strfcpy(buf, mutt_b2s(Context->mailbox->pathbuf), sizeof(buf));
1419  mutt_pretty_mailbox(buf, sizeof(buf));
1420  }
1421 
1422  if ((mutt_enter_fname(prompt, buf, sizeof(buf), true) == -1) || (buf[0] == '\0'))
1423  break;
1424 
1425 #ifdef USE_NNTP
1426  if (OptNews)
1427  nntp_expand_path(buf, sizeof(buf), &CurrentNewsSrv->conn->account);
1428  else
1429 #endif
1430  mutt_expand_path(buf, sizeof(buf));
1431 #ifdef USE_IMAP
1432  if (imap_path_probe(buf, NULL) != MUTT_IMAP)
1433 #endif
1434 #ifdef USE_POP
1435  if (pop_path_probe(buf, NULL) != MUTT_POP)
1436 #endif
1437 #ifdef USE_NNTP
1438  if (!OptNews && (nntp_path_probe(buf, NULL) != MUTT_NNTP))
1439 #endif
1440  /* check to make sure the file exists and is readable */
1441  if (access(buf, R_OK) == -1)
1442  {
1443  mutt_perror(buf);
1444  break;
1445  }
1446 
1447  menu->redraw = REDRAW_FULL;
1448 
1449  struct Mailbox *m = mx_path_resolve(buf);
1450  struct Context *ctx = mx_mbox_open(m, MUTT_READONLY);
1451  if (!ctx)
1452  {
1453  mutt_error(_("Unable to open mailbox %s"), buf);
1454  mailbox_free(&m);
1455  break;
1456  }
1457 
1458  if (ctx->mailbox->msg_count == 0)
1459  {
1460  mx_mbox_close(&ctx);
1461  mutt_error(_("No messages in that folder"));
1462  break;
1463  }
1464 
1465  struct Context *ctx_cur = Context; /* remember current folder and sort methods */
1466  int old_sort = C_Sort; /* C_Sort, SortAux could be changed in mutt_index_menu() */
1467  int old_sort_aux = C_SortAux;
1468 
1469  Context = ctx;
1470  OptAttachMsg = true;
1471  mutt_message(_("Tag the messages you want to attach"));
1472  op_close = mutt_index_menu();
1473  OptAttachMsg = false;
1474 
1475  if (!Context)
1476  {
1477  /* go back to the folder we started from */
1478  Context = ctx_cur;
1479  /* Restore old $sort and $sort_aux */
1480  C_Sort = old_sort;
1481  C_SortAux = old_sort_aux;
1482  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1483  break;
1484  }
1485 
1486  for (int i = 0; i < Context->mailbox->msg_count; i++)
1487  {
1488  if (!message_is_tagged(Context, i))
1489  continue;
1490 
1491  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1493  Context->mailbox->emails[i], true);
1494  if (ap->content)
1495  update_idx(menu, actx, ap);
1496  else
1497  {
1498  mutt_error(_("Unable to attach"));
1499  FREE(&ap);
1500  }
1501  }
1502  menu->redraw |= REDRAW_FULL;
1503 
1504  if (op_close == OP_QUIT)
1506  else
1507  {
1509  ctx_free(&Context);
1510  }
1511 
1512  /* go back to the folder we started from */
1513  Context = ctx_cur;
1514  /* Restore old $sort and $sort_aux */
1515  C_Sort = old_sort;
1516  C_SortAux = old_sort_aux;
1518  break;
1519  }
1520 
1521  case OP_DELETE:
1522  CHECK_COUNT;
1523  if (CUR_ATTACH->unowned)
1524  CUR_ATTACH->content->unlink = false;
1525  if (delete_attachment(actx, menu->current) == -1)
1526  break;
1527  mutt_update_compose_menu(actx, menu, false);
1528  if (menu->current == 0)
1529  e->content = actx->idx[0]->content;
1530 
1532  break;
1533 
1534  case OP_COMPOSE_TOGGLE_RECODE:
1535  {
1536  CHECK_COUNT;
1537  if (!mutt_is_text_part(CUR_ATTACH->content))
1538  {
1539  mutt_error(_("Recoding only affects text attachments"));
1540  break;
1541  }
1542  CUR_ATTACH->content->noconv = !CUR_ATTACH->content->noconv;
1543  if (CUR_ATTACH->content->noconv)
1544  mutt_message(_("The current attachment won't be converted"));
1545  else
1546  mutt_message(_("The current attachment will be converted"));
1547  menu->redraw = REDRAW_CURRENT;
1549  break;
1550  }
1551 
1552  case OP_COMPOSE_EDIT_DESCRIPTION:
1553  CHECK_COUNT;
1555  buf, CUR_ATTACH->content->description ? CUR_ATTACH->content->description : "",
1556  sizeof(buf));
1557  /* header names should not be translated */
1558  if (mutt_get_field("Description: ", buf, sizeof(buf), 0) == 0)
1559  {
1560  mutt_str_replace(&CUR_ATTACH->content->description, buf);
1561  menu->redraw = REDRAW_CURRENT;
1562  }
1564  break;
1565 
1566  case OP_COMPOSE_UPDATE_ENCODING:
1567  CHECK_COUNT;
1568  if (menu->tagprefix)
1569  {
1570  struct Body *top = NULL;
1571  for (top = e->content; top; top = top->next)
1572  {
1573  if (top->tagged)
1574  mutt_update_encoding(top);
1575  }
1576  menu->redraw = REDRAW_FULL;
1577  }
1578  else
1579  {
1580  mutt_update_encoding(CUR_ATTACH->content);
1582  }
1584  break;
1585 
1586  case OP_COMPOSE_TOGGLE_DISPOSITION:
1587  /* toggle the content-disposition between inline/attachment */
1588  CUR_ATTACH->content->disposition =
1589  (CUR_ATTACH->content->disposition == DISP_INLINE) ? DISP_ATTACH : DISP_INLINE;
1590  menu->redraw = REDRAW_CURRENT;
1591  break;
1592 
1593  case OP_EDIT_TYPE:
1594  CHECK_COUNT;
1595  {
1596  mutt_edit_content_type(NULL, CUR_ATTACH->content, NULL);
1597 
1598  /* this may have been a change to text/something */
1599  mutt_update_encoding(CUR_ATTACH->content);
1600 
1601  menu->redraw = REDRAW_CURRENT;
1602  }
1604  break;
1605 
1606  case OP_COMPOSE_EDIT_LANGUAGE:
1607  CHECK_COUNT;
1608  buf[0] = '\0'; /* clear buffer first */
1609  if (CUR_ATTACH->content->language)
1610  mutt_str_strfcpy(buf, CUR_ATTACH->content->language, sizeof(buf));
1611  if (mutt_get_field("Content-Language: ", buf, sizeof(buf), 0) == 0)
1612  {
1613  CUR_ATTACH->content->language = mutt_str_strdup(buf);
1615  mutt_clear_error();
1616  }
1617  else
1618  mutt_warning(_("Empty 'Content-Language'"));
1620  break;
1621 
1622  case OP_COMPOSE_EDIT_ENCODING:
1623  CHECK_COUNT;
1624  mutt_str_strfcpy(buf, ENCODING(CUR_ATTACH->content->encoding), sizeof(buf));
1625  if ((mutt_get_field("Content-Transfer-Encoding: ", buf, sizeof(buf), 0) == 0) &&
1626  (buf[0] != '\0'))
1627  {
1628  int enc = mutt_check_encoding(buf);
1629  if ((enc != ENC_OTHER) && (enc != ENC_UUENCODED))
1630  {
1631  CUR_ATTACH->content->encoding = enc;
1633  mutt_clear_error();
1634  }
1635  else
1636  mutt_error(_("Invalid encoding"));
1637  }
1639  break;
1640 
1641  case OP_COMPOSE_SEND_MESSAGE:
1642  /* Note: We don't invoke send2-hook here, since we want to leave
1643  * users an opportunity to change settings from the ":" prompt. */
1644  if (check_attachments(actx) != 0)
1645  {
1646  menu->redraw = REDRAW_FULL;
1647  break;
1648  }
1649 
1650 #ifdef MIXMASTER
1651  if (!STAILQ_EMPTY(&e->chain) && (mix_check_message(e) != 0))
1652  break;
1653 #endif
1654 
1655  if (!fcc_set && *fcc)
1656  {
1657  enum QuadOption ans =
1658  query_quadoption(C_Copy, _("Save a copy of this message?"));
1659  if (ans == MUTT_ABORT)
1660  break;
1661  else if (ans == MUTT_NO)
1662  *fcc = '\0';
1663  }
1664 
1665  loop = false;
1666  rc = 0;
1667  break;
1668 
1669  case OP_COMPOSE_EDIT_FILE:
1670  CHECK_COUNT;
1671  mutt_edit_file(NONULL(C_Editor), CUR_ATTACH->content->filename);
1672  mutt_update_encoding(CUR_ATTACH->content);
1675  break;
1676 
1677  case OP_COMPOSE_TOGGLE_UNLINK:
1678  CHECK_COUNT;
1679  CUR_ATTACH->content->unlink = !CUR_ATTACH->content->unlink;
1680 
1681  menu->redraw = REDRAW_INDEX;
1682  /* No send2hook since this doesn't change the message. */
1683  break;
1684 
1685  case OP_COMPOSE_GET_ATTACHMENT:
1686  CHECK_COUNT;
1687  if (menu->tagprefix)
1688  {
1689  for (struct Body *top = e->content; top; top = top->next)
1690  {
1691  if (top->tagged)
1693  }
1694  menu->redraw = REDRAW_FULL;
1695  }
1696  else if (mutt_get_tmp_attachment(CUR_ATTACH->content) == 0)
1697  menu->redraw = REDRAW_CURRENT;
1698 
1699  /* No send2hook since this doesn't change the message. */
1700  break;
1701 
1702  case OP_COMPOSE_RENAME_ATTACHMENT:
1703  {
1704  CHECK_COUNT;
1705  char *src = NULL;
1706  if (CUR_ATTACH->content->d_filename)
1707  src = CUR_ATTACH->content->d_filename;
1708  else
1709  src = CUR_ATTACH->content->filename;
1710  mutt_str_strfcpy(buf, mutt_path_basename(NONULL(src)), sizeof(buf));
1711  int ret = mutt_get_field(_("Send attachment with name: "), buf, sizeof(buf), MUTT_FILE);
1712  if (ret == 0)
1713  {
1714  /* As opposed to RENAME_FILE, we don't check buf[0] because it's
1715  * valid to set an empty string here, to erase what was set */
1716  mutt_str_replace(&CUR_ATTACH->content->d_filename, buf);
1717  menu->redraw = REDRAW_CURRENT;
1718  }
1719  break;
1720  }
1721 
1722  case OP_COMPOSE_RENAME_FILE:
1723  CHECK_COUNT;
1724  mutt_str_strfcpy(buf, CUR_ATTACH->content->filename, sizeof(buf));
1725  mutt_pretty_mailbox(buf, sizeof(buf));
1726  if ((mutt_get_field(_("Rename to: "), buf, sizeof(buf), MUTT_FILE) == 0) &&
1727  (buf[0] != '\0'))
1728  {
1729  struct stat st;
1730  if (stat(CUR_ATTACH->content->filename, &st) == -1)
1731  {
1732  /* L10N: "stat" is a system call. Do "man 2 stat" for more information. */
1733  mutt_error(_("Can't stat %s: %s"), buf, strerror(errno));
1734  break;
1735  }
1736 
1737  mutt_expand_path(buf, sizeof(buf));
1738  if (mutt_file_rename(CUR_ATTACH->content->filename, buf))
1739  break;
1740 
1741  mutt_str_replace(&CUR_ATTACH->content->filename, buf);
1742  menu->redraw = REDRAW_CURRENT;
1743 
1744  if (CUR_ATTACH->content->stamp >= st.st_mtime)
1746  }
1748  break;
1749 
1750  case OP_COMPOSE_NEW_MIME:
1751  {
1753  buf[0] = '\0';
1754  if ((mutt_get_field(_("New file: "), buf, sizeof(buf), MUTT_FILE) != 0) ||
1755  (buf[0] == '\0'))
1756  {
1757  continue;
1758  }
1759  mutt_expand_path(buf, sizeof(buf));
1760 
1761  /* Call to lookup_mime_type () ? maybe later */
1762  char type[256] = { 0 };
1763  if ((mutt_get_field("Content-Type: ", type, sizeof(type), 0) != 0) ||
1764  (type[0] == '\0'))
1765  {
1766  continue;
1767  }
1768 
1769  char *p = strchr(type, '/');
1770  if (!p)
1771  {
1772  mutt_error(_("Content-Type is of the form base/sub"));
1773  continue;
1774  }
1775  *p++ = 0;
1776  enum ContentType itype = mutt_check_mime_type(type);
1777  if (itype == TYPE_OTHER)
1778  {
1779  mutt_error(_("Unknown Content-Type %s"), type);
1780  continue;
1781  }
1782  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1783  /* Touch the file */
1784  FILE *fp = mutt_file_fopen(buf, "w");
1785  if (!fp)
1786  {
1787  mutt_error(_("Can't create file %s"), buf);
1788  FREE(&ap);
1789  continue;
1790  }
1791  mutt_file_fclose(&fp);
1792 
1793  ap->content = mutt_make_file_attach(buf);
1794  if (!ap->content)
1795  {
1796  mutt_error(_("What we have here is a failure to make an attachment"));
1797  FREE(&ap);
1798  continue;
1799  }
1800  update_idx(menu, actx, ap);
1801 
1802  CUR_ATTACH->content->type = itype;
1803  mutt_str_replace(&CUR_ATTACH->content->subtype, p);
1804  CUR_ATTACH->content->unlink = true;
1805  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
1806 
1807  if (mutt_compose_attachment(CUR_ATTACH->content))
1808  {
1809  mutt_update_encoding(CUR_ATTACH->content);
1810  menu->redraw = REDRAW_FULL;
1811  }
1813  break;
1814  }
1815 
1816  case OP_COMPOSE_EDIT_MIME:
1817  CHECK_COUNT;
1818  if (mutt_edit_attachment(CUR_ATTACH->content))
1819  {
1820  mutt_update_encoding(CUR_ATTACH->content);
1821  menu->redraw = REDRAW_FULL;
1822  }
1824  break;
1825 
1826  case OP_VIEW_ATTACH:
1827  case OP_DISPLAY_HEADERS:
1828  CHECK_COUNT;
1829  mutt_attach_display_loop(menu, op, NULL, actx, false);
1830  menu->redraw = REDRAW_FULL;
1831  /* no send2hook, since this doesn't modify the message */
1832  break;
1833 
1834  case OP_SAVE:
1835  CHECK_COUNT;
1836  mutt_save_attachment_list(actx, NULL, menu->tagprefix,
1837  CUR_ATTACH->content, NULL, menu);
1838  /* no send2hook, since this doesn't modify the message */
1839  break;
1840 
1841  case OP_PRINT:
1842  CHECK_COUNT;
1843  mutt_print_attachment_list(actx, NULL, menu->tagprefix, CUR_ATTACH->content);
1844  /* no send2hook, since this doesn't modify the message */
1845  break;
1846 
1847  case OP_PIPE:
1848  case OP_FILTER:
1849  CHECK_COUNT;
1850  mutt_pipe_attachment_list(actx, NULL, menu->tagprefix,
1851  CUR_ATTACH->content, (op == OP_FILTER));
1852  if (op == OP_FILTER) /* cte might have changed */
1853  menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT;
1854  menu->redraw |= REDRAW_STATUS;
1856  break;
1857 
1858  case OP_EXIT:
1859  {
1860  enum QuadOption ans =
1861  query_quadoption(C_Postpone, _("Save (postpone) draft message?"));
1862  if (ans == MUTT_NO)
1863  {
1864  for (int i = 0; i < actx->idxlen; i++)
1865  if (actx->idx[i]->unowned)
1866  actx->idx[i]->content->unlink = false;
1867 
1868  if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
1869  {
1870  for (int i = 0; i < actx->idxlen; i++)
1871  {
1872  /* avoid freeing other attachments */
1873  actx->idx[i]->content->next = NULL;
1874  actx->idx[i]->content->parts = NULL;
1875  mutt_body_free(&actx->idx[i]->content);
1876  }
1877  }
1878  rc = -1;
1879  loop = false;
1880  break;
1881  }
1882  else if (ans == MUTT_ABORT)
1883  break; /* abort */
1884  }
1885  /* fallthrough */
1886 
1887  case OP_COMPOSE_POSTPONE_MESSAGE:
1888  if (check_attachments(actx) != 0)
1889  {
1890  menu->redraw = REDRAW_FULL;
1891  break;
1892  }
1893 
1894  loop = false;
1895  rc = 1;
1896  break;
1897 
1898  case OP_COMPOSE_ISPELL:
1899  endwin();
1900  snprintf(buf, sizeof(buf), "%s -x %s", NONULL(C_Ispell), e->content->filename);
1901  if (mutt_system(buf) == -1)
1902  mutt_error(_("Error running \"%s\""), buf);
1903  else
1904  {
1906  menu->redraw |= REDRAW_STATUS;
1907  }
1908  break;
1909 
1910  case OP_COMPOSE_WRITE_MESSAGE:
1911  buf[0] = '\0';
1912  if (Context)
1913  {
1914  mutt_str_strfcpy(buf, mutt_b2s(Context->mailbox->pathbuf), sizeof(buf));
1915  mutt_pretty_mailbox(buf, sizeof(buf));
1916  }
1917  if (actx->idxlen)
1918  e->content = actx->idx[0]->content;
1919  if ((mutt_enter_fname(_("Write message to mailbox"), buf, sizeof(buf), true) != -1) &&
1920  (buf[0] != '\0'))
1921  {
1922  mutt_message(_("Writing message to %s ..."), buf);
1923  mutt_expand_path(buf, sizeof(buf));
1924 
1925  if (e->content->next)
1927 
1928  if (mutt_write_fcc(buf, e, NULL, false, NULL, NULL) < 0)
1930  else
1931  mutt_message(_("Message written"));
1932  }
1933  break;
1934 
1935  case OP_COMPOSE_PGP_MENU:
1936  if (!(WithCrypto & APPLICATION_PGP))
1937  break;
1938  if (!crypt_has_module_backend(APPLICATION_PGP))
1939  {
1940  mutt_error(_("No PGP backend configured"));
1941  break;
1942  }
1943  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
1944  {
1945  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1946  {
1947  if (mutt_yesorno(_("S/MIME already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
1948  {
1949  mutt_clear_error();
1950  break;
1951  }
1952  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
1953  }
1954  e->security &= ~APPLICATION_SMIME;
1955  e->security |= APPLICATION_PGP;
1957  redraw_crypt_lines(e);
1958  }
1959  e->security = crypt_pgp_send_menu(e);
1960  redraw_crypt_lines(e);
1962  break;
1963 
1964  case OP_FORGET_PASSPHRASE:
1966  break;
1967 
1968  case OP_COMPOSE_SMIME_MENU:
1969  if (!(WithCrypto & APPLICATION_SMIME))
1970  break;
1971  if (!crypt_has_module_backend(APPLICATION_SMIME))
1972  {
1973  mutt_error(_("No S/MIME backend configured"));
1974  break;
1975  }
1976 
1977  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
1978  {
1979  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1980  {
1981  if (mutt_yesorno(_("PGP already selected. Clear and continue?"), MUTT_YES) != MUTT_YES)
1982  {
1983  mutt_clear_error();
1984  break;
1985  }
1986  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
1987  }
1988  e->security &= ~APPLICATION_PGP;
1991  redraw_crypt_lines(e);
1992  }
1994  redraw_crypt_lines(e);
1996  break;
1997 
1998 #ifdef MIXMASTER
1999  case OP_COMPOSE_MIX:
2000  mix_make_chain(&e->chain);
2002  break;
2003 #endif
2004  }
2005  }
2006 
2007  mutt_menu_pop_current(menu);
2008  mutt_menu_destroy(&menu);
2009 
2010  if (actx->idxlen)
2011  e->content = actx->idx[0]->content;
2012  else
2013  e->content = NULL;
2014 
2015  mutt_actx_free(&actx);
2016 
2017  return rc;
2018 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:111
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:39
struct NntpAccountData * nntp_select_server(struct Mailbox *m, char *server, bool leave_lock)
Open a connection to an NNTP server.
Definition: newsrc.c:982
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1477
static int delete_attachment(struct AttachCtx *actx, int x)
Delete an attachment.
Definition: compose.c:554
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1409
Unknown Content-Type.
Definition: mime.h:31
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
An email to which things will be attached.
Definition: attach.h:34
int mutt_attach_display_loop(struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
Event loop for the Attachment menu.
Definition: recvattach.c:1136
int msg_count
Total number of messages.
Definition: mailbox.h:103
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1733
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
static void redraw_crypt_lines(struct Email *e)
Update the encryption info in the compose window.
Definition: compose.c:270
#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:2432
struct ConnAccount account
Definition: connection.h:36
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:561
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:48
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3321
#define mutt_message(...)
Definition: logging.h:83
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1333
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:46
static void compose_custom_redraw(struct Menu *menu)
Redraw the compose menu - Implements Menu::menu_custom_redraw()
Definition: compose.c:680
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
Definition: recvattach.c:649
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
"To:" field
Definition: compose.c:113
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:101
"Cc:" field
Definition: compose.c:114
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:256
#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
Compose an email.
Definition: keymap.h:72
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:264
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:181
char * C_Ispell
Config: External command to perform spell-checking.
Definition: compose.c:91
int menu
menu definition for keymap entries.
Definition: mutt_menu.h:90
#define MUTT_READONLY
Open in read-only mode.
Definition: mx.h:54
"Subject:" field
Definition: compose.c:116
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:260
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:121
static int check_attachments(struct AttachCtx *actx)
Check if any attachments have changed or been deleted.
Definition: compose.c:401
"From:" field
Definition: compose.c:112
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:122
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
char * mutt_compile_help(char *buf, size_t buflen, int menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1161
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:257
#define CUR_ATTACH
Definition: compose.c:103
void mutt_generate_boundary(struct ParameterList *parm)
Create a unique boundary id for a MIME part.
Definition: sendlib.c:594
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
void * redraw_data
Definition: mutt_menu.h:152
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1019
int mutt_get_tmp_attachment(struct Body *a)
Get a temporary copy of an attachment.
Definition: mutt_attach.c:67
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:208
struct Mailbox * mailbox
Definition: context.h:53
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
int mutt_enter_fname_full(const char *prompt, char *buf, size_t buflen, bool mailbox, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:622
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1611
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:56
enum ContentType mutt_check_mime_type(const char *s)
Check a MIME type string.
Definition: parse.c:296
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:43
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:117
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:480
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1446
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
Envelope information.
Definition: email.h:89
#define ENCODING(x)
Definition: mime.h:85
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:395
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:45
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:306
static void compose_attach_swap(struct Body *msg, struct AttachPtr **idx, short first)
Swap two adjacent entries in the attachment list.
Definition: compose.c:729
void(* menu_custom_redraw)(struct Menu *menu)
Redraw the menu.
Definition: mutt_menu.h:151
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:59
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:141
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:1707
char * subtype
content-type subtype
Definition: body.h:37
void mutt_actx_free(struct AttachCtx **pactx)
Free an Attachment Context.
Definition: attach.c:131
#define mutt_b2s(buf)
Definition: buffer.h:42
WHERE char * C_NewsServer
Config: (nntp) Url of the news server.
Definition: globals.h:127
static const struct Mapping ComposeHelp[]
Definition: compose.c:177
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:64
void mutt_actx_free_entries(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
WHERE short C_SortAux
Config: Secondary sort method for the index.
Definition: sort.h:60
#define HDR_XOFFSET
Definition: compose.c:135
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:122
WHERE struct Context * Context
Definition: globals.h:41
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:447
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:267
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
int mutt_check_encoding(const char *c)
Check the encoding type.
Definition: parse.c:405
#define ALTS_TAG
A mailbox.
Definition: mailbox.h:93
#define PATH_MAX
Definition: mutt.h:50
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool tagprefix
Definition: mutt_menu.h:93
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:325
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
void mix_make_chain(struct ListHead *chainhead)
Create a Mixmaster chain.
Definition: remailer.c:559
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:625
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:615
char * description
content-description
Definition: body.h:40
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:436
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
#define W
Definition: compose.c:136
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:43
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:193
int tagged
number of tagged entries
Definition: mutt_menu.h:113
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:549
#define MUTT_FILE
Do file completion.
Definition: mutt.h:64
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
unsigned int type
content-type primary type
Definition: body.h:65
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:139
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:130
"Bcc:" field
Definition: compose.c:115
static void edit_address_list(int line, struct AddressList *al)
Let the user edit the address list.
Definition: compose.c:519
#define LINGUAL_TAG
struct Buffer * pathbuf
Definition: mailbox.h:95
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:153
static void update_idx(struct Menu *menu, struct AttachCtx *actx, struct AttachPtr *ap)
Add a new attchment to the message.
Definition: compose.c:654
struct Connection * conn
Definition: nntp.h:103
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
Definition: recvattach.c:870
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:222
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:985
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:261
int offset
row offset within the window to start the index
Definition: mutt_menu.h:91
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * subject
Email&#39;s subject.
Definition: envelope.h:52
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
char * newsgroups
List of newsgroups.
Definition: envelope.h:61
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:55
#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:281
struct Body * content
Attachment.
Definition: attach.h:36
unsigned char C_Postpone
Config: Save messages to the C_Postponed folder.
Definition: compose.c:92
#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:1231
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:63
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:104
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, char *fcc, size_t fcclen)
Let the user edit the message header and body.
Definition: mutt_header.c:170
#define mutt_enter_fname(prompt, buf, buflen, mailbox)
Definition: curs_lib.h:85
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1544
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:36
#define STAILQ_EMPTY(head)
Definition: queue.h:346
Position to start printing the attachments.
Definition: compose.c:129
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:44
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
static void init_header_padding(void)
Calculate how much padding the compose table will need.
Definition: compose.c:230
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:47
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
enum MailboxType nntp_path_probe(const char *path, const struct stat *st)
Is this an NNTP Mailbox? - Implements MxOps::path_probe()
Definition: nntp.c:2827
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1186
int current
current entry
Definition: mutt_menu.h:87
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
"Fcc:" (save folder) field
Definition: compose.c:118
#define CHECK_COUNT
Definition: compose.c:96
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:584
int mutt_index_menu(void)
Display a list of emails.
Definition: index.c:1020
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
#define WithCrypto
Definition: ncrypt.h:156
A set of attachments.
Definition: attach.h:49
Encoding unknown.
Definition: mime.h:48
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:308
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:42
char * help
quickref for the current menu
Definition: mutt_menu.h:85
Keep track when the compose screen needs redrawing.
Definition: compose.c:668
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:50
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
UUEncoded text.
Definition: mime.h:54
bool message_is_tagged(struct Context *ctx, int index)
Is a message in the index tagged (and within limit)
Definition: context.c:319
#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:117
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:776
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:76
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:131
ContentType
Content-Type.
Definition: mime.h:29
"Reply-To:" field
Definition: compose.c:117
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3168

Variable Documentation

char* C_ComposeFormat

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

Definition at line 90 of file compose.c.

char* C_Ispell

Config: External command to perform spell-checking.

Definition at line 91 of file compose.c.

unsigned char C_Postpone

Config: Save messages to the C_Postponed folder.

Definition at line 92 of file compose.c.

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

Definition at line 94 of file compose.c.

int HeaderPadding[HDR_XCOMMENTTO+1] = { 0 }

Definition at line 132 of file compose.c.

int MaxHeaderWidth = 0

Definition at line 133 of file compose.c.

const char* const Prompts[]
static

Definition at line 138 of file compose.c.

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

Definition at line 177 of file compose.c.

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

Definition at line 193 of file compose.c.