NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
commands.c File Reference

Manage where the email is piped to external commands. More...

#include "config.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "commands.h"
#include "menu/lib.h"
#include "ncrypt/lib.h"
#include "pager/lib.h"
#include "progress/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "attachments.h"
#include "browser.h"
#include "context.h"
#include "copy.h"
#include "format_flags.h"
#include "hdrline.h"
#include "hook.h"
#include "icommands.h"
#include "init.h"
#include "keymap.h"
#include "mutt_commands.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "mutt_thread.h"
#include "muttlib.h"
#include "mx.h"
#include "options.h"
#include "protos.h"
#include "imap/lib.h"
#include "notmuch/lib.h"
#include <libintl.h>
#include "autocrypt/lib.h"
+ Include dependency graph for commands.c:

Go to the source code of this file.

Macros

#define EXTRA_SPACE   (15 + 7 + 2)
 

Functions

void mutt_commands_cleanup (void)
 Clean up commands globals. More...
 
static void process_protected_headers (struct Mailbox *m, struct Email *e)
 Get the protected header and update the index. More...
 
int mutt_display_message (struct MuttWindow *win_index, struct MuttWindow *win_ibar, struct MuttWindow *win_pager, struct MuttWindow *win_pbar, struct Mailbox *m, struct Email *e)
 Display a message in the pager. More...
 
void ci_bounce_message (struct Mailbox *m, struct EmailList *el)
 Bounce an email. More...
 
static void pipe_set_flags (bool decode, bool print, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
 Generate flags for copy header/message. More...
 
static void pipe_msg (struct Mailbox *m, struct Email *e, struct Message *msg, FILE *fp, bool decode, bool print)
 Pipe a message. More...
 
static int pipe_message (struct Mailbox *m, struct EmailList *el, const char *cmd, bool decode, bool print, bool split, const char *sep)
 Pipe message to a command. More...
 
void mutt_pipe_message (struct Mailbox *m, struct EmailList *el)
 Pipe a message. More...
 
void mutt_print_message (struct Mailbox *m, struct EmailList *el)
 Print a message. More...
 
bool mutt_select_sort (bool reverse)
 Ask the user for a sort method. More...
 
bool mutt_shell_escape (void)
 invoke a command in a subshell More...
 
void mutt_enter_command (void)
 enter a neomutt command More...
 
void mutt_display_address (struct Envelope *env)
 Display the address of a message. More...
 
static void set_copy_flags (struct Email *e, enum MessageTransformOpt transform_opt, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
 Set the flags for a message copy. More...
 
int mutt_save_message_ctx (struct Mailbox *m_src, struct Email *e, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt, struct Mailbox *m_dst)
 Save a message to a given mailbox. More...
 
int mutt_save_message (struct Mailbox *m, struct EmailList *el, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt)
 Save an email. More...
 
bool mutt_edit_content_type (struct Email *e, struct Body *b, FILE *fp)
 Edit the content type of an attachment. More...
 
static bool check_traditional_pgp (struct Mailbox *m, struct Email *e)
 Check for an inline PGP content. More...
 
bool mutt_check_traditional_pgp (struct Mailbox *m, struct EmailList *el)
 Check if a message has inline PGP content. More...
 
void mutt_check_stats (struct Mailbox *m)
 Forcibly update mailbox stats. More...
 

Variables

static const char * ExtPagerProgress = "all"
 
static struct Buffer LastSaveFolder = { 0 }
 The folder the user last saved to. More...
 

Detailed Description

Manage where the email is piped to external commands.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • Pietro Cerutti

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

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

Definition in file commands.c.

Macro Definition Documentation

◆ EXTRA_SPACE

#define EXTRA_SPACE   (15 + 7 + 2)

Function Documentation

◆ mutt_commands_cleanup()

void mutt_commands_cleanup ( void  )

Clean up commands globals.

Definition at line 95 of file commands.c.

96 {
98 }
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
static struct Buffer LastSaveFolder
The folder the user last saved to.
Definition: commands.c:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_protected_headers()

static void process_protected_headers ( struct Mailbox m,
struct Email e 
)
static

Get the protected header and update the index.

Parameters
mMailbox
eEmail to update

Definition at line 105 of file commands.c.

106 {
107  struct Envelope *prot_headers = NULL;
108  regmatch_t pmatch[1];
109 
110  const bool c_crypt_protected_headers_read =
111  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
112 #ifdef USE_AUTOCRYPT
113  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
114  if (!c_crypt_protected_headers_read && !c_autocrypt)
115  return;
116 #else
117  if (!c_crypt_protected_headers_read)
118  return;
119 #endif
120 
121  /* Grab protected headers to update in the index */
122  if (e->security & SEC_SIGN)
123  {
124  /* Don't update on a bad signature.
125  *
126  * This is a simplification. It's possible the headers are in the
127  * encrypted part of a nested encrypt/signed. But properly handling that
128  * case would require more complexity in the decryption handlers, which
129  * I'm not sure is worth it. */
130  if (!(e->security & SEC_GOODSIGN))
131  return;
132 
133  if (mutt_is_multipart_signed(e->body) && e->body->parts)
134  {
135  prot_headers = e->body->parts->mime_headers;
136  }
137  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
138  {
139  prot_headers = e->body->mime_headers;
140  }
141  }
142  if (!prot_headers && (e->security & SEC_ENCRYPT))
143  {
144  if (((WithCrypto & APPLICATION_PGP) != 0) &&
147  {
148  prot_headers = e->body->mime_headers;
149  }
150  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
151  {
152  prot_headers = e->body->mime_headers;
153  }
154  }
155 
156  /* Update protected headers in the index and header cache. */
157  if (c_crypt_protected_headers_read && prot_headers && prot_headers->subject &&
158  !mutt_str_equal(e->env->subject, prot_headers->subject))
159  {
160  if (m->subj_hash && e->env->real_subj)
162 
163  mutt_str_replace(&e->env->subject, prot_headers->subject);
164  FREE(&e->env->disp_subj);
165  const struct Regex *c_reply_regex =
166  cs_subset_regex(NeoMutt->sub, "reply_regex");
167  if (mutt_regex_capture(c_reply_regex, e->env->subject, 1, pmatch))
168  e->env->real_subj = e->env->subject + pmatch[0].rm_eo;
169  else
170  e->env->real_subj = e->env->subject;
171 
172  if (m->subj_hash)
174 
175  mx_save_hcache(m, e);
176 
177  /* Also persist back to the message headers if this is set */
178  const bool c_crypt_protected_headers_save =
179  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_save");
180  if (c_crypt_protected_headers_save)
181  {
183  e->changed = true;
184  m->changed = true;
185  }
186  }
187 
188 #ifdef USE_AUTOCRYPT
189  if (c_autocrypt && (e->security & SEC_ENCRYPT) && prot_headers && prot_headers->autocrypt_gossip)
190  {
191  mutt_autocrypt_process_gossip_header(m, e, prot_headers);
192  }
193 #endif
194 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define WithCrypto
Definition: lib.h:113
struct Body * body
List of MIME parts.
Definition: email.h:91
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
int mutt_autocrypt_process_gossip_header(struct Mailbox *m, struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:419
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:68
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:623
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:484
char * real_subj
Offset of the real subject.
Definition: envelope.h:67
bool changed
Email has been edited.
Definition: email.h:48
int mx_save_hcache(struct Mailbox *m, struct Email *e)
Save message to the header cache - Wrapper for MxOps::msg_save_hcache()
Definition: mx.c:1806
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:35
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
struct Envelope * env
Envelope information.
Definition: email.h:90
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:420
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:128
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:521
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
match a regex against a string, with provided options
Definition: regex.c:596
#define SEC_SIGN
Email is signed.
Definition: lib.h:76
char * subject
Email&#39;s subject.
Definition: envelope.h:66
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
Cached regular expression.
Definition: regex3.h:89
#define FREE(x)
Definition: memory.h:40
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:77
The header of an Email.
Definition: envelope.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_display_message()

int mutt_display_message ( struct MuttWindow win_index,
struct MuttWindow win_ibar,
struct MuttWindow win_pager,
struct MuttWindow win_pbar,
struct Mailbox m,
struct Email e 
)

Display a message in the pager.

Parameters
win_indexIndex Window
win_ibarIndex Bar Window
win_pagerPager Window
win_pbarPager Bar Window
mMailbox
eEmail to display
Return values
0Success
-1Error

Definition at line 207 of file commands.c.

210 {
211  int rc = 0;
212  bool builtin = false;
214  CopyHeaderFlags chflags;
215  pid_t filterpid = -1;
216  struct Buffer *tempfile = NULL;
217  int res;
218 
219  struct Message *msg = mx_msg_open(m, e->msgno);
220  if (!msg)
221  {
222  return -1;
223  }
224 
225  mutt_parse_mime_message(m, e, msg->fp);
227 
228  char columns[16];
229  // win_pager might not be visible and have a size yet, so use win_index
230  snprintf(columns, sizeof(columns), "%d", win_index->state.cols);
231  mutt_envlist_set("COLUMNS", columns, true);
232 
233  /* see if crypto is needed for this message. if so, we should exit curses */
234  if ((WithCrypto != 0) && e->security)
235  {
236  if (e->security & SEC_ENCRYPT)
237  {
238  if (e->security & APPLICATION_SMIME)
241  goto cleanup;
242 
243  cmflags |= MUTT_CM_VERIFY;
244  }
245  else if (e->security & SEC_SIGN)
246  {
247  /* find out whether or not the verify signature */
248  /* L10N: Used for the $crypt_verify_sig prompt */
249  const enum QuadOption c_crypt_verify_sig =
250  cs_subset_quad(NeoMutt->sub, "crypt_verify_sig");
251  if (query_quadoption(c_crypt_verify_sig, _("Verify signature?")) == MUTT_YES)
252  {
253  cmflags |= MUTT_CM_VERIFY;
254  }
255  }
256  }
257 
258  if (cmflags & MUTT_CM_VERIFY || e->security & SEC_ENCRYPT)
259  {
260  if (e->security & APPLICATION_PGP)
261  {
262  if (!TAILQ_EMPTY(&e->env->from))
264 
266  }
267 
268  if (e->security & APPLICATION_SMIME)
270  }
271 
272  FILE *fp_filter_out = NULL;
273  tempfile = mutt_buffer_pool_get();
274  mutt_buffer_mktemp(tempfile);
275  FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfile), "w");
276  if (!fp_out)
277  {
278  mutt_error(_("Could not create temporary file"));
279  goto cleanup;
280  }
281 
282  const char *const c_display_filter =
283  cs_subset_string(NeoMutt->sub, "display_filter");
284  if (c_display_filter)
285  {
286  fp_filter_out = fp_out;
287  fp_out = NULL;
288  filterpid = filter_create_fd(c_display_filter, &fp_out, NULL, NULL, -1,
289  fileno(fp_filter_out), -1);
290  if (filterpid < 0)
291  {
292  mutt_error(_("Can't create display filter"));
293  mutt_file_fclose(&fp_filter_out);
294  unlink(mutt_buffer_string(tempfile));
295  goto cleanup;
296  }
297  }
298 
299  const char *const c_pager = cs_subset_string(NeoMutt->sub, "pager");
300  if (!c_pager || mutt_str_equal(c_pager, "builtin"))
301  builtin = true;
302  else
303  {
304  char buf[1024] = { 0 };
305  const char *const c_pager_format =
306  cs_subset_string(NeoMutt->sub, "pager_format");
307  mutt_make_string(buf, sizeof(buf), win_index->state.cols, NONULL(c_pager_format),
308  m, Context ? Context->msg_in_pager : -1, e,
310  fputs(buf, fp_out);
311  fputs("\n\n", fp_out);
312  }
313 
314  const bool c_weed = cs_subset_bool(NeoMutt->sub, "weed");
315  chflags = (c_weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) | CH_DECODE | CH_FROM | CH_DISPLAY;
316 #ifdef USE_NOTMUCH
317  if (m->type == MUTT_NOTMUCH)
318  chflags |= CH_VIRTUAL;
319 #endif
320  res = mutt_copy_message(fp_out, m, e, msg, cmflags, chflags, win_index->state.cols);
321 
322  if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (res < 0))
323  {
324  mutt_error(_("Could not copy message"));
325  if (fp_filter_out)
326  {
327  filter_wait(filterpid);
328  mutt_file_fclose(&fp_filter_out);
329  }
331  goto cleanup;
332  }
333 
334  if (fp_filter_out && (filter_wait(filterpid) != 0))
336 
337  mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
338 
339  if (WithCrypto)
340  {
341  /* update crypto information for this message */
342  e->security &= ~(SEC_GOODSIGN | SEC_BADSIGN);
343  e->security |= crypt_query(e->body);
344 
345  /* Remove color cache for this message, in case there
346  * are color patterns for both ~g and ~V */
347  e->pair = 0;
348 
349  /* Process protected headers and autocrypt gossip headers */
351  }
352 
353  if (builtin)
354  {
355  if ((WithCrypto != 0) && (e->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
356  {
357  if (e->security & SEC_GOODSIGN)
358  {
359  if (crypt_smime_verify_sender(m, e, msg) == 0)
360  mutt_message(_("S/MIME signature successfully verified"));
361  else
362  mutt_error(_("S/MIME certificate owner does not match sender"));
363  }
364  else if (e->security & SEC_PARTSIGN)
365  mutt_message(_("Warning: Part of this message has not been signed"));
366  else if (e->security & SEC_SIGN || e->security & SEC_BADSIGN)
367  mutt_error(_("S/MIME signature could NOT be verified"));
368  }
369 
370  if ((WithCrypto != 0) && (e->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
371  {
372  if (e->security & SEC_GOODSIGN)
373  mutt_message(_("PGP signature successfully verified"));
374  else if (e->security & SEC_PARTSIGN)
375  mutt_message(_("Warning: Part of this message has not been signed"));
376  else if (e->security & SEC_SIGN)
377  mutt_message(_("PGP signature could NOT be verified"));
378  }
379 
380  /* Invoke the builtin pager */
381  struct PagerData pdata = { 0 };
382  struct PagerView pview = { &pdata };
383 
384  pdata.fp = msg->fp;
385  pdata.fname = mutt_buffer_string(tempfile);
386 
387  pview.mode = PAGER_MODE_EMAIL;
388  pview.banner = NULL;
389  pview.flags = MUTT_PAGER_MESSAGE | (e->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
390  pview.win_ibar = win_ibar;
391  pview.win_index = win_index;
392  pview.win_pbar = win_pbar;
393  pview.win_pager = win_pager;
394  rc = mutt_pager(&pview);
395  }
396  else
397  {
398  mutt_endwin();
399 
400  struct Buffer *cmd = mutt_buffer_pool_get();
401  mutt_buffer_printf(cmd, "%s %s", NONULL(c_pager), mutt_buffer_string(tempfile));
402  int r = mutt_system(mutt_buffer_string(cmd));
403  if (r == -1)
404  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
405  unlink(mutt_buffer_string(tempfile));
407 
408  if (!OptNoCurses)
409  keypad(stdscr, true);
410  if (r != -1)
411  mutt_set_flag(m, e, MUTT_READ, true);
412  const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
413  if ((r != -1) && c_prompt_after)
414  {
415  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
416  rc = km_dokey(MENU_PAGER);
417  }
418  else
419  rc = 0;
420  }
421 
422 cleanup:
423  mx_msg_close(m, &msg);
424  mutt_envlist_unset("COLUMNS");
425  mutt_buffer_pool_release(&tempfile);
426  return rc;
427 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
The "current" mailbox.
Definition: context.h:37
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define WithCrypto
Definition: lib.h:113
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:43
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:723
int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e, struct Message *msg)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:472
struct Body * body
List of MIME parts.
Definition: email.h:91
#define mutt_error(...)
Definition: logging.h:88
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
Paged view into some data.
Definition: lib.h:154
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:583
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
#define _(a)
Definition: message.h:28
static const char * ExtPagerProgress
Definition: commands.c:87
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:47
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:46
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:32
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
struct MuttWindow * win_index
Definition: lib.h:162
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int mutt_pager(struct PagerView *pview)
Display an email, attachment, or help, in a window.
Definition: dlg_pager.c:2360
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
Pager pager (email viewer)
Definition: type.h:54
Data to be displayed by PagerView.
Definition: lib.h:143
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:39
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
#define CH_WEED
Weed the headers?
Definition: copy.h:53
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1409
struct Envelope * env
Envelope information.
Definition: email.h:90
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:73
#define MUTT_PAGER_MESSAGE
Definition: lib.h:70
static void process_protected_headers(struct Mailbox *m, struct Email *e)
Get the protected header and update the index.
Definition: commands.c:105
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
bool nowrap
Do not wrap the output in the pager.
Definition: body.h:74
enum PagerMode mode
Pager mode.
Definition: lib.h:157
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:158
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:131
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
A local copy of an email.
Definition: mxapi.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:422
bool mutt_envlist_unset(const char *name)
Unset an environment variable.
Definition: envlist.c:132
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:51
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:59
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:463
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:279
#define CH_DISPLAY
Display result to user.
Definition: copy.h:70
Messages that have been read.
Definition: mutt.h:92
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
PagerFlags flags
Additional settings to tweak pager&#39;s function.
Definition: lib.h:158
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:47
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:78
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
#define SEC_SIGN
Email is signed.
Definition: lib.h:76
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:455
FILE * fp
Source stream.
Definition: lib.h:146
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:50
FILE * fp
pointer to the message data
Definition: mxapi.h:43
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:698
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:853
#define mutt_message(...)
Definition: logging.h:87
struct MuttWindow * win_pager
Definition: lib.h:164
struct MuttWindow * win_pbar
Definition: lib.h:163
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:67
struct MuttWindow * win_ibar
Definition: lib.h:161
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:598
const char * fname
Name of the file to read.
Definition: lib.h:148
#define TAILQ_EMPTY(head)
Definition: queue.h:721
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:635
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
const char * banner
Title to display in status bar.
Definition: lib.h:159
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:77
int pair
Color-pair to use when displaying in the index.
Definition: email.h:80
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:79
int msgno
Number displayed to the user.
Definition: email.h:87
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ci_bounce_message()

void ci_bounce_message ( struct Mailbox m,
struct EmailList *  el 
)

Bounce an email.

Parameters
mMailbox
elList of Emails to bounce

Definition at line 434 of file commands.c.

435 {
436  if (!m || !el || STAILQ_EMPTY(el))
437  return;
438 
439  char prompt[8193];
440  char scratch[8192];
441  char buf[8192] = { 0 };
442  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
443  char *err = NULL;
444  int rc;
445  int msg_count = 0;
446 
447  struct EmailNode *en = NULL;
448  STAILQ_FOREACH(en, el, entries)
449  {
450  /* RFC5322 mandates a From: header,
451  * so warn before bouncing messages without one */
452  if (TAILQ_EMPTY(&en->email->env->from))
453  mutt_error(_("Warning: message contains no From: header"));
454 
455  msg_count++;
456  }
457 
458  if (msg_count == 1)
459  mutt_str_copy(prompt, _("Bounce message to: "), sizeof(prompt));
460  else
461  mutt_str_copy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
462 
463  rc = mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS, false, NULL, NULL);
464  if (rc || (buf[0] == '\0'))
465  return;
466 
467  mutt_addrlist_parse2(&al, buf);
468  if (TAILQ_EMPTY(&al))
469  {
470  mutt_error(_("Error parsing address"));
471  return;
472  }
473 
474  mutt_expand_aliases(&al);
475 
476  if (mutt_addrlist_to_intl(&al, &err) < 0)
477  {
478  mutt_error(_("Bad IDN: '%s'"), err);
479  FREE(&err);
480  mutt_addrlist_clear(&al);
481  return;
482  }
483 
484  buf[0] = '\0';
485  mutt_addrlist_write(&al, buf, sizeof(buf), true);
486 
487 #define EXTRA_SPACE (15 + 7 + 2)
488  snprintf(scratch, sizeof(scratch),
489  ngettext("Bounce message to %s?", "Bounce messages to %s?", msg_count), buf);
490 
491  const size_t width = msgwin_get_width();
492  if (mutt_strwidth(scratch) > (width - EXTRA_SPACE))
493  {
494  mutt_simple_format(prompt, sizeof(prompt), 0, width - EXTRA_SPACE,
495  JUSTIFY_LEFT, 0, scratch, sizeof(scratch), false);
496  mutt_str_cat(prompt, sizeof(prompt), "...?");
497  }
498  else
499  mutt_str_copy(prompt, scratch, sizeof(prompt));
500 
501  const enum QuadOption c_bounce = cs_subset_quad(NeoMutt->sub, "bounce");
502  if (query_quadoption(c_bounce, prompt) != MUTT_YES)
503  {
504  mutt_addrlist_clear(&al);
506  mutt_message(ngettext("Message not bounced", "Messages not bounced", msg_count));
507  return;
508  }
509 
511 
512  struct Message *msg = NULL;
513  STAILQ_FOREACH(en, el, entries)
514  {
515  msg = mx_msg_open(m, en->email->msgno);
516  if (!msg)
517  {
518  rc = -1;
519  break;
520  }
521 
522  rc = mutt_bounce_message(msg->fp, m, en->email, &al, NeoMutt->sub);
523  mx_msg_close(m, &msg);
524 
525  if (rc < 0)
526  break;
527  }
528 
529  mutt_addrlist_clear(&al);
530  /* If no error, or background, display message. */
531  if ((rc == 0) || (rc == S_BKG))
532  mutt_message(ngettext("Message bounced", "Messages bounced", msg_count));
533 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:300
Left justify the text.
Definition: curs_lib.h:43
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:53
#define mutt_error(...)
Definition: logging.h:88
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
size_t msgwin_get_width(void)
Get the width of the Message Window.
Definition: msgwin.c:262
#define _(a)
Definition: message.h:28
#define S_BKG
Definition: string2.h:42
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:242
Container for Accounts, Notifications.
Definition: neomutt.h:36
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
int mutt_bounce_message(FILE *fp, struct Mailbox *m, struct Email *e, struct AddressList *to, struct ConfigSubset *sub)
Bounce an email message.
Definition: sendlib.c:1379
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct Envelope * env
Envelope information.
Definition: email.h:90
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
A local copy of an email.
Definition: mxapi.h:41
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:983
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct Email * email
Email in the list.
Definition: email.h:131
FILE * fp
pointer to the message data
Definition: mxapi.h:43
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
#define STAILQ_EMPTY(head)
Definition: queue.h:348
List of Emails.
Definition: email.h:129
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define EXTRA_SPACE
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:716
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pipe_set_flags()

static void pipe_set_flags ( bool  decode,
bool  print,
CopyMessageFlags cmflags,
CopyHeaderFlags chflags 
)
static

Generate flags for copy header/message.

Parameters
[in]decodeIf true decode the message
[in]printIf true, mark the message for printing
[out]cmflagsFlags, see CopyMessageFlags
[out]chflagsFlags, see CopyHeaderFlags

Definition at line 542 of file commands.c.

544 {
545  if (decode)
546  {
547  *chflags |= CH_DECODE | CH_REORDER;
548  *cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
549 
550  const bool c_print_decode_weed =
551  cs_subset_bool(NeoMutt->sub, "print_decode_weed");
552  const bool c_pipe_decode_weed =
553  cs_subset_bool(NeoMutt->sub, "pipe_decode_weed");
554  if (print ? c_print_decode_weed : c_pipe_decode_weed)
555  {
556  *chflags |= CH_WEED;
557  *cmflags |= MUTT_CM_WEED;
558  }
559 
560  /* Just as with copy-decode, we need to update the mime fields to avoid
561  * confusing programs that may process the email. However, we don't want
562  * to force those fields to appear in printouts. */
563  if (!print)
564  *chflags |= CH_MIME | CH_TXTPLAIN;
565  }
566 
567  if (print)
568  *cmflags |= MUTT_CM_PRINTING;
569 }
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:61
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:41
#define MUTT_CM_PRINTING
Printing the message - display light.
Definition: copy.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CH_WEED
Weed the headers?
Definition: copy.h:53
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:63
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:59
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pipe_msg()

static void pipe_msg ( struct Mailbox m,
struct Email e,
struct Message msg,
FILE *  fp,
bool  decode,
bool  print 
)
static

Pipe a message.

Parameters
mMailbox
eEmail to pipe
msgMessage
fpFile to write to
decodeIf true, decode the message
printIf true, message is for printing

Definition at line 580 of file commands.c.

582 {
584  CopyHeaderFlags chflags = CH_FROM;
585 
586  pipe_set_flags(decode, print, &cmflags, &chflags);
587 
588  if ((WithCrypto != 0) && decode && e->security & SEC_ENCRYPT)
589  {
591  return;
592  endwin();
593  }
594 
595  const bool own_msg = !msg;
596  if (own_msg)
597  {
598  msg = mx_msg_open(m, e->msgno);
599  if (!msg)
600  {
601  return;
602  }
603  }
604 
605  if (decode)
606  {
607  mutt_parse_mime_message(m, e, msg->fp);
608  }
609 
610  mutt_copy_message(fp, m, e, msg, cmflags, chflags, 0);
611 
612  if (own_msg)
613  {
614  mx_msg_close(m, &msg);
615  }
616 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
#define WithCrypto
Definition: lib.h:113
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:32
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:50
FILE * fp
pointer to the message data
Definition: mxapi.h:43
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:853
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
static void pipe_set_flags(bool decode, bool print, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Generate flags for copy header/message.
Definition: commands.c:542
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pipe_message()

static int pipe_message ( struct Mailbox m,
struct EmailList *  el,
const char *  cmd,
bool  decode,
bool  print,
bool  split,
const char *  sep 
)
static

Pipe message to a command.

Parameters
mMailbox
elList of Emails to pipe
cmdCommand to pipe to
decodeShould the message be decrypted
printTrue if this is a print job
splitShould a separator be sent between messages?
sepSeparator string
Return values
0Success
1Error

The following code is shared between printing and piping.

Definition at line 632 of file commands.c.

634 {
635  if (!m || !el)
636  return 1;
637 
638  struct EmailNode *en = STAILQ_FIRST(el);
639  if (!en)
640  return 1;
641 
642  int rc = 0;
643  pid_t pid;
644  FILE *fp_out = NULL;
645 
646  if (!STAILQ_NEXT(en, entries))
647  {
648  /* handle a single message */
650 
651  struct Message *msg = mx_msg_open(m, en->email->msgno);
652  if (msg && WithCrypto && decode)
653  {
654  mutt_parse_mime_message(m, en->email, msg->fp);
655  if ((en->email->security & SEC_ENCRYPT) &&
657  {
658  mx_msg_close(m, &msg);
659  return 1;
660  }
661  }
662  mutt_endwin();
663 
664  pid = filter_create(cmd, &fp_out, NULL, NULL);
665  if (pid < 0)
666  {
667  mutt_perror(_("Can't create filter process"));
668  mx_msg_close(m, &msg);
669  return 1;
670  }
671 
672  OptKeepQuiet = true;
673  pipe_msg(m, en->email, msg, fp_out, decode, print);
674  mx_msg_close(m, &msg);
675  mutt_file_fclose(&fp_out);
676  rc = filter_wait(pid);
677  OptKeepQuiet = false;
678  }
679  else
680  {
681  /* handle tagged messages */
682  if ((WithCrypto != 0) && decode)
683  {
684  STAILQ_FOREACH(en, el, entries)
685  {
686  struct Message *msg = mx_msg_open(m, en->email->msgno);
687  if (msg)
688  {
689  mutt_parse_mime_message(m, en->email, msg->fp);
691  mx_msg_close(m, &msg);
692  }
693  if ((en->email->security & SEC_ENCRYPT) &&
695  {
696  return 1;
697  }
698  }
699  }
700 
701  if (split)
702  {
703  STAILQ_FOREACH(en, el, entries)
704  {
706  mutt_endwin();
707  pid = filter_create(cmd, &fp_out, NULL, NULL);
708  if (pid < 0)
709  {
710  mutt_perror(_("Can't create filter process"));
711  return 1;
712  }
713  OptKeepQuiet = true;
714  pipe_msg(m, en->email, NULL, fp_out, decode, print);
715  /* add the message separator */
716  if (sep)
717  fputs(sep, fp_out);
718  mutt_file_fclose(&fp_out);
719  if (filter_wait(pid) != 0)
720  rc = 1;
721  OptKeepQuiet = false;
722  }
723  }
724  else
725  {
726  mutt_endwin();
727  pid = filter_create(cmd, &fp_out, NULL, NULL);
728  if (pid < 0)
729  {
730  mutt_perror(_("Can't create filter process"));
731  return 1;
732  }
733  OptKeepQuiet = true;
734  STAILQ_FOREACH(en, el, entries)
735  {
737  pipe_msg(m, en->email, NULL, fp_out, decode, print);
738  /* add the message separator */
739  if (sep)
740  fputs(sep, fp_out);
741  }
742  mutt_file_fclose(&fp_out);
743  if (filter_wait(pid) != 0)
744  rc = 1;
745  OptKeepQuiet = false;
746  }
747  }
748 
749  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
750  if ((rc != 0) || c_wait_key)
752  return rc;
753 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
#define WithCrypto
Definition: lib.h:113
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
#define _(a)
Definition: message.h:28
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:46
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
static void pipe_msg(struct Mailbox *m, struct Email *e, struct Message *msg, FILE *fp, bool decode, bool print)
Pipe a message.
Definition: commands.c:580
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
A local copy of an email.
Definition: mxapi.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:422
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_NEXT(elm, field)
Definition: queue.h:400
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:455
struct Email * email
Email in the list.
Definition: email.h:131
FILE * fp
pointer to the message data
Definition: mxapi.h:43
List of Emails.
Definition: email.h:129
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:598
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:38
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
#define STAILQ_FIRST(head)
Definition: queue.h:350
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pipe_message()

void mutt_pipe_message ( struct Mailbox m,
struct EmailList *  el 
)

Pipe a message.

Parameters
mMailbox
elList of Emails to pipe

Definition at line 760 of file commands.c.

761 {
762  if (!m || !el)
763  return;
764 
765  struct Buffer *buf = mutt_buffer_pool_get();
766 
767  if (mutt_buffer_get_field(_("Pipe to command: "), buf, MUTT_CMD, false, NULL,
768  NULL, NULL) != 0)
769  {
770  goto cleanup;
771  }
772 
773  if (mutt_buffer_len(buf) == 0)
774  goto cleanup;
775 
777  const bool c_pipe_decode = cs_subset_bool(NeoMutt->sub, "pipe_decode");
778  const bool c_pipe_split = cs_subset_bool(NeoMutt->sub, "pipe_split");
779  const char *const c_pipe_sep = cs_subset_string(NeoMutt->sub, "pipe_sep");
780  pipe_message(m, el, mutt_buffer_string(buf), c_pipe_decode, false, c_pipe_split, c_pipe_sep);
781 
782 cleanup:
784 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
static int pipe_message(struct Mailbox *m, struct EmailList *el, const char *cmd, bool decode, bool print, bool split, const char *sep)
Pipe message to a command.
Definition: commands.c:632
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:56
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_print_message()

void mutt_print_message ( struct Mailbox m,
struct EmailList *  el 
)

Print a message.

Parameters
mMailbox
elList of Emails to print

Definition at line 791 of file commands.c.

792 {
793  if (!m || !el)
794  return;
795 
796  const enum QuadOption c_print = cs_subset_quad(NeoMutt->sub, "print");
797  const char *const c_print_command =
798  cs_subset_string(NeoMutt->sub, "print_command");
799  if (c_print && !c_print_command)
800  {
801  mutt_message(_("No printing command has been defined"));
802  return;
803  }
804 
805  int msg_count = 0;
806  struct EmailNode *en = NULL;
807  STAILQ_FOREACH(en, el, entries)
808  {
809  msg_count++;
810  }
811 
812  if (query_quadoption(c_print, (msg_count == 1) ?
813  _("Print message?") :
814  _("Print tagged messages?")) != MUTT_YES)
815  {
816  return;
817  }
818 
819  const bool c_print_decode = cs_subset_bool(NeoMutt->sub, "print_decode");
820  const bool c_print_split = cs_subset_bool(NeoMutt->sub, "print_split");
821  if (pipe_message(m, el, c_print_command, c_print_decode, true, c_print_split, "\f") == 0)
822  mutt_message(ngettext("Message printed", "Messages printed", msg_count));
823  else
824  {
825  mutt_message(ngettext("Message could not be printed",
826  "Messages could not be printed", msg_count));
827  }
828 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
static int pipe_message(struct Mailbox *m, struct EmailList *el, const char *cmd, bool decode, bool print, bool split, const char *sep)
Pipe message to a command.
Definition: commands.c:632
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
#define mutt_message(...)
Definition: logging.h:87
List of Emails.
Definition: email.h:129
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_select_sort()

bool mutt_select_sort ( bool  reverse)

Ask the user for a sort method.

Parameters
reverseIf true make it a reverse sort
Return values
trueThe sort type changed

Definition at line 835 of file commands.c.

836 {
837  enum SortType sort = SORT_DATE;
838 
839  switch (mutt_multi_choice(reverse ?
840  /* L10N: The highlighted letters must match the "Sort" options */
841  _("Rev-Sort "
842  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
843  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?") :
844  /* L10N: The highlighted letters must match the "Rev-Sort" options */
845  _("Sort "
846  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
847  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?"),
848  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
849  _("dfrsotuzcpl")))
850  {
851  case -1: /* abort - don't resort */
852  return -1;
853 
854  case 1: /* (d)ate */
855  sort = SORT_DATE;
856  break;
857 
858  case 2: /* (f)rm */
859  sort = SORT_FROM;
860  break;
861 
862  case 3: /* (r)ecv */
863  sort = SORT_RECEIVED;
864  break;
865 
866  case 4: /* (s)ubj */
867  sort = SORT_SUBJECT;
868  break;
869 
870  case 5: /* t(o) */
871  sort = SORT_TO;
872  break;
873 
874  case 6: /* (t)hread */
875  sort = SORT_THREADS;
876  break;
877 
878  case 7: /* (u)nsort */
879  sort = SORT_ORDER;
880  break;
881 
882  case 8: /* si(z)e */
883  sort = SORT_SIZE;
884  break;
885 
886  case 9: /* s(c)ore */
887  sort = SORT_SCORE;
888  break;
889 
890  case 10: /* s(p)am */
891  sort = SORT_SPAM;
892  break;
893 
894  case 11: /* (l)abel */
895  sort = SORT_LABEL;
896  break;
897  }
898 
899  const unsigned char c_use_threads =
900  cs_subset_enum(NeoMutt->sub, "use_threads");
901  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
902  int rc = CSR_ERR_CODE;
903  if ((sort != SORT_THREADS) || (c_use_threads == UT_UNSET))
904  {
905  if ((sort != SORT_THREADS) && (c_sort & SORT_LAST))
906  sort |= SORT_LAST;
907  if (reverse)
908  sort |= SORT_REVERSE;
909 
910  rc = cs_subset_str_native_set(NeoMutt->sub, "sort", sort, NULL);
911  }
912  else
913  {
914  assert((c_sort & SORT_MASK) != SORT_THREADS); /* See index_config_observer() */
915  /* Preserve the value of $sort, and toggle whether we are threaded. */
916  switch (c_use_threads)
917  {
918  case UT_FLAT:
919  rc = cs_subset_str_native_set(NeoMutt->sub, "use_threads",
920  reverse ? UT_REVERSE : UT_THREADS, NULL);
921  break;
922  case UT_THREADS:
923  rc = cs_subset_str_native_set(NeoMutt->sub, "use_threads",
924  reverse ? UT_REVERSE : UT_FLAT, NULL);
925  break;
926  case UT_REVERSE:
927  rc = cs_subset_str_native_set(NeoMutt->sub, "use_threads",
928  reverse ? UT_FLAT : UT_THREADS, NULL);
929  break;
930  default:
931  assert(false);
932  }
933  }
934 
935  return ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE));
936 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
SortType
Methods for sorting.
Definition: sort2.h:41
Sort by the email&#39;s From field.
Definition: sort2.h:47
#define _(a)
Definition: message.h:28
Sort by the email&#39;s score.
Definition: sort2.h:52
Normal threading (root above subthreads)
Definition: mutt_thread.h:81
Not yet set by user, stick to legacy semantics.
Definition: mutt_thread.h:79
Sort by the emails label.
Definition: sort2.h:62
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CSR_RESULT(x)
Definition: set.h:52
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
Sort by the size of the email.
Definition: sort2.h:44
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
#define CSR_SUC_NO_CHANGE
The value hasn&#39;t changed.
Definition: set.h:44
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
Sort by email threads.
Definition: sort2.h:49
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: question.c:49
Sort by the email&#39;s spam score.
Definition: sort2.h:57
Sort by the email&#39;s To field.
Definition: sort2.h:51
Unthreaded.
Definition: mutt_thread.h:80
unsigned char cs_subset_enum(const struct ConfigSubset *sub, const char *name)
Get a enumeration config item by name.
Definition: helpers.c:97
#define CSR_ERR_CODE
Problem with the code.
Definition: set.h:36
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Sort by when the message were delivered locally.
Definition: sort2.h:50
Sort by the date the email was sent.
Definition: sort2.h:43
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
Reverse threading (subthreads above root)
Definition: mutt_thread.h:82
#define SORT_LAST
Sort thread by last-X, e.g. received date.
Definition: sort2.h:80
Sort by the email&#39;s subject.
Definition: sort2.h:46
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_shell_escape()

bool mutt_shell_escape ( void  )

invoke a command in a subshell

Return values
trueA command was invoked (no matter what its result)
falseNo command was invoked

Definition at line 943 of file commands.c.

944 {
945  char buf[1024];
946 
947  buf[0] = '\0';
948  if (mutt_get_field(_("Shell command: "), buf, sizeof(buf), MUTT_CMD, false, NULL, NULL) != 0)
949  {
950  return false;
951  }
952 
953  const char *const c_shell = cs_subset_string(NeoMutt->sub, "shell");
954  if ((buf[0] == '\0') && c_shell)
955  mutt_str_copy(buf, c_shell, sizeof(buf));
956  if (buf[0] == '\0')
957  {
958  return false;
959  }
960 
962  mutt_endwin();
963  fflush(stdout);
964  int rc = mutt_system(buf);
965  if (rc == -1)
966  mutt_debug(LL_DEBUG1, "Error running \"%s\"", buf);
967 
968  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
969  if ((rc != 0) || c_wait_key)
971 
972  return true;
973 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
#define _(a)
Definition: message.h:28
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:242
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:56
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:422
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:455
Log at debug level 1.
Definition: logging.h:40
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_command()

void mutt_enter_command ( void  )

enter a neomutt command

Definition at line 978 of file commands.c.

979 {
980  char buf[1024] = { 0 };
981 
982  window_redraw(NULL);
983  /* if enter is pressed after : with no command, just return */
984  if ((mutt_get_field(":", buf, sizeof(buf), MUTT_COMMAND, false, NULL, NULL) != 0) ||
985  (buf[0] == '\0'))
986  {
987  return;
988  }
989 
990  struct Buffer err = mutt_buffer_make(256);
991 
992  /* check if buf is a valid icommand, else fall back quietly to parse_rc_lines */
993  enum CommandResult rc = mutt_parse_icommand(buf, &err);
994  if (!mutt_buffer_is_empty(&err))
995  {
996  /* since errbuf could potentially contain printf() sequences in it,
997  * we must call mutt_error() in this fashion so that vsprintf()
998  * doesn't expect more arguments that we passed */
999  if (rc == MUTT_CMD_ERROR)
1000  mutt_error("%s", err.data);
1001  else
1002  mutt_warning("%s", err.data);
1003  }
1004  else if (rc != MUTT_CMD_SUCCESS)
1005  {
1006  rc = mutt_parse_rc_line(buf, &err);
1007  if (!mutt_buffer_is_empty(&err))
1008  {
1009  if (rc == MUTT_CMD_SUCCESS) /* command succeeded with message */
1010  mutt_message("%s", err.data);
1011  else if (rc == MUTT_CMD_ERROR)
1012  mutt_error("%s", err.data);
1013  else if (rc == MUTT_CMD_WARNING)
1014  mutt_warning("%s", err.data);
1015  }
1016  }
1017  /* else successful command */
1018 
1019  mutt_buffer_dealloc(&err);
1020 }
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:34
Error: Can&#39;t help the user.
Definition: mutt_commands.h:36
#define mutt_error(...)
Definition: logging.h:88
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1039
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:632
enum CommandResult mutt_parse_icommand(char *line, struct Buffer *err)
Parse an informational command.
Definition: icommands.c:78
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
#define MUTT_COMMAND
Do command completion.
Definition: mutt.h:59
#define mutt_warning(...)
Definition: logging.h:86
char * data
Pointer to data.
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:38
Warning: Help given to the user.
Definition: mutt_commands.h:37
#define mutt_message(...)
Definition: logging.h:87
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_display_address()

void mutt_display_address ( struct Envelope env)

Display the address of a message.

Parameters
envEnvelope containing address

Definition at line 1026 of file commands.c.

1027 {
1028  const char *pfx = NULL;
1029  char buf[128];
1030 
1031  struct AddressList *al = mutt_get_address(env, &pfx);
1032  if (!al)
1033  return;
1034 
1035  /* Note: We don't convert IDNA to local representation this time.
1036  * That is intentional, so the user has an opportunity to copy &
1037  * paste the on-the-wire form of the address to other, IDN-unable
1038  * software. */
1039  buf[0] = '\0';
1040  mutt_addrlist_write(al, buf, sizeof(buf), false);
1041  mutt_message("%s: %s", pfx, buf);
1042 }
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
Definition: alias.c:332
#define mutt_message(...)
Definition: logging.h:87
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_copy_flags()

static void set_copy_flags ( struct Email e,
enum MessageTransformOpt  transform_opt,
CopyMessageFlags cmflags,
CopyHeaderFlags chflags 
)
static

Set the flags for a message copy.

Parameters
[in]eEmail
[in]transform_optTransformation, e.g. TRANSFORM_DECRYPT
[out]cmflagsFlags, see CopyMessageFlags
[out]chflagsFlags, see CopyHeaderFlags

Definition at line 1051 of file commands.c.

1053 {
1054  *cmflags = MUTT_CM_NO_FLAGS;
1055  *chflags = CH_UPDATE_LEN;
1056 
1057  const bool need_decrypt =
1058  (transform_opt == TRANSFORM_DECRYPT) && (e->security & SEC_ENCRYPT);
1059  const bool want_pgp = (WithCrypto & APPLICATION_PGP);
1060  const bool want_smime = (WithCrypto & APPLICATION_SMIME);
1061  const bool is_pgp = mutt_is_application_pgp(e->body) & SEC_ENCRYPT;
1062  const bool is_smime = mutt_is_application_smime(e->body) & SEC_ENCRYPT;
1063 
1064  if (need_decrypt && want_pgp && mutt_is_multipart_encrypted(e->body))
1065  {
1066  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
1067  *cmflags = MUTT_CM_DECODE_PGP;
1068  }
1069  else if (need_decrypt && want_pgp && is_pgp)
1070  {
1071  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN;
1072  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1073  }
1074  else if (need_decrypt && want_smime && is_smime)
1075  {
1076  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
1077  *cmflags = MUTT_CM_DECODE_SMIME;
1078  }
1079  else if (transform_opt == TRANSFORM_DECODE)
1080  {
1081  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN | CH_DECODE; // then decode RFC2047
1082  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1083  const bool c_copy_decode_weed =
1084  cs_subset_bool(NeoMutt->sub, "copy_decode_weed");
1085  if (c_copy_decode_weed)
1086  {
1087  *chflags |= CH_WEED; // and respect $weed
1088  *cmflags |= MUTT_CM_WEED;
1089  }
1090  }
1091 }
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:61
Decrypt message.
Definition: commands.h:42
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define WithCrypto
Definition: lib.h:113
struct Body * body
List of MIME parts.
Definition: email.h:91
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:623
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:41
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:36
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:460
#define CH_WEED
Weed the headers?
Definition: copy.h:53
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:63
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:55
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:62
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:46
SecurityFlags mutt_is_application_pgp(struct Body *b)
Does the message use PGP?
Definition: crypt.c:565
#define MUTT_CM_DECODE_PGP
Used for decoding PGP messages.
Definition: copy.h:45
Decode message.
Definition: commands.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_message_ctx()

int mutt_save_message_ctx ( struct Mailbox m_src,
struct Email e,
enum MessageSaveOpt  save_opt,
enum MessageTransformOpt  transform_opt,
struct Mailbox m_dst 
)

Save a message to a given mailbox.

Parameters
m_srcMailbox to copy from
eEmail
save_optCopy or move, e.g. SAVE_MOVE
transform_optTransformation, e.g. TRANSFORM_DECRYPT
m_dstMailbox to save to
Return values
0Success
-1Error

Definition at line 1103 of file commands.c.

1105 {
1107  CopyHeaderFlags chflags = CH_NO_FLAGS;
1108  int rc;
1109 
1110  set_copy_flags(e, transform_opt, &cmflags, &chflags);
1111 
1112  struct Message *msg = mx_msg_open(m_src, e->msgno);
1113  if (msg && transform_opt != TRANSFORM_NONE)
1114  {
1115  mutt_parse_mime_message(m_src, e, msg->fp);
1116  }
1117 
1118  rc = mutt_append_message(m_dst, m_src, e, msg, cmflags, chflags);
1119  mx_msg_close(m_src, &msg);
1120  if (rc != 0)
1121  return rc;
1122 
1123  if (save_opt == SAVE_MOVE)
1124  {
1125  mutt_set_flag(m_src, e, MUTT_DELETE, true);
1126  mutt_set_flag(m_src, e, MUTT_PURGE, true);
1127  const bool c_delete_untag = cs_subset_bool(NeoMutt->sub, "delete_untag");
1128  if (c_delete_untag)
1129  mutt_set_flag(m_src, e, MUTT_TAG, false);
1130  }
1131 
1132  return 0;
1133 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:66
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int mutt_append_message(struct Mailbox *m_dst, struct Mailbox *m_src, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:923
No transformation.
Definition: commands.h:41
Messages to be purged (bypass trash)
Definition: mutt.h:96
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:32
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
static void set_copy_flags(struct Email *e, enum MessageTransformOpt transform_opt, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Set the flags for a message copy.
Definition: commands.c:1051
A local copy of an email.
Definition: mxapi.h:41
Messages to be deleted.
Definition: mutt.h:94
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:51
Tagged messages.
Definition: mutt.h:99
Move message to another mailbox, removing the original.
Definition: commands.h:52
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:50
FILE * fp
pointer to the message data
Definition: mxapi.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_message()

int mutt_save_message ( struct Mailbox m,
struct EmailList *  el,
enum MessageSaveOpt  save_opt,
enum MessageTransformOpt  transform_opt 
)

Save an email.

Parameters
mMailbox
elList of Emails to save
save_optCopy or move, e.g. SAVE_MOVE
transform_optTransformation, e.g. TRANSFORM_DECRYPT
Return values
0Copy/save was successful
-1Error/abort

Definition at line 1144 of file commands.c.

1146 {
1147  if (!el || STAILQ_EMPTY(el))
1148  return -1;
1149 
1150  int rc = -1;
1151  int tagged_progress_count = 0;
1152  unsigned int msg_count = 0;
1153 
1154  struct Buffer *buf = mutt_buffer_pool_get();
1155  struct stat st;
1156  struct EmailNode *en = NULL;
1157 
1158  STAILQ_FOREACH(en, el, entries)
1159  {
1160  msg_count++;
1161  }
1162  en = STAILQ_FIRST(el);
1163 
1164  const SecurityFlags security_flags = WithCrypto ? en->email->security : SEC_NO_FLAGS;
1165  const bool is_passphrase_needed = security_flags & SEC_ENCRYPT;
1166 
1167  const char *prompt = NULL;
1168  const char *progress_msg = NULL;
1169 
1170  // Set prompt and progress_msg
1171  switch (save_opt)
1172  {
1173  case SAVE_COPY:
1174  // L10N: Progress meter message when copying tagged messages
1175  progress_msg = (msg_count > 1) ? _("Copying tagged messages...") : NULL;
1176  switch (transform_opt)
1177  {
1178  case TRANSFORM_NONE:
1179  prompt = (msg_count > 1) ? _("Copy tagged to mailbox") : _("Copy to mailbox");
1180  break;
1181  case TRANSFORM_DECRYPT:
1182  prompt = (msg_count > 1) ? _("Decrypt-copy tagged to mailbox") :
1183  _("Decrypt-copy to mailbox");
1184  break;
1185  case TRANSFORM_DECODE:
1186  prompt = (msg_count > 1) ? _("Decode-copy tagged to mailbox") :
1187  _("Decode-copy to mailbox");
1188  break;
1189  }
1190  break;
1191 
1192  case SAVE_MOVE:
1193  // L10N: Progress meter message when saving tagged messages
1194  progress_msg = (msg_count > 1) ? _("Saving tagged messages...") : NULL;
1195  switch (transform_opt)
1196  {
1197  case TRANSFORM_NONE:
1198  prompt = (msg_count > 1) ? _("Save tagged to mailbox") : _("Save to mailbox");
1199  break;
1200  case TRANSFORM_DECRYPT:
1201  prompt = (msg_count > 1) ? _("Decrypt-save tagged to mailbox") :
1202  _("Decrypt-save to mailbox");
1203  break;
1204  case TRANSFORM_DECODE:
1205  prompt = (msg_count > 1) ? _("Decode-save tagged to mailbox") :
1206  _("Decode-save to mailbox");
1207  break;
1208  }
1209  break;
1210  }
1211 
1213  mutt_default_save(buf->data, buf->dsize, en->email);
1214  mutt_buffer_fix_dptr(buf);
1216 
1217  if (mutt_buffer_enter_fname(prompt, buf, false, NULL, false, NULL, NULL,
1218  MUTT_SEL_NO_FLAGS) == -1)
1219  {
1220  goto cleanup;
1221  }
1222 
1223  size_t pathlen = mutt_buffer_len(buf);
1224  if (pathlen == 0)
1225  goto cleanup;
1226 
1227  /* Trim any trailing '/' */
1228  if (buf->data[pathlen - 1] == '/')
1229  buf->data[pathlen - 1] = '\0';
1230 
1231  /* This is an undocumented feature of ELM pointed out to me by Felix von
1232  * Leitner <leitner@prz.fu-berlin.de> */
1233  if (mutt_buffer_len(&LastSaveFolder) == 0)
1235  if (mutt_str_equal(mutt_buffer_string(buf), "."))
1237  else
1239 
1241 
1242  /* check to make sure that this file is really the one the user wants */
1243  if (mutt_save_confirm(mutt_buffer_string(buf), &st) != 0)
1244  goto cleanup;
1245 
1246  if (is_passphrase_needed && (transform_opt != TRANSFORM_NONE) &&
1247  !crypt_valid_passphrase(security_flags))
1248  {
1249  rc = -1;
1250  goto errcleanup;
1251  }
1252 
1253  mutt_message(_("Copying to %s..."), mutt_buffer_string(buf));
1254 
1255 #ifdef USE_IMAP
1256  enum MailboxType mailbox_type = imap_path_probe(mutt_buffer_string(buf), NULL);
1257  if ((m->type == MUTT_IMAP) && (transform_opt == TRANSFORM_NONE) && (mailbox_type == MUTT_IMAP))
1258  {
1259  rc = imap_copy_messages(m, el, mutt_buffer_string(buf), save_opt);
1260  switch (rc)
1261  {
1262  /* success */
1263  case 0:
1264  mutt_clear_error();
1265  rc = 0;
1266  goto cleanup;
1267  /* non-fatal error: continue to fetch/append */
1268  case 1:
1269  break;
1270  /* fatal error, abort */
1271  case -1:
1272  goto errcleanup;
1273  }
1274  }
1275 #endif
1276 
1278  struct Mailbox *m_save = mx_path_resolve(mutt_buffer_string(buf));
1279  bool old_append = m_save->append;
1280  OpenMailboxFlags mbox_flags = MUTT_NEWFOLDER;
1281  /* Display a tagged message progress counter, rather than (for
1282  * IMAP) a per-message progress counter */
1283  if (msg_count > 1)
1284  mbox_flags |= MUTT_QUIET;
1285  if (!mx_mbox_open(m_save, mbox_flags))
1286  {
1287  rc = -1;
1288  mailbox_free(&m_save);
1289  goto errcleanup;
1290  }
1291  m_save->append = true;
1292 
1293 #ifdef USE_COMP_MBOX
1294  /* If we're saving to a compressed mailbox, the stats won't be updated
1295  * until the next open. Until then, improvise. */
1296  struct Mailbox *m_comp = NULL;
1297  if (m_save->compress_info)
1298  {
1299  m_comp = mailbox_find(m_save->realpath);
1300  }
1301  /* We probably haven't been opened yet */
1302  if (m_comp && (m_comp->msg_count == 0))
1303  m_comp = NULL;
1304 #endif
1305  if (msg_count == 1)
1306  {
1307  rc = mutt_save_message_ctx(m, en->email, save_opt, transform_opt, m_save);
1308  if (rc != 0)
1309  {
1310  mx_mbox_close(m_save);
1311  m_save->append = old_append;
1312  goto errcleanup;
1313  }
1314 #ifdef USE_COMP_MBOX
1315  if (m_comp)
1316  {
1317  m_comp->msg_count++;
1318  if (!en->email->read)
1319  {
1320  m_comp->msg_unread++;
1321  if (!en->email->old)
1322  m_comp->msg_new++;
1323  }
1324  if (en->email->flagged)
1325  m_comp->msg_flagged++;
1326  }
1327 #endif
1328  }
1329  else
1330  {
1331  rc = 0;
1332 
1333 #ifdef USE_NOTMUCH
1334  if (m->type == MUTT_NOTMUCH)
1335  nm_db_longrun_init(m, true);
1336 #endif
1337  struct Progress *progress = progress_new(progress_msg, MUTT_PROGRESS_WRITE, msg_count);
1338  STAILQ_FOREACH(en, el, entries)
1339  {
1340  progress_update(progress, ++tagged_progress_count, -1);
1342  rc = mutt_save_message_ctx(m, en->email, save_opt, transform_opt, m_save);
1343  if (rc != 0)
1344  break;
1345 #ifdef USE_COMP_MBOX
1346  if (m_comp)
1347  {
1348  struct Email *e2 = en->email;
1349  m_comp->msg_count++;
1350  if (!e2->read)
1351  {
1352  m_comp->msg_unread++;
1353  if (!e2->old)
1354  m_comp->msg_new++;
1355  }
1356  if (e2->flagged)
1357  m_comp->msg_flagged++;
1358  }
1359 #endif
1360  }
1361  progress_free(&progress);
1362 
1363 #ifdef USE_NOTMUCH
1364  if (m->type == MUTT_NOTMUCH)
1365  nm_db_longrun_done(m);
1366 #endif
1367  if (rc != 0)
1368  {
1369  mx_mbox_close(m_save);
1370  m_save->append = old_append;
1371  goto errcleanup;
1372  }
1373  }
1374 
1375  const bool need_mailbox_cleanup =
1376  ((m_save->type == MUTT_MBOX) || (m_save->type == MUTT_MMDF));
1377 
1378  mx_mbox_close(m_save);
1379  m_save->append = old_append;
1380 
1381  if (need_mailbox_cleanup)
1383 
1384  mutt_clear_error();
1385  rc = 0;
1386 
1387 errcleanup:
1388  if (rc != 0)
1389  {
1390  switch (save_opt)
1391  {
1392  case SAVE_MOVE:
1393  if (msg_count > 1)
1394  {
1395  // L10N: Message when an index tagged save operation fails for some reason
1396  mutt_error(_("Error saving tagged messages"));
1397  }
1398  else
1399  {
1400  // L10N: Message when an index/pager save operation fails for some reason
1401  mutt_error(_("Error saving message"));
1402  }
1403  break;
1404  case SAVE_COPY:
1405  if (msg_count > 1)
1406  {
1407  // L10N: Message when an index tagged copy operation fails for some reason
1408  mutt_error(_("Error copying tagged messages"));
1409  }
1410  else
1411  {
1412  // L10N: Message when an index/pager copy operation fails for some reason
1413  mutt_error(_("Error copying message"));
1414  }
1415  break;
1416  }
1417  }
1418 
1419 cleanup:
1421  return rc;
1422 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
Decrypt message.
Definition: commands.h:42
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define WithCrypto
Definition: lib.h:113
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
#define mutt_error(...)
Definition: logging.h:88
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:74
void mutt_mailbox_cleanup(const char *path, struct stat *st)
Restore the timestamp of a mailbox.
Definition: mutt_mailbox.c:360
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
int mutt_save_message_ctx(struct Mailbox *m_src, struct Email *e, enum MessageSaveOpt save_opt, enum MessageTransformOpt transform_opt, struct Mailbox *m_dst)
Save a message to a given mailbox.
Definition: commands.c:1103
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:125
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
No transformation.
Definition: commands.h:41
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:36
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: db.c:314
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:71
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:46
Copy message, making a duplicate in another mailbox.
Definition: commands.h:51
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:610
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:677
A Progress Bar.
Definition: progress.c:47
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:603
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1360
int imap_copy_messages(struct Mailbox *m, struct EmailList *el, const char *dest, enum MessageSaveOpt save_opt)
Server COPY messages to another folder.
Definition: message.c:1643
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
size_t dsize
Length of data.
Definition: buffer.h:37
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
A mailbox.
Definition: mailbox.h:81
#define PATH_MAX
Definition: mutt.h:40
char * data
Pointer to data.
Definition: buffer.h:35
static struct Buffer LastSaveFolder
The folder the user last saved to.
Definition: commands.c:90
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: db.c:329
void mutt_file_resolve_symlink(struct Buffer *buf)
Resolve a symlink in place.
Definition: file.c:1620
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mxapi.h:59
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mxapi.h:65
#define MUTT_QUIET
Do not print any messages.
Definition: mxapi.h:64
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
int mutt_buffer_enter_fname(const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
Ask the user to select a file.
Definition: curs_lib.c:513
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
Move message to another mailbox, removing the original.
Definition: commands.h:52
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:95
Progress tracks elements, according to $write_inc
Definition: lib.h:47
struct Email * email
Email in the list.
Definition: email.h:131
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
#define mutt_message(...)
Definition: logging.h:87
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1668
#define STAILQ_EMPTY(head)
Definition: queue.h:348
Decode message.
Definition: commands.h:43
List of Emails.
Definition: email.h:129
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:598
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
#define STAILQ_FIRST(head)
Definition: queue.h:350
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_edit_content_type()

bool mutt_edit_content_type ( struct Email e,
struct Body b,
FILE *  fp 
)

Edit the content type of an attachment.

Parameters
eEmail
bAttachment
fpFile handle to the attachment
Return values
trueA Any change is made

recvattach requires the return code to know when to regenerate the actx.

Definition at line 1433 of file commands.c.

1434 {
1435  char buf[1024];
1436  char obuf[1024];
1437  char tmp[256];
1438  char charset[256];
1439 
1440  bool charset_changed = false;
1441  bool type_changed = false;
1442  bool structure_changed = false;
1443 
1444  char *cp = mutt_param_get(&b->parameter, "charset");
1445  mutt_str_copy(charset, cp, sizeof(charset));
1446 
1447  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
1448  mutt_str_copy(obuf, buf, sizeof(obuf));
1449  if (!TAILQ_EMPTY(&b->parameter))
1450  {
1451  size_t l = strlen(buf);
1452  struct Parameter *np = NULL;
1453  TAILQ_FOREACH(np, &b->parameter, entries)
1454  {
1455  mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
1456  l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
1457  if (l >= sizeof(buf))
1458  {
1459  // L10N: e.g. "text/plain; charset=UTF-8; ..."
1460  mutt_error(_("Content type is too long"));
1461  return false;
1462  }
1463  }
1464  }
1465 
1466  if ((mutt_get_field("Content-Type: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
1467  false, NULL, NULL) != 0) ||
1468  (buf[0] == '\0'))
1469  {
1470  return false;
1471  }
1472 
1473  /* clean up previous junk */
1475  FREE(&b->subtype);
1476 
1477  mutt_parse_content_type(buf, b);
1478 
1479  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1480  type_changed = !mutt_istr_equal(tmp, obuf);
1481  charset_changed =
1482  !mutt_istr_equal(charset, mutt_param_get(&b->parameter, "charset"));
1483 
1484  /* if in send mode, check for conversion - current setting is default. */
1485 
1486  if (!e && (b->type == TYPE_TEXT) && charset_changed)
1487  {
1488  snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
1489  mutt_param_get(&b->parameter, "charset"));
1490  enum QuadOption ans = mutt_yesorno(tmp, b->noconv ? MUTT_NO : MUTT_YES);
1491  if (ans != MUTT_ABORT)
1492  b->noconv = (ans == MUTT_NO);
1493  }
1494 
1495  /* inform the user */
1496 
1497  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1498  if (type_changed)
1499  mutt_message(_("Content-Type changed to %s"), tmp);
1500  if ((b->type == TYPE_TEXT) && charset_changed)
1501  {
1502  if (type_changed)
1503  mutt_sleep(1);
1504  mutt_message(b->noconv ? _("Character set changed to %s; not converting") :
1505  _("Character set changed to %s; converting"),
1506  mutt_param_get(&b->parameter, "charset"));
1507  }
1508 
1509  b->force_charset |= charset_changed;
1510 
1511  if (!is_multipart(b) && b->parts)
1512  {
1513  structure_changed = true;
1514  mutt_body_free(&b->parts);
1515  }
1516  if (!mutt_is_message_type(b->type, b->subtype) && b->email)
1517  {
1518  structure_changed = true;
1519  b->email->body = NULL;
1520  email_free(&b->email);
1521  }
1522 
1523  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
1524  {
1525  structure_changed = true;
1526  mutt_parse_part(fp, b);
1527  }
1528 
1529  if ((WithCrypto != 0) && e)
1530  {
1531  if (e->body == b)
1532  e->security = SEC_NO_FLAGS;
1533 
1534  e->security |= crypt_query(b);
1535  }
1536 
1537  return structure_changed | type_changed;
1538 }
char * attribute
Parameter name.
Definition: parameter.h:34
#define NONULL(x)
Definition: string2.h:37
#define WithCrypto
Definition: lib.h:113
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:44
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
struct Body * body
List of MIME parts.
Definition: email.h:91
#define mutt_error(...)
Definition: logging.h:88
#define is_multipart(body)
Definition: mime.h:82
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:74
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
#define _(a)
Definition: message.h:28
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:52
bool force_charset
Send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:75
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:61
User aborted the question (with Ctrl-G)
Definition: quad.h:37
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
Type: &#39;text/*&#39;.
Definition: mime.h:38
const char MimeSpecials[]
Characters that need special treatment in MIME.
Definition: mime.c:67
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
#define TYPE(body)
Definition: mime.h:89
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:427
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1678
char * value
Parameter value.
Definition: parameter.h:35
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
Attribute associated with a MIME part.
Definition: parameter.h:32
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:698
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
#define TAILQ_EMPTY(head)
Definition: queue.h:721
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
struct Email * email
header information for message/rfc822
Definition: body.h:55
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:681
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_traditional_pgp()

static bool check_traditional_pgp ( struct Mailbox m,
struct Email e 
)
static

Check for an inline PGP content.

Parameters
mMailbox
eEmail to check
Return values
trueMessage contains inline PGP content

Definition at line 1546 of file commands.c.

1547 {
1548  bool rc = false;
1549 
1551 
1552  struct Message *msg = mx_msg_open(m, e->msgno);
1553  if (msg)
1554  {
1555  mutt_parse_mime_message(m, e, msg->fp);
1556  if (crypt_pgp_check_traditional(msg->fp, e->body, false))
1557  {
1558  e->security = crypt_query(e->body);
1559  rc = true;
1560  }
1561 
1563  mx_msg_close(m, &msg);
1564  }
1565  return rc;
1566 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
struct Body * body
List of MIME parts.
Definition: email.h:91
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1186
bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:288
A local copy of an email.
Definition: mxapi.h:41
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
FILE * fp
pointer to the message data
Definition: mxapi.h:43
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:698
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:89
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1140
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_traditional_pgp()

bool mutt_check_traditional_pgp ( struct Mailbox m,
struct EmailList *  el 
)

Check if a message has inline PGP content.

Parameters
mMailbox
elList of Emails to check
Return values
trueMessage contains inline PGP content

Definition at line 1574 of file commands.c.

1575 {
1576  bool rc = false;
1577  struct EmailNode *en = NULL;
1578  STAILQ_FOREACH(en, el, entries)
1579  {
1580  if (!(en->email->security & PGP_TRADITIONAL_CHECKED))
1581  rc = check_traditional_pgp(m, en->email) || rc;
1582  }
1583 
1584  return rc;
1585 }
static bool check_traditional_pgp(struct Mailbox *m, struct Email *e)
Check for an inline PGP content.
Definition: commands.c:1546
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
struct Email * email
Email in the list.
Definition: email.h:131
List of Emails.
Definition: email.h:129
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_stats()

void mutt_check_stats ( struct Mailbox m)

Forcibly update mailbox stats.

Definition at line 1590 of file commands.c.

1591 {
1593 }
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:137
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mutt_mailbox.h:32
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Definition: mutt_mailbox.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ ExtPagerProgress

const char* ExtPagerProgress = "all"
static

Definition at line 87 of file commands.c.

◆ LastSaveFolder

struct Buffer LastSaveFolder = { 0 }
static

The folder the user last saved to.

Used by ci_save_message()

Definition at line 90 of file commands.c.