NeoMutt  2018-07-16 +952-a2da0a
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 "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 "curs_lib.h"
#include "edit.h"
#include "format_flags.h"
#include "globals.h"
#include "hook.h"
#include "index.h"
#include "keymap.h"
#include "mailbox.h"
#include "menu.h"
#include "mutt_attach.h"
#include "mutt_curses.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "recvattach.h"
#include "sendlib.h"
#include "sort.h"
#include <libintl.h>
#include "nntp/nntp.h"
#include "pop/pop.h"
#include "imap/imap.h"
+ Include dependency graph for compose.c:

Go to the source code of this file.

Data Structures

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

Macros

#define CHECK_COUNT
 
#define CURATTACH   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 *msg)
 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 Address *addr)
 Write addresses to the compose window. More...
 
static void draw_envelope (struct Email *msg, char *fcc)
 Write the email headers to the compose window. More...
 
static void edit_address_list (int line, struct Address **addr)
 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 *new)
 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, enum FormatFlag flags)
 Create the status bar string for compose mode - Implements format_t. More...
 
int mutt_compose_menu (struct Email *msg, char *fcc, size_t fcclen, struct Email *cur, int flags)
 Allow the user to edit the message envelope. More...
 

Variables

char * ComposeFormat
 Config: printf-like format string for the Compose panel's status bar. More...
 
char * Ispell
 Config: External command to perform spell-checking. More...
 
unsigned char Postpone
 Config: Save messages to the 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

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:92
#define _(a)
Definition: message.h:28
#define mutt_error(...)
Definition: logging.h:88

Definition at line 94 of file compose.c.

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

Definition at line 101 of file compose.c.

#define HDR_XOFFSET   MaxHeaderWidth

Definition at line 133 of file compose.c.

#define W   (MuttIndexWindow->cols - MaxHeaderWidth)

Definition at line 134 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 108 of file compose.c.

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

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:131
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:663
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1176
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void init_header_padding ( void  )
static

Calculate how much padding the compose table will need.

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

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

Definition at line 230 of file compose.c.

231 {
232  static short done = 0;
233 
234  if (done)
235  return;
236  done = 1;
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:131
#define _(a)
Definition: message.h:28
"Sign as:" field (encryption/signing info)
Definition: compose.c:121
"X-Comment-To:" field
Definition: compose.c:125
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:130
static const char *const Prompts[]
Definition: compose.c:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

Definition at line 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 }
#define NONULL(x)
Definition: string2.h:39
used by attach_format_str
Definition: format_flags.h:37
const char * line
Definition: common.c:35
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
reserve space for arrow_cursor
Definition: format_flags.h:38
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, enum FormatFlag flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:208
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
WHERE char * AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:105
void * data
extra data for the current menu
Definition: menu.h:60
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void redraw_crypt_lines ( struct Email msg)
static

Update the encryption info in the compose window.

Parameters
msgHeader of message

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 ((msg->security & (ENCRYPT | SIGN)) == (ENCRYPT | SIGN))
284  {
286  addstr(_("Sign, Encrypt"));
287  }
288  else if (msg->security & ENCRYPT)
289  {
291  addstr(_("Encrypt"));
292  }
293  else if (msg->security & 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 ((msg->security & (ENCRYPT | SIGN)))
307  {
308  if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP))
309  {
310  if ((msg->security & INLINE))
311  addstr(_(" (inline PGP)"));
312  else
313  addstr(_(" (PGP/MIME)"));
314  }
315  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
316  addstr(_(" (S/MIME)"));
317  }
318 
320  addstr(_(" (OppEnc mode)"));
321 
325 
326  if (((WithCrypto & APPLICATION_PGP) != 0) &&
327  (msg->security & APPLICATION_PGP) && (msg->security & SIGN))
328  {
330  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
331  NORMAL_COLOR;
332  printw("%s", PgpSignAs ? PgpSignAs : _("<default>"));
333  }
334 
335  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
336  (msg->security & APPLICATION_SMIME) && (msg->security & SIGN))
337  {
339  printw("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
340  NORMAL_COLOR;
341  printw("%s", SmimeSignAs ? SmimeSignAs : _("<default>"));
342  }
343 
344  if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME) &&
346  {
348  mutt_window_mvprintw(MuttIndexWindow, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
349  NORMAL_COLOR;
350  printw("%s", NONULL(SmimeEncryptWith));
351  }
352 }
Header labels, e.g. From:
Definition: mutt_curses.h:167
#define SIGN
Definition: ncrypt.h:120
#define NONULL(x)
Definition: string2.h:39
Mail will not be encrypted or signed.
Definition: mutt_curses.h:171
unsigned int security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:37
#define NORMAL_COLOR
Definition: mutt_curses.h:235
Mail will be encrypted.
Definition: mutt_curses.h:168
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
"Sign as:" field (encryption/signing info)
Definition: compose.c:121
Mail will be signed.
Definition: mutt_curses.h:169
Mail will be encrypted and signed.
Definition: mutt_curses.h:170
#define INLINE
Definition: ncrypt.h:126
WHERE char * SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:173
#define OPPENCRYPT
Definition: ncrypt.h:127
WHERE char * PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:168
WHERE char * SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:172
#define ENCRYPT
Definition: ncrypt.h:119
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:130
"Security:" field (encryption/signing info)
Definition: compose.c:120
static const char *const Prompts[]
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
#define SETCOLOR(X)
Definition: mutt_curses.h:220
#define APPLICATION_PGP
Definition: ncrypt.h:129
WHERE bool CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:271
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:205
#define WithCrypto
Definition: ncrypt.h:154
#define APPLICATION_SMIME
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int check_attachments ( struct AttachCtx actx)
static

Check if any attachments have changed or been deleted.

Parameters
actxAttachment context
Return values
0Success
-1Error

Definition at line 401 of file compose.c.

402 {
403  int r;
404  struct stat st;
405  char pretty[PATH_MAX], msg[PATH_MAX + SHORT_STRING];
406 
407  for (int i = 0; i < actx->idxlen; i++)
408  {
409  if (actx->idx[i]->content->type == TYPE_MULTIPART)
410  continue;
411  mutt_str_strfcpy(pretty, actx->idx[i]->content->filename, sizeof(pretty));
412  if (stat(actx->idx[i]->content->filename, &st) != 0)
413  {
414  mutt_pretty_mailbox(pretty, sizeof(pretty));
415  mutt_error(_("%s [#%d] no longer exists"), pretty, i + 1);
416  return -1;
417  }
418 
419  if (actx->idx[i]->content->stamp < st.st_mtime)
420  {
421  mutt_pretty_mailbox(pretty, sizeof(pretty));
422  snprintf(msg, sizeof(msg), _("%s [#%d] modified. Update encoding?"), pretty, i + 1);
423 
424  r = mutt_yesorno(msg, MUTT_YES);
425  if (r == MUTT_YES)
426  mutt_update_encoding(actx->idx[i]->content);
427  else if (r == MUTT_ABORT)
428  return -1;
429  }
430  }
431 
432  return 0;
433 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
#define SHORT_STRING
Definition: string2.h:34
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:606
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
int mutt_yesorno(const char *msg, int def)
Ask the user a Yes/No question.
Definition: curs_lib.c:330
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1428
#define PATH_MAX
Definition: mutt.h:46
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:742
unsigned int type
content-type primary type
Definition: body.h:67
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Definition: attach.h:36
time_t stamp
time stamp of last encoding update.
Definition: body.h:65
#define mutt_error(...)
Definition: logging.h:88
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void draw_envelope_addr ( int  line,
struct Address addr 
)
static

Write addresses to the compose window.

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

Definition at line 440 of file compose.c.

441 {
442  char buf[LONG_STRING];
443 
444  buf[0] = 0;
445  mutt_addr_write(buf, sizeof(buf), addr, true);
448  _(Prompts[line]));
449  NORMAL_COLOR;
450  mutt_paddstr(W, buf);
451 }
Header labels, e.g. From:
Definition: mutt_curses.h:167
#define NORMAL_COLOR
Definition: mutt_curses.h:235
#define _(a)
Definition: message.h:28
#define LONG_STRING
Definition: string2.h:36
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1083
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1146
const char * line
Definition: common.c:35
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:130
static const char *const Prompts[]
Definition: compose.c:136
#define W
Definition: compose.c:134
#define SETCOLOR(X)
Definition: mutt_curses.h:220
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:205

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void draw_envelope ( struct Email msg,
char *  fcc 
)
static

Write the email headers to the compose window.

Parameters
msgHeader of the message
fccFcc field

Definition at line 458 of file compose.c.

459 {
461 #ifdef USE_NNTP
462  if (!OptNewsSend)
463  {
464 #endif
468 #ifdef USE_NNTP
469  }
470  else
471  {
473  HeaderPadding[HDR_NEWSGROUPS], Prompts[HDR_NEWSGROUPS]);
476  HeaderPadding[HDR_FOLLOWUPTO], Prompts[HDR_FOLLOWUPTO]);
478  if (XCommentTo)
479  {
481  HeaderPadding[HDR_XCOMMENTTO], Prompts[HDR_XCOMMENTTO]);
483  }
484  }
485 #endif
486 
489  HeaderPadding[HDR_SUBJECT], _(Prompts[HDR_SUBJECT]));
490  NORMAL_COLOR;
491  mutt_paddstr(W, NONULL(msg->env->subject));
492 
494 
497  HeaderPadding[HDR_FCC], _(Prompts[HDR_FCC]));
498  NORMAL_COLOR;
499  mutt_paddstr(W, fcc);
500 
501  if (WithCrypto)
502  redraw_crypt_lines(msg);
503 
504 #ifdef MIXMASTER
505  redraw_mix_line(&msg->chain);
506 #endif
507 
509  mutt_window_mvaddstr(MuttIndexWindow, HDR_ATTACH - 1, 0, _("-- Attachments"));
511 
512  NORMAL_COLOR;
513 }
Header labels, e.g. From:
Definition: mutt_curses.h:167
#define NONULL(x)
Definition: string2.h:39
WHERE bool XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:282
struct Address * to
Definition: envelope.h:36
#define NORMAL_COLOR
Definition: mutt_curses.h:235
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
"To:" field
Definition: compose.c:111
"Cc:" field
Definition: compose.c:112
#define _(a)
Definition: message.h:28
"Subject:" field
Definition: compose.c:114
"From:" field
Definition: compose.c:110
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1083
struct Address * reply_to
Definition: envelope.h:40
static void draw_envelope_addr(int line, struct Address *addr)
Write addresses to the compose window.
Definition: compose.c:440
struct Envelope * env
envelope information
Definition: email.h:91
"X-Comment-To:" field
Definition: compose.c:125
struct Address * from
Definition: envelope.h:35
char * x_comment_to
Definition: envelope.h:56
struct Address * bcc
Definition: envelope.h:38
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int HeaderPadding[HDR_XCOMMENTTO+1]
Definition: compose.c:130
static const char *const Prompts[]
Definition: compose.c:136
#define W
Definition: compose.c:134
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
#define SETCOLOR(X)
Definition: mutt_curses.h:220
"Bcc:" field
Definition: compose.c:113
"Followup-To:" field
Definition: compose.c:124
char * subject
Definition: envelope.h:44
char * newsgroups
Definition: envelope.h:53
char * followup_to
Definition: envelope.h:55
Status bar.
Definition: mutt_curses.h:128
Position to start printing the attachments.
Definition: compose.c:127
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:205
"Newsgroups:" field
Definition: compose.c:123
static void redraw_crypt_lines(struct Email *msg)
Update the encryption info in the compose window.
Definition: compose.c:270
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
"Fcc:" (save folder) field
Definition: compose.c:116
#define WithCrypto
Definition: ncrypt.h:154
struct Address * cc
Definition: envelope.h:37
"Reply-To:" field
Definition: compose.c:115

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void edit_address_list ( int  line,
struct Address **  addr 
)
static

Let the user edit the address list.

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

Definition at line 520 of file compose.c.

521 {
522  char buf[HUGE_STRING] = ""; /* needs to be large for alias expansion */
523  char *err = NULL;
524 
525  mutt_addrlist_to_local(*addr);
526  mutt_addr_write(buf, sizeof(buf), *addr, false);
527  if (mutt_get_field(_(Prompts[line]), buf, sizeof(buf), MUTT_ALIAS) == 0)
528  {
529  mutt_addr_free(addr);
530  *addr = mutt_addr_parse_list2(*addr, buf);
531  *addr = mutt_expand_aliases(*addr);
532  }
533 
534  if (mutt_addrlist_to_intl(*addr, &err) != 0)
535  {
536  mutt_error(_("Bad IDN: '%s'"), err);
537  mutt_refresh();
538  FREE(&err);
539  }
540 
541  /* redraw the expanded list so the user can see the result */
542  buf[0] = 0;
543  mutt_addr_write(buf, sizeof(buf), *addr, true);
545  mutt_paddstr(W, buf);
546 }
struct Address * mutt_addr_parse_list2(struct Address *p, const char *s)
Parse a list of email addresses.
Definition: address.c:630
#define MUTT_ALIAS
do alias "completion" by calling up the alias-menu
Definition: mutt.h:58
#define _(a)
Definition: message.h:28
int mutt_addrlist_to_intl(struct Address *a, char **err)
Convert an Address list to Punycode.
Definition: address.c:1208
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1083
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1146
const char * line
Definition: common.c:35
#define HUGE_STRING
Definition: string2.h:37
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:99
int mutt_addrlist_to_local(struct Address *a)
Convert an Address list from Punycode.
Definition: address.c:1249
#define HDR_XOFFSET
Definition: compose.c:133
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
static const char *const Prompts[]
Definition: compose.c:136
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
#define W
Definition: compose.c:134
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
struct Address * mutt_expand_aliases(struct Address *a)
Expand aliases in a List of Addresses.
Definition: alias.c:296
#define mutt_error(...)
Definition: logging.h:88
#define FREE(x)
Definition: memory.h:46
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:446

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Delete an attachment.

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

Definition at line 555 of file compose.c.

556 {
557  struct AttachPtr **idx = actx->idx;
558  int rindex = actx->v2r[x];
559 
560  if (rindex == 0 && actx->idxlen == 1)
561  {
562  mutt_error(_("You may not delete the only attachment"));
563  idx[rindex]->content->tagged = false;
564  return -1;
565  }
566 
567  for (int y = 0; y < actx->idxlen; y++)
568  {
569  if (idx[y]->content->next == idx[rindex]->content)
570  {
571  idx[y]->content->next = idx[rindex]->content->next;
572  break;
573  }
574  }
575 
576  idx[rindex]->content->next = NULL;
577  idx[rindex]->content->parts = NULL;
578  mutt_body_free(&(idx[rindex]->content));
579  FREE(&idx[rindex]->tree);
580  FREE(&idx[rindex]);
581  for (; rindex < actx->idxlen - 1; rindex++)
582  idx[rindex] = idx[rindex + 1];
583  idx[actx->idxlen - 1] = NULL;
584  actx->idxlen--;
585 
586  return 0;
587 }
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:57
short idxlen
Definition: attach.h:55
char * tree
Definition: attach.h:39
bool tagged
Definition: body.h:74
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:58
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:56
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
#define FREE(x)
Definition: memory.h:46
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Generate the attachment list for the compose screen.

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

Definition at line 596 of file compose.c.

598 {
599  struct AttachPtr *new = NULL;
600 
601  for (; m; m = m->next)
602  {
603  if (m->type == TYPE_MULTIPART && m->parts &&
605  {
607  }
608  else
609  {
610  new = mutt_mem_calloc(1, sizeof(struct AttachPtr));
611  mutt_actx_add_attach(actx, new);
612  new->content = m;
613  m->aptr = new;
614  new->parent_type = parent_type;
615  new->level = level;
616 
617  /* We don't support multipart messages in the compose menu yet */
618  }
619  }
620 }
int mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:403
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
An email to which things will be attached.
Definition: attach.h:34
struct Body * next
next attachment in the list
Definition: body.h:57
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:596
int parent_type
Definition: attach.h:38
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:61
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:58
unsigned int type
content-type primary type
Definition: body.h:67
#define APPLICATION_PGP
Definition: ncrypt.h:129
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define WithCrypto
Definition: ncrypt.h:154
int level
Definition: attach.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Redraw the compose window.

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

Definition at line 628 of file compose.c.

629 {
630  if (init)
631  {
632  mutt_gen_compose_attach_list(actx, actx->email->content, -1, 0);
633  mutt_attach_init(actx);
634  menu->data = actx;
635  }
636 
637  mutt_update_tree(actx);
638 
639  menu->max = actx->vcount;
640  if (menu->max)
641  {
642  if (menu->current >= menu->max)
643  menu->current = menu->max - 1;
644  }
645  else
646  menu->current = 0;
647 
648  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
649 }
int redraw
when to redraw the screen
Definition: menu.h:63
struct Email * email
used by recvattach for updating
Definition: attach.h:51
struct Body * content
list of MIME parts
Definition: email.h:92
static void mutt_gen_compose_attach_list(struct AttachCtx *actx, struct Body *m, int parent_type, int level)
Generate the attachment list for the compose screen.
Definition: compose.c:596
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1236
int max
the number of entries in the menu
Definition: menu.h:62
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:143
void * data
extra data for the current menu
Definition: menu.h:60
int current
current entry
Definition: menu.h:61
short vcount
the number of virtual attachments
Definition: attach.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Add a new attchment to the message.

Parameters
menuCurrent menu
actxAttachment context
newAttachment to add

Definition at line 657 of file compose.c.

658 {
659  new->level = (actx->idxlen > 0) ? actx->idx[actx->idxlen - 1]->level : 0;
660  if (actx->idxlen)
661  actx->idx[actx->idxlen - 1]->content->next = new->content;
662  new->content->aptr = new;
663  mutt_actx_add_attach(actx, new);
664  mutt_update_compose_menu(actx, menu, false);
665  menu->current = actx->vcount - 1;
666 }
struct Content * content
structure used to store detailed info about the content of the attachment.
Definition: body.h:53
struct Body * next
next attachment in the list
Definition: body.h:57
short idxlen
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
static void mutt_update_compose_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
Definition: compose.c:628
struct Body * content
Definition: attach.h:36
int current
current entry
Definition: menu.h:61
int level
Definition: attach.h:40
struct AttachPtr ** idx
Definition: attach.h:54
short vcount
the number of virtual attachments
Definition: attach.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Compose the string for the status bar.

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

Definition at line 871 of file compose.c.

873 {
874  mutt_expando_format(buf, buflen, col, cols, src, compose_format_str,
875  (unsigned long) menu, 0);
876 }
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, enum FormatFlag flags)
Create the status bar string for compose mode - Implements format_t.
Definition: compose.c:813
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void compose_custom_redraw ( struct Menu menu)
static

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

Definition at line 683 of file compose.c.

684 {
685  struct ComposeRedrawData *rd = menu->redraw_data;
686 
687  if (!rd)
688  return;
689 
690  if (menu->redraw & REDRAW_FULL)
691  {
692  menu_redraw_full(menu);
693 
694  draw_envelope(rd->msg, rd->fcc);
695  menu->offset = HDR_ATTACH;
697  }
698 
699  menu_check_recenter(menu);
700 
701  if (menu->redraw & REDRAW_STATUS)
702  {
703  char buf[LONG_STRING];
704  compose_status_line(buf, sizeof(buf), 0, MuttStatusWindow->cols, menu,
709  NORMAL_COLOR;
710  menu->redraw &= ~REDRAW_STATUS;
711  }
712 
713 #ifdef USE_SIDEBAR
714  if (menu->redraw & REDRAW_SIDEBAR)
715  menu_redraw_sidebar(menu);
716 #endif
717 
718  if (menu->redraw & REDRAW_INDEX)
719  menu_redraw_index(menu);
720  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH))
721  menu_redraw_motion(menu);
722  else if (menu->redraw == REDRAW_CURRENT)
723  menu_redraw_current(menu);
724 }
#define NONULL(x)
Definition: string2.h:39
int redraw
when to redraw the screen
Definition: menu.h:63
struct MuttWindow * MuttStatusWindow
Status Window.
Definition: mutt_window.c:40
#define NORMAL_COLOR
Definition: mutt_curses.h:235
struct Email * msg
Definition: compose.c:673
#define LONG_STRING
Definition: string2.h:36
static void draw_envelope(struct Email *msg, char *fcc)
Write the email headers to the compose window.
Definition: compose.c:458
void mutt_paddstr(int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:1083
void * redraw_data
Definition: menu.h:126
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:871
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
int pagelen
number of entries per screen
Definition: menu.h:66
char * ComposeFormat
Config: printf-like format string for the Compose panel&#39;s status bar.
Definition: compose.c:88
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:162
#define SETCOLOR(X)
Definition: mutt_curses.h:220
int offset
row offset within the window to start the index
Definition: menu.h:65
Status bar.
Definition: mutt_curses.h:128
Position to start printing the attachments.
Definition: compose.c:127
Keep track when the compose screen needs redrawing.
Definition: compose.c:671

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Swap two adjacent entries in the attachment list.

Parameters
msgBody of email
idxArray of Attachments
firstIndex of first attachment to swap

Definition at line 732 of file compose.c.

733 {
734  /* Reorder Body pointers.
735  * Must traverse msg from top since Body has no previous ptr.
736  */
737  for (struct Body *part = msg; part; part = part->next)
738  {
739  if (part->next == idx[first]->content)
740  {
741  idx[first]->content->next = idx[first + 1]->content->next;
742  idx[first + 1]->content->next = idx[first]->content;
743  part->next = idx[first + 1]->content;
744  break;
745  }
746  }
747 
748  /* Reorder index */
749  struct AttachPtr *saved = idx[first];
750  idx[first] = idx[first + 1];
751  idx[first + 1] = saved;
752 
753  /* Swap ptr->num */
754  int i = idx[first]->num;
755  idx[first]->num = idx[first + 1]->num;
756  idx[first + 1]->num = i;
757 }
An email to which things will be attached.
Definition: attach.h:34
struct Body * next
next attachment in the list
Definition: body.h:57
The body of an email.
Definition: body.h:33
int num
Definition: attach.h:41
struct Body * content
Definition: attach.h:36

+ Here is the caller graph for this function:

static unsigned long cum_attachs_size ( struct Menu menu)
static

Cumulative Attachments Size.

Parameters
menuMenu listing attachments
Return values
numBytes in attachments

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

Definition at line 767 of file compose.c.

768 {
769  size_t s = 0;
770  struct AttachCtx *actx = menu->data;
771  struct AttachPtr **idx = actx->idx;
772  struct Content *info = NULL;
773  struct Body *b = NULL;
774 
775  for (unsigned short i = 0; i < actx->idxlen; i++)
776  {
777  b = idx[i]->content;
778 
779  if (!b->content)
781 
782  info = b->content;
783  if (info)
784  {
785  switch (b->encoding)
786  {
788  s += 3 * (info->lobin + info->hibin) + info->ascii + info->crlf;
789  break;
790  case ENC_BASE64:
791  s += (4 * (info->lobin + info->hibin + info->ascii + info->crlf)) / 3;
792  break;
793  default:
794  s += info->lobin + info->hibin + info->ascii + info->crlf;
795  break;
796  }
797  }
798  }
799 
800  return s;
801 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
An email to which things will be attached.
Definition: attach.h:34
struct Content * content
structure used to store detailed info about the content of the attachment.
Definition: body.h:53
short idxlen
Definition: attach.h:55
long hibin
8-bit characters
Definition: content.h:35
The body of an email.
Definition: body.h:33
struct Content * mutt_get_content_info(const char *fname, struct Body *b)
Analyze file to determine MIME encoding to use.
Definition: sendlib.c:979
unsigned int encoding
content-transfer-encoding
Definition: body.h:68
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
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: menu.h:60
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* compose_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
unsigned long  data,
enum FormatFlag  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 813 of file compose.c.

817 {
818  char fmt[SHORT_STRING], tmp[SHORT_STRING];
819  int optional = (flags & MUTT_FORMAT_OPTIONAL);
820  struct Menu *menu = (struct Menu *) data;
821 
822  *buf = 0;
823  switch (op)
824  {
825  case 'a': /* total number of attachments */
826  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
827  snprintf(buf, buflen, fmt, menu->max);
828  break;
829 
830  case 'h': /* hostname */
831  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
832  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
833  break;
834 
835  case 'l': /* approx length of current message in bytes */
836  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
837  mutt_str_pretty_size(tmp, sizeof(tmp), menu ? cum_attachs_size(menu) : 0);
838  snprintf(buf, buflen, fmt, tmp);
839  break;
840 
841  case 'v':
842  snprintf(buf, buflen, "%s", mutt_make_version());
843  break;
844 
845  case 0:
846  *buf = 0;
847  return src;
848 
849  default:
850  snprintf(buf, buflen, "%%%s%c", prec, op);
851  break;
852  }
853 
854  if (optional)
855  compose_status_line(buf, buflen, col, cols, menu, if_str);
856  else if (flags & MUTT_FORMAT_OPTIONAL)
857  compose_status_line(buf, buflen, col, cols, menu, else_str);
858 
859  return src;
860 }
#define NONULL(x)
Definition: string2.h:39
#define SHORT_STRING
Definition: string2.h:34
GUI selectable list of items.
Definition: menu.h:56
int menu
menu definition for keymap entries.
Definition: menu.h:64
allow optional field processing
Definition: format_flags.h:36
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:871
int max
the number of entries in the menu
Definition: menu.h:62
static unsigned long cum_attachs_size(struct Menu *menu)
Cumulative Attachments Size.
Definition: compose.c:767
WHERE char * ShortHostname
Short version of the hostname.
Definition: globals.h:48
void * data
extra data for the current menu
Definition: menu.h:60
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1015
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1492

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_compose_menu ( struct Email msg,
char *  fcc,
size_t  fcclen,
struct Email cur,
int  flags 
)

Allow the user to edit the message envelope.

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

Definition at line 889 of file compose.c.

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

+ Here is the caller graph for this function:

Variable Documentation

char* ComposeFormat

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

Definition at line 88 of file compose.c.

char* Ispell

Config: External command to perform spell-checking.

Definition at line 89 of file compose.c.

unsigned char Postpone

Config: Save messages to the Postponed folder.

Definition at line 90 of file compose.c.

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

Definition at line 92 of file compose.c.

int HeaderPadding[HDR_XCOMMENTTO+1] = { 0 }

Definition at line 130 of file compose.c.

int MaxHeaderWidth = 0

Definition at line 131 of file compose.c.

const char* const Prompts[]
static

Definition at line 136 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.