NeoMutt  2021-02-05-329-g9e03b7
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 <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 "ncrypt/lib.h"
#include "pager/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 "muttlib.h"
#include "mx.h"
#include "options.h"
#include "progress.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 91 of file commands.c.

92 {
94 }
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:86
+ 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 101 of file commands.c.

102 {
103  struct Envelope *prot_headers = NULL;
104  regmatch_t pmatch[1];
105 
106  const bool c_crypt_protected_headers_read =
107  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
108 #ifdef USE_AUTOCRYPT
109  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
110  if (!c_crypt_protected_headers_read && !c_autocrypt)
111  return;
112 #else
113  if (!c_crypt_protected_headers_read)
114  return;
115 #endif
116 
117  /* Grab protected headers to update in the index */
118  if (e->security & SEC_SIGN)
119  {
120  /* Don't update on a bad signature.
121  *
122  * This is a simplification. It's possible the headers are in the
123  * encrypted part of a nested encrypt/signed. But properly handling that
124  * case would require more complexity in the decryption handlers, which
125  * I'm not sure is worth it. */
126  if (!(e->security & SEC_GOODSIGN))
127  return;
128 
129  if (mutt_is_multipart_signed(e->body) && e->body->parts)
130  {
131  prot_headers = e->body->parts->mime_headers;
132  }
133  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
134  {
135  prot_headers = e->body->mime_headers;
136  }
137  }
138  if (!prot_headers && (e->security & SEC_ENCRYPT))
139  {
140  if (((WithCrypto & APPLICATION_PGP) != 0) &&
143  {
144  prot_headers = e->body->mime_headers;
145  }
146  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
147  {
148  prot_headers = e->body->mime_headers;
149  }
150  }
151 
152  /* Update protected headers in the index and header cache. */
153  if (c_crypt_protected_headers_read && prot_headers && prot_headers->subject &&
154  !mutt_str_equal(e->env->subject, prot_headers->subject))
155  {
156  if (m->subj_hash && e->env->real_subj)
158 
159  mutt_str_replace(&e->env->subject, prot_headers->subject);
160  FREE(&e->env->disp_subj);
161  const struct Regex *c_reply_regex =
162  cs_subset_regex(NeoMutt->sub, "reply_regex");
163  if (mutt_regex_capture(c_reply_regex, e->env->subject, 1, pmatch))
164  e->env->real_subj = e->env->subject + pmatch[0].rm_eo;
165  else
166  e->env->real_subj = e->env->subject;
167 
168  if (m->subj_hash)
170 
171  mx_save_hcache(m, e);
172 
173  /* Also persist back to the message headers if this is set */
174  const bool c_crypt_protected_headers_save =
175  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_save");
176  if (c_crypt_protected_headers_save)
177  {
179  e->changed = true;
180  m->changed = true;
181  }
182  }
183 
184 #ifdef USE_AUTOCRYPT
185  if (c_autocrypt && (e->security & SEC_ENCRYPT) && prot_headers && prot_headers->autocrypt_gossip)
186  {
187  mutt_autocrypt_process_gossip_header(m, e, prot_headers);
188  }
189 #endif
190 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
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:71
#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:414
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:622
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:483
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:1802
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:227
struct Envelope * env
Envelope information.
Definition: email.h:90
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:419
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:520
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 203 of file commands.c.

206 {
207  int rc = 0;
208  bool builtin = false;
210  CopyHeaderFlags chflags;
211  pid_t filterpid = -1;
212  struct Buffer *tempfile = NULL;
213  int res;
214 
215  struct Message *msg = mx_msg_open(m, e->msgno);
216  if (!msg)
217  {
218  return -1;
219  }
220 
221  mutt_parse_mime_message(m, e, msg->fp);
223 
224  char columns[16];
225  // win_pager might not be visible and have a size yet, so use win_index
226  snprintf(columns, sizeof(columns), "%d", win_index->state.cols);
227  mutt_envlist_set("COLUMNS", columns, true);
228 
229  /* see if crypto is needed for this message. if so, we should exit curses */
230  if ((WithCrypto != 0) && e->security)
231  {
232  if (e->security & SEC_ENCRYPT)
233  {
234  if (e->security & APPLICATION_SMIME)
237  goto cleanup;
238 
239  cmflags |= MUTT_CM_VERIFY;
240  }
241  else if (e->security & SEC_SIGN)
242  {
243  /* find out whether or not the verify signature */
244  /* L10N: Used for the $crypt_verify_sig prompt */
245  const enum QuadOption c_crypt_verify_sig =
246  cs_subset_quad(NeoMutt->sub, "crypt_verify_sig");
247  if (query_quadoption(c_crypt_verify_sig, _("Verify signature?")) == MUTT_YES)
248  {
249  cmflags |= MUTT_CM_VERIFY;
250  }
251  }
252  }
253 
254  if (cmflags & MUTT_CM_VERIFY || e->security & SEC_ENCRYPT)
255  {
256  if (e->security & APPLICATION_PGP)
257  {
258  if (!TAILQ_EMPTY(&e->env->from))
260 
262  }
263 
264  if (e->security & APPLICATION_SMIME)
266  }
267 
268  FILE *fp_filter_out = NULL;
269  tempfile = mutt_buffer_pool_get();
270  mutt_buffer_mktemp(tempfile);
271  FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfile), "w");
272  if (!fp_out)
273  {
274  mutt_error(_("Could not create temporary file"));
275  goto cleanup;
276  }
277 
278  const char *const c_display_filter =
279  cs_subset_string(NeoMutt->sub, "display_filter");
280  if (c_display_filter)
281  {
282  fp_filter_out = fp_out;
283  fp_out = NULL;
284  filterpid = filter_create_fd(c_display_filter, &fp_out, NULL, NULL, -1,
285  fileno(fp_filter_out), -1);
286  if (filterpid < 0)
287  {
288  mutt_error(_("Can't create display filter"));
289  mutt_file_fclose(&fp_filter_out);
290  unlink(mutt_buffer_string(tempfile));
291  goto cleanup;
292  }
293  }
294 
295  const char *const c_pager = cs_subset_string(NeoMutt->sub, "pager");
296  if (!c_pager || mutt_str_equal(c_pager, "builtin"))
297  builtin = true;
298  else
299  {
300  char buf[1024] = { 0 };
301  const char *const c_pager_format =
302  cs_subset_string(NeoMutt->sub, "pager_format");
303  mutt_make_string(buf, sizeof(buf), win_index->state.cols, NONULL(c_pager_format),
304  m, Context ? Context->msg_in_pager : -1, e,
306  fputs(buf, fp_out);
307  fputs("\n\n", fp_out);
308  }
309 
310  const bool c_weed = cs_subset_bool(NeoMutt->sub, "weed");
311  chflags = (c_weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) | CH_DECODE | CH_FROM | CH_DISPLAY;
312 #ifdef USE_NOTMUCH
313  if (m->type == MUTT_NOTMUCH)
314  chflags |= CH_VIRTUAL;
315 #endif
316  res = mutt_copy_message(fp_out, m, e, msg, cmflags, chflags, win_index->state.cols);
317 
318  if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (res < 0))
319  {
320  mutt_error(_("Could not copy message"));
321  if (fp_filter_out)
322  {
323  filter_wait(filterpid);
324  mutt_file_fclose(&fp_filter_out);
325  }
327  goto cleanup;
328  }
329 
330  if (fp_filter_out && (filter_wait(filterpid) != 0))
332 
333  mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
334 
335  if (WithCrypto)
336  {
337  /* update crypto information for this message */
338  e->security &= ~(SEC_GOODSIGN | SEC_BADSIGN);
339  e->security |= crypt_query(e->body);
340 
341  /* Remove color cache for this message, in case there
342  * are color patterns for both ~g and ~V */
343  e->pair = 0;
344 
345  /* Process protected headers and autocrypt gossip headers */
347  }
348 
349  if (builtin)
350  {
351  if ((WithCrypto != 0) && (e->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
352  {
353  if (e->security & SEC_GOODSIGN)
354  {
355  if (crypt_smime_verify_sender(m, e, msg) == 0)
356  mutt_message(_("S/MIME signature successfully verified"));
357  else
358  mutt_error(_("S/MIME certificate owner does not match sender"));
359  }
360  else if (e->security & SEC_PARTSIGN)
361  mutt_message(_("Warning: Part of this message has not been signed"));
362  else if (e->security & SEC_SIGN || e->security & SEC_BADSIGN)
363  mutt_error(_("S/MIME signature could NOT be verified"));
364  }
365 
366  if ((WithCrypto != 0) && (e->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
367  {
368  if (e->security & SEC_GOODSIGN)
369  mutt_message(_("PGP signature successfully verified"));
370  else if (e->security & SEC_PARTSIGN)
371  mutt_message(_("Warning: Part of this message has not been signed"));
372  else if (e->security & SEC_SIGN)
373  mutt_message(_("PGP signature could NOT be verified"));
374  }
375 
376  /* Invoke the builtin pager */
377  struct PagerData pdata = { 0 };
378  struct PagerView pview = { &pdata };
379 
380  pdata.email = e;
381  pdata.fp = msg->fp;
382  pdata.ctx = Context;
383  pdata.fname = mutt_buffer_string(tempfile);
384 
385  pview.mode = PAGER_MODE_EMAIL;
386  pview.banner = NULL;
387  pview.flags = MUTT_PAGER_MESSAGE | (e->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
388  pview.win_ibar = win_ibar;
389  pview.win_index = win_index;
390  pview.win_pbar = win_pbar;
391  pview.win_pager = win_pager;
392  rc = mutt_pager(&pview);
393  }
394  else
395  {
396  mutt_endwin();
397 
398  struct Buffer *cmd = mutt_buffer_pool_get();
399  mutt_buffer_printf(cmd, "%s %s", NONULL(c_pager), mutt_buffer_string(tempfile));
400  int r = mutt_system(mutt_buffer_string(cmd));
401  if (r == -1)
402  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
403  unlink(mutt_buffer_string(tempfile));
405 
406  if (!OptNoCurses)
407  keypad(stdscr, true);
408  if (r != -1)
409  mutt_set_flag(m, e, MUTT_READ, true);
410  const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
411  if ((r != -1) && c_prompt_after)
412  {
413  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
414  rc = km_dokey(MENU_PAGER);
415  }
416  else
417  rc = 0;
418  }
419 
420 cleanup:
421  mx_msg_close(m, &msg);
422  mutt_envlist_unset("COLUMNS");
423  mutt_buffer_pool_release(&tempfile);
424  return rc;
425 }
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:661
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:587
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
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:71
#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:716
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_message(...)
Definition: logging.h:83
#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:148
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:725
#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:83
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
#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
WHERE struct Context * Context
Definition: mutt_globals.h:40
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:156
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
struct Email * email
Current message.
Definition: lib.h:138
Pager pager (email viewer)
Definition: keymap.h:81
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1185
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
Data to be displayed by PagerView.
Definition: lib.h:135
#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:1410
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:62
static void process_protected_headers(struct Mailbox *m, struct Email *e)
Get the protected header and update the index.
Definition: commands.c:101
bool nowrap
Do not wrap the output in the pager.
Definition: body.h:74
enum PagerMode mode
Pager mode.
Definition: lib.h:151
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
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:123
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
#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:568
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
struct Context * ctx
Current Mailbox context.
Definition: lib.h:137
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:295
PagerFlags flags
Additional settings to tweak pager&#39;s function.
Definition: lib.h:152
#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:204
#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:601
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:513
FILE * fp
Source stream.
Definition: lib.h:140
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
#define mutt_error(...)
Definition: logging.h:84
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:697
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:846
struct MuttWindow * win_pager
Definition: lib.h:158
struct MuttWindow * win_pbar
Definition: lib.h:157
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:59
struct MuttWindow * win_ibar
Definition: lib.h:155
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:142
#define TAILQ_EMPTY(head)
Definition: queue.h:714
int mutt_pager(struct PagerView *pview)
Display a an email, attachment, or help, in a window.
Definition: pager.c:2370
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:153
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:1139
#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 432 of file commands.c.

433 {
434  if (!m || !el || STAILQ_EMPTY(el))
435  return;
436 
437  char prompt[8193];
438  char scratch[8192];
439  char buf[8192] = { 0 };
440  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
441  char *err = NULL;
442  int rc;
443  int msg_count = 0;
444 
445  struct EmailNode *en = NULL;
446  STAILQ_FOREACH(en, el, entries)
447  {
448  /* RFC5322 mandates a From: header,
449  * so warn before bouncing messages without one */
450  if (TAILQ_EMPTY(&en->email->env->from))
451  mutt_error(_("Warning: message contains no From: header"));
452 
453  msg_count++;
454  }
455 
456  if (msg_count == 1)
457  mutt_str_copy(prompt, _("Bounce message to: "), sizeof(prompt));
458  else
459  mutt_str_copy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
460 
461  rc = mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS, false, NULL, NULL);
462  if (rc || (buf[0] == '\0'))
463  return;
464 
465  mutt_addrlist_parse2(&al, buf);
466  if (TAILQ_EMPTY(&al))
467  {
468  mutt_error(_("Error parsing address"));
469  return;
470  }
471 
472  mutt_expand_aliases(&al);
473 
474  if (mutt_addrlist_to_intl(&al, &err) < 0)
475  {
476  mutt_error(_("Bad IDN: '%s'"), err);
477  FREE(&err);
478  mutt_addrlist_clear(&al);
479  return;
480  }
481 
482  buf[0] = '\0';
483  mutt_addrlist_write(&al, buf, sizeof(buf), true);
484 
485 #define EXTRA_SPACE (15 + 7 + 2)
486  snprintf(scratch, sizeof(scratch),
487  ngettext("Bounce message to %s?", "Bounce messages to %s?", msg_count), buf);
488 
489  if (mutt_strwidth(scratch) > (MessageWindow->state.cols - EXTRA_SPACE))
490  {
491  mutt_simple_format(prompt, sizeof(prompt), 0, MessageWindow->state.cols - EXTRA_SPACE,
492  JUSTIFY_LEFT, 0, scratch, sizeof(scratch), false);
493  mutt_str_cat(prompt, sizeof(prompt), "...?");
494  }
495  else
496  mutt_str_copy(prompt, scratch, sizeof(prompt));
497 
498  const enum QuadOption c_bounce = cs_subset_quad(NeoMutt->sub, "bounce");
499  if (query_quadoption(c_bounce, prompt) != MUTT_YES)
500  {
501  mutt_addrlist_clear(&al);
503  mutt_message(ngettext("Message not bounced", "Messages not bounced", msg_count));
504  return;
505  }
506 
508 
509  struct Message *msg = NULL;
510  STAILQ_FOREACH(en, el, entries)
511  {
512  msg = mx_msg_open(m, en->email->msgno);
513  if (!msg)
514  {
515  rc = -1;
516  break;
517  }
518 
519  rc = mutt_bounce_message(msg->fp, m, en->email, &al, NeoMutt->sub);
520  mx_msg_close(m, &msg);
521 
522  if (rc < 0)
523  break;
524  }
525 
526  mutt_addrlist_clear(&al);
527  /* If no error, or background, display message. */
528  if ((rc == 0) || (rc == S_BKG))
529  mutt_message(ngettext("Message bounced", "Messages bounced", msg_count));
530 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:299
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_message(...)
Definition: logging.h:83
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:306
#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
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:1185
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
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:230
struct Envelope * env
Envelope information.
Definition: email.h:90
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
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:1249
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:204
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:513
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:716
struct Email * email
Email in the list.
Definition: email.h:127
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mxapi.h:43
#define FREE(x)
Definition: memory.h:40
#define STAILQ_EMPTY(head)
Definition: queue.h:345
List of Emails.
Definition: email.h:125
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:714
#define EXTRA_SPACE
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
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:1139
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:983
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 539 of file commands.c.

541 {
542  if (decode)
543  {
544  *chflags |= CH_DECODE | CH_REORDER;
545  *cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
546 
547  const bool c_print_decode_weed =
548  cs_subset_bool(NeoMutt->sub, "print_decode_weed");
549  const bool c_pipe_decode_weed =
550  cs_subset_bool(NeoMutt->sub, "pipe_decode_weed");
551  if (print ? c_print_decode_weed : c_pipe_decode_weed)
552  {
553  *chflags |= CH_WEED;
554  *cmflags |= MUTT_CM_WEED;
555  }
556 
557  /* Just as with copy-decode, we need to update the mime fields to avoid
558  * confusing programs that may process the email. However, we don't want
559  * to force those fields to appear in printouts. */
560  if (!print)
561  *chflags |= CH_MIME | CH_TXTPLAIN;
562  }
563 
564  if (print)
565  *cmflags |= MUTT_CM_PRINTING;
566 }
#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:71
#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 577 of file commands.c.

579 {
581  CopyHeaderFlags chflags = CH_FROM;
582 
583  pipe_set_flags(decode, print, &cmflags, &chflags);
584 
585  if ((WithCrypto != 0) && decode && e->security & SEC_ENCRYPT)
586  {
588  return;
589  endwin();
590  }
591 
592  const bool own_msg = !msg;
593  if (own_msg)
594  {
595  msg = mx_msg_open(m, e->msgno);
596  if (!msg)
597  {
598  return;
599  }
600  }
601 
602  if (decode)
603  {
604  mutt_parse_mime_message(m, e, msg->fp);
605  }
606 
607  mutt_copy_message(fp, m, e, msg, cmflags, chflags, 0);
608 
609  if (own_msg)
610  {
611  mx_msg_close(m, &msg);
612  }
613 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:587
#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:1185
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
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:846
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1139
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:539
+ 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 629 of file commands.c.

631 {
632  if (!m || !el)
633  return 1;
634 
635  struct EmailNode *en = STAILQ_FIRST(el);
636  if (!en)
637  return 1;
638 
639  int rc = 0;
640  pid_t pid;
641  FILE *fp_out = NULL;
642 
643  if (!STAILQ_NEXT(en, entries))
644  {
645  /* handle a single message */
647 
648  struct Message *msg = mx_msg_open(m, en->email->msgno);
649  if (msg && WithCrypto && decode)
650  {
651  mutt_parse_mime_message(m, en->email, msg->fp);
652  if ((en->email->security & SEC_ENCRYPT) &&
654  {
655  mx_msg_close(m, &msg);
656  return 1;
657  }
658  }
659  mutt_endwin();
660 
661  pid = filter_create(cmd, &fp_out, NULL, NULL);
662  if (pid < 0)
663  {
664  mutt_perror(_("Can't create filter process"));
665  mx_msg_close(m, &msg);
666  return 1;
667  }
668 
669  OptKeepQuiet = true;
670  pipe_msg(m, en->email, msg, fp_out, decode, print);
671  mx_msg_close(m, &msg);
672  mutt_file_fclose(&fp_out);
673  rc = filter_wait(pid);
674  OptKeepQuiet = false;
675  }
676  else
677  {
678  /* handle tagged messages */
679  if ((WithCrypto != 0) && decode)
680  {
681  STAILQ_FOREACH(en, el, entries)
682  {
683  struct Message *msg = mx_msg_open(m, en->email->msgno);
684  if (msg)
685  {
686  mutt_parse_mime_message(m, en->email, msg->fp);
688  mx_msg_close(m, &msg);
689  }
690  if ((en->email->security & SEC_ENCRYPT) &&
692  {
693  return 1;
694  }
695  }
696  }
697 
698  if (split)
699  {
700  STAILQ_FOREACH(en, el, entries)
701  {
703  mutt_endwin();
704  pid = filter_create(cmd, &fp_out, NULL, NULL);
705  if (pid < 0)
706  {
707  mutt_perror(_("Can't create filter process"));
708  return 1;
709  }
710  OptKeepQuiet = true;
711  pipe_msg(m, en->email, NULL, fp_out, decode, print);
712  /* add the message separator */
713  if (sep)
714  fputs(sep, fp_out);
715  mutt_file_fclose(&fp_out);
716  if (filter_wait(pid) != 0)
717  rc = 1;
718  OptKeepQuiet = false;
719  }
720  }
721  else
722  {
723  mutt_endwin();
724  pid = filter_create(cmd, &fp_out, NULL, NULL);
725  if (pid < 0)
726  {
727  mutt_perror(_("Can't create filter process"));
728  return 1;
729  }
730  OptKeepQuiet = true;
731  STAILQ_FOREACH(en, el, entries)
732  {
734  pipe_msg(m, en->email, NULL, fp_out, decode, print);
735  /* add the message separator */
736  if (sep)
737  fputs(sep, fp_out);
738  }
739  mutt_file_fclose(&fp_out);
740  if (filter_wait(pid) != 0)
741  rc = 1;
742  OptKeepQuiet = false;
743  }
744  }
745 
746  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
747  if ((rc != 0) || c_wait_key)
749  return rc;
750 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:587
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
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 mutt_perror(...)
Definition: logging.h:85
#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
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:577
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1185
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
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:568
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
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:601
struct Email * email
Email in the list.
Definition: email.h:127
FILE * fp
pointer to the message data
Definition: mxapi.h:43
List of Emails.
Definition: email.h:125
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:39
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:347
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1139
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 757 of file commands.c.

758 {
759  if (!m || !el)
760  return;
761 
762  struct Buffer *buf = mutt_buffer_pool_get();
763 
764  if (mutt_buffer_get_field(_("Pipe to command: "), buf, MUTT_CMD, false, NULL,
765  NULL, NULL) != 0)
766  {
767  goto cleanup;
768  }
769 
770  if (mutt_buffer_len(buf) == 0)
771  goto cleanup;
772 
774  const bool c_pipe_decode = cs_subset_bool(NeoMutt->sub, "pipe_decode");
775  const bool c_pipe_split = cs_subset_bool(NeoMutt->sub, "pipe_split");
776  const char *const c_pipe_sep = cs_subset_string(NeoMutt->sub, "pipe_sep");
777  pipe_message(m, el, mutt_buffer_string(buf), c_pipe_decode, false, c_pipe_split, c_pipe_sep);
778 
779 cleanup:
781 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
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:255
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:629
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:295
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:321
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 788 of file commands.c.

789 {
790  if (!m || !el)
791  return;
792 
793  const enum QuadOption c_print = cs_subset_quad(NeoMutt->sub, "print");
794  const char *const c_print_command =
795  cs_subset_string(NeoMutt->sub, "print_command");
796  if (c_print && !c_print_command)
797  {
798  mutt_message(_("No printing command has been defined"));
799  return;
800  }
801 
802  int msg_count = 0;
803  struct EmailNode *en = NULL;
804  STAILQ_FOREACH(en, el, entries)
805  {
806  msg_count++;
807  }
808 
809  if (query_quadoption(c_print, (msg_count == 1) ?
810  _("Print message?") :
811  _("Print tagged messages?")) != MUTT_YES)
812  {
813  return;
814  }
815 
816  const bool c_print_decode = cs_subset_bool(NeoMutt->sub, "print_decode");
817  const bool c_print_split = cs_subset_bool(NeoMutt->sub, "print_split");
818  if (pipe_message(m, el, c_print_command, c_print_decode, true, c_print_split, "\f") == 0)
819  mutt_message(ngettext("Message printed", "Messages printed", msg_count));
820  else
821  {
822  mutt_message(ngettext("Message could not be printed",
823  "Messages could not be printed", msg_count));
824  }
825 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
#define mutt_message(...)
Definition: logging.h:83
#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:629
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:204
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:513
List of Emails.
Definition: email.h:125
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
numSort type, see SortType

Definition at line 832 of file commands.c.

833 {
834  enum SortType sort = SORT_DATE;
835 
836  switch (mutt_multi_choice(reverse ?
837  /* L10N: The highlighted letters must match the "Sort" options */
838  _("Rev-Sort "
839  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
840  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?") :
841  /* L10N: The highlighted letters must match the "Rev-Sort" options */
842  _("Sort "
843  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
844  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?"),
845  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
846  _("dfrsotuzcpl")))
847  {
848  case -1: /* abort - don't resort */
849  return -1;
850 
851  case 1: /* (d)ate */
852  sort = SORT_DATE;
853  break;
854 
855  case 2: /* (f)rm */
856  sort = SORT_FROM;
857  break;
858 
859  case 3: /* (r)ecv */
860  sort = SORT_RECEIVED;
861  break;
862 
863  case 4: /* (s)ubj */
864  sort = SORT_SUBJECT;
865  break;
866 
867  case 5: /* t(o) */
868  sort = SORT_TO;
869  break;
870 
871  case 6: /* (t)hread */
872  sort = SORT_THREADS;
873  break;
874 
875  case 7: /* (u)nsort */
876  sort = SORT_ORDER;
877  break;
878 
879  case 8: /* si(z)e */
880  sort = SORT_SIZE;
881  break;
882 
883  case 9: /* s(c)ore */
884  sort = SORT_SCORE;
885  break;
886 
887  case 10: /* s(p)am */
888  sort = SORT_SPAM;
889  break;
890 
891  case 11: /* (l)abel */
892  sort = SORT_LABEL;
893  break;
894  }
895  if (reverse)
896  sort |= SORT_REVERSE;
897 
898  int rc = cs_subset_str_native_set(NeoMutt->sub, "sort", sort, NULL);
899 
900  return ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE));
901 }
#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
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:292
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
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:824
Sort by email threads.
Definition: sort2.h: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
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
Sort by the email&#39;s subject.
Definition: sort2.h:46
+ 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 908 of file commands.c.

909 {
910  char buf[1024];
911 
912  buf[0] = '\0';
913  if (mutt_get_field(_("Shell command: "), buf, sizeof(buf), MUTT_CMD, false, NULL, NULL) != 0)
914  {
915  return false;
916  }
917 
918  const char *const c_shell = cs_subset_string(NeoMutt->sub, "shell");
919  if ((buf[0] == '\0') && c_shell)
920  mutt_str_copy(buf, c_shell, sizeof(buf));
921  if (buf[0] == '\0')
922  {
923  return false;
924  }
925 
927  mutt_endwin();
928  fflush(stdout);
929  int rc = mutt_system(buf);
930  if (rc == -1)
931  mutt_debug(LL_DEBUG1, "Error running \"%s\"", buf);
932 
933  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
934  if ((rc != 0) || c_wait_key)
936 
937  return true;
938 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
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:306
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:230
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:56
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:568
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:601
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:716
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
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 943 of file commands.c.

944 {
945  char buf[1024] = { 0 };
946 
948  window_redraw(RootWindow, true);
949  /* if enter is pressed after : with no command, just return */
950  if ((mutt_get_field(":", buf, sizeof(buf), MUTT_COMMAND, false, NULL, NULL) != 0) ||
951  (buf[0] == '\0'))
952  {
953  return;
954  }
955 
956  struct Buffer err = mutt_buffer_make(256);
957 
958  /* check if buf is a valid icommand, else fall back quietly to parse_rc_lines */
959  enum CommandResult rc = mutt_parse_icommand(buf, &err);
960  if (!mutt_buffer_is_empty(&err))
961  {
962  /* since errbuf could potentially contain printf() sequences in it,
963  * we must call mutt_error() in this fashion so that vsprintf()
964  * doesn't expect more arguments that we passed */
965  if (rc == MUTT_CMD_ERROR)
966  mutt_error("%s", err.data);
967  else
968  mutt_warning("%s", err.data);
969  }
970  else if (rc != MUTT_CMD_SUCCESS)
971  {
972  rc = mutt_parse_rc_line(buf, &err);
973  if (!mutt_buffer_is_empty(&err))
974  {
975  if (rc == MUTT_CMD_SUCCESS) /* command succeeded with message */
976  mutt_message("%s", err.data);
977  else if (rc == MUTT_CMD_ERROR)
978  mutt_error("%s", err.data);
979  else if (rc == MUTT_CMD_WARNING)
980  mutt_warning("%s", err.data);
981  }
982  }
983  /* else successful command */
984 
985  mutt_buffer_dealloc(&err);
986 }
#define mutt_warning(...)
Definition: logging.h:82
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
void window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:760
#define mutt_message(...)
Definition: logging.h:83
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:306
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:1038
enum CommandResult mutt_parse_icommand(char *line, struct Buffer *err)
Parse an informational command.
Definition: icommands.c:77
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
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:45
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:43
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_error(...)
Definition: logging.h:84
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
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 992 of file commands.c.

993 {
994  const char *pfx = NULL;
995  char buf[128];
996 
997  struct AddressList *al = mutt_get_address(env, &pfx);
998  if (!al)
999  return;
1000 
1001  /* Note: We don't convert IDNA to local representation this time.
1002  * That is intentional, so the user has an opportunity to copy &
1003  * paste the on-the-wire form of the address to other, IDN-unable
1004  * software. */
1005  buf[0] = '\0';
1006  mutt_addrlist_write(al, buf, sizeof(buf), false);
1007  mutt_message("%s: %s", pfx, buf);
1008 }
#define mutt_message(...)
Definition: logging.h:83
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
Definition: alias.c:331
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 1017 of file commands.c.

1019 {
1020  *cmflags = MUTT_CM_NO_FLAGS;
1021  *chflags = CH_UPDATE_LEN;
1022 
1023  const bool need_decrypt =
1024  (transform_opt == TRANSFORM_DECRYPT) && (e->security & SEC_ENCRYPT);
1025  const bool want_pgp = (WithCrypto & APPLICATION_PGP);
1026  const bool want_smime = (WithCrypto & APPLICATION_SMIME);
1027  const bool is_pgp = mutt_is_application_pgp(e->body) & SEC_ENCRYPT;
1028  const bool is_smime = mutt_is_application_smime(e->body) & SEC_ENCRYPT;
1029 
1030  if (need_decrypt && want_pgp && mutt_is_multipart_encrypted(e->body))
1031  {
1032  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
1033  *cmflags = MUTT_CM_DECODE_PGP;
1034  }
1035  else if (need_decrypt && want_pgp && is_pgp)
1036  {
1037  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN;
1038  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1039  }
1040  else if (need_decrypt && want_smime && is_smime)
1041  {
1042  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
1043  *cmflags = MUTT_CM_DECODE_SMIME;
1044  }
1045  else if (transform_opt == TRANSFORM_DECODE)
1046  {
1047  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN | CH_DECODE; // then decode RFC2047
1048  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1049  const bool c_copy_decode_weed =
1050  cs_subset_bool(NeoMutt->sub, "copy_decode_weed");
1051  if (c_copy_decode_weed)
1052  {
1053  *chflags |= CH_WEED; // and respect $weed
1054  *cmflags |= MUTT_CM_WEED;
1055  }
1056  }
1057 }
#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:71
#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:622
#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:459
#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:564
#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 1069 of file commands.c.

1071 {
1073  CopyHeaderFlags chflags = CH_NO_FLAGS;
1074  int rc;
1075 
1076  set_copy_flags(e, transform_opt, &cmflags, &chflags);
1077 
1078  struct Message *msg = mx_msg_open(m_src, e->msgno);
1079  if (msg && transform_opt != TRANSFORM_NONE)
1080  {
1081  mutt_parse_mime_message(m_src, e, msg->fp);
1082  }
1083 
1084  rc = mutt_append_message(m_dst, m_src, e, msg, cmflags, chflags);
1085  mx_msg_close(m_src, &msg);
1086  if (rc != 0)
1087  return rc;
1088 
1089  if (save_opt == SAVE_MOVE)
1090  {
1091  mutt_set_flag(m_src, e, MUTT_DELETE, true);
1092  mutt_set_flag(m_src, e, MUTT_PURGE, true);
1093  const bool c_delete_untag = cs_subset_bool(NeoMutt->sub, "delete_untag");
1094  if (c_delete_untag)
1095  mutt_set_flag(m_src, e, MUTT_TAG, false);
1096  }
1097 
1098  return 0;
1099 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:587
#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:71
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:916
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:1185
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:1017
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:1139
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 1110 of file commands.c.

1112 {
1113  if (!el || STAILQ_EMPTY(el))
1114  return -1;
1115 
1116  int rc = -1;
1117  int tagged_progress_count = 0;
1118  unsigned int msg_count = 0;
1119 
1120  struct Buffer *buf = mutt_buffer_pool_get();
1121  struct Progress progress;
1122  struct stat st;
1123  struct EmailNode *en = NULL;
1124 
1125  STAILQ_FOREACH(en, el, entries)
1126  {
1127  msg_count++;
1128  }
1129  en = STAILQ_FIRST(el);
1130 
1131  const SecurityFlags security_flags = WithCrypto ? en->email->security : SEC_NO_FLAGS;
1132  const bool is_passphrase_needed = security_flags & SEC_ENCRYPT;
1133 
1134  const char *prompt = NULL;
1135  const char *progress_msg = NULL;
1136 
1137  // Set prompt and progress_msg
1138  switch (save_opt)
1139  {
1140  case SAVE_COPY:
1141  // L10N: Progress meter message when copying tagged messages
1142  progress_msg = (msg_count > 1) ? _("Copying tagged messages...") : NULL;
1143  switch (transform_opt)
1144  {
1145  case TRANSFORM_NONE:
1146  prompt = (msg_count > 1) ? _("Copy tagged to mailbox") : _("Copy to mailbox");
1147  break;
1148  case TRANSFORM_DECRYPT:
1149  prompt = (msg_count > 1) ? _("Decrypt-copy tagged to mailbox") :
1150  _("Decrypt-copy to mailbox");
1151  break;
1152  case TRANSFORM_DECODE:
1153  prompt = (msg_count > 1) ? _("Decode-copy tagged to mailbox") :
1154  _("Decode-copy to mailbox");
1155  break;
1156  }
1157  break;
1158 
1159  case SAVE_MOVE:
1160  // L10N: Progress meter message when saving tagged messages
1161  progress_msg = (msg_count > 1) ? _("Saving tagged messages...") : NULL;
1162  switch (transform_opt)
1163  {
1164  case TRANSFORM_NONE:
1165  prompt = (msg_count > 1) ? _("Save tagged to mailbox") : _("Save to mailbox");
1166  break;
1167  case TRANSFORM_DECRYPT:
1168  prompt = (msg_count > 1) ? _("Decrypt-save tagged to mailbox") :
1169  _("Decrypt-save to mailbox");
1170  break;
1171  case TRANSFORM_DECODE:
1172  prompt = (msg_count > 1) ? _("Decode-save tagged to mailbox") :
1173  _("Decode-save to mailbox");
1174  break;
1175  }
1176  break;
1177  }
1178 
1180  mutt_default_save(buf->data, buf->dsize, en->email);
1181  mutt_buffer_fix_dptr(buf);
1183 
1184  if (mutt_buffer_enter_fname(prompt, buf, false, NULL, false, NULL, NULL,
1185  MUTT_SEL_NO_FLAGS) == -1)
1186  goto cleanup;
1187 
1188  size_t pathlen = mutt_buffer_len(buf);
1189  if (pathlen == 0)
1190  goto cleanup;
1191 
1192  /* Trim any trailing '/' */
1193  if (buf->data[pathlen - 1] == '/')
1194  buf->data[pathlen - 1] = '\0';
1195 
1196  /* This is an undocumented feature of ELM pointed out to me by Felix von
1197  * Leitner <leitner@prz.fu-berlin.de> */
1198  if (mutt_buffer_len(&LastSaveFolder) == 0)
1200  if (mutt_str_equal(mutt_buffer_string(buf), "."))
1202  else
1204 
1206 
1207  /* check to make sure that this file is really the one the user wants */
1208  if (mutt_save_confirm(mutt_buffer_string(buf), &st) != 0)
1209  goto cleanup;
1210 
1211  if (is_passphrase_needed && (transform_opt != TRANSFORM_NONE) &&
1212  !crypt_valid_passphrase(security_flags))
1213  {
1214  rc = -1;
1215  goto errcleanup;
1216  }
1217 
1218  mutt_message(_("Copying to %s..."), mutt_buffer_string(buf));
1219 
1220 #ifdef USE_IMAP
1221  enum MailboxType mailbox_type = imap_path_probe(mutt_buffer_string(buf), NULL);
1222  if ((m->type == MUTT_IMAP) && (transform_opt == TRANSFORM_NONE) && (mailbox_type == MUTT_IMAP))
1223  {
1224  rc = imap_copy_messages(m, el, mutt_buffer_string(buf), save_opt);
1225  switch (rc)
1226  {
1227  /* success */
1228  case 0:
1229  mutt_clear_error();
1230  rc = 0;
1231  goto cleanup;
1232  /* non-fatal error: continue to fetch/append */
1233  case 1:
1234  break;
1235  /* fatal error, abort */
1236  case -1:
1237  goto errcleanup;
1238  }
1239  }
1240 #endif
1241 
1243  struct Mailbox *m_save = mx_path_resolve(mutt_buffer_string(buf));
1244  bool old_append = m_save->append;
1245  OpenMailboxFlags mbox_flags = MUTT_NEWFOLDER;
1246  /* Display a tagged message progress counter, rather than (for
1247  * IMAP) a per-message progress counter */
1248  if (msg_count > 1)
1249  mbox_flags |= MUTT_QUIET;
1250  if (!mx_mbox_open(m_save, mbox_flags))
1251  {
1252  rc = -1;
1253  mailbox_free(&m_save);
1254  goto errcleanup;
1255  }
1256  m_save->append = true;
1257 
1258 #ifdef USE_COMP_MBOX
1259  /* If we're saving to a compressed mailbox, the stats won't be updated
1260  * until the next open. Until then, improvise. */
1261  struct Mailbox *m_comp = NULL;
1262  if (m_save->compress_info)
1263  {
1264  m_comp = mailbox_find(m_save->realpath);
1265  }
1266  /* We probably haven't been opened yet */
1267  if (m_comp && (m_comp->msg_count == 0))
1268  m_comp = NULL;
1269 #endif
1270  if (msg_count == 1)
1271  {
1272  rc = mutt_save_message_ctx(m, en->email, save_opt, transform_opt, m_save);
1273  if (rc != 0)
1274  {
1275  mx_mbox_close(m_save);
1276  m_save->append = old_append;
1277  goto errcleanup;
1278  }
1279 #ifdef USE_COMP_MBOX
1280  if (m_comp)
1281  {
1282  m_comp->msg_count++;
1283  if (!en->email->read)
1284  {
1285  m_comp->msg_unread++;
1286  if (!en->email->old)
1287  m_comp->msg_new++;
1288  }
1289  if (en->email->flagged)
1290  m_comp->msg_flagged++;
1291  }
1292 #endif
1293  }
1294  else
1295  {
1296  rc = 0;
1297  mutt_progress_init(&progress, progress_msg, MUTT_PROGRESS_WRITE, msg_count);
1298 
1299 #ifdef USE_NOTMUCH
1300  if (m->type == MUTT_NOTMUCH)
1301  nm_db_longrun_init(m, true);
1302 #endif
1303  STAILQ_FOREACH(en, el, entries)
1304  {
1305  mutt_progress_update(&progress, ++tagged_progress_count, -1);
1307  rc = mutt_save_message_ctx(m, en->email, save_opt, transform_opt, m_save);
1308  if (rc != 0)
1309  break;
1310 #ifdef USE_COMP_MBOX
1311  if (m_comp)
1312  {
1313  struct Email *e2 = en->email;
1314  m_comp->msg_count++;
1315  if (!e2->read)
1316  {
1317  m_comp->msg_unread++;
1318  if (!e2->old)
1319  m_comp->msg_new++;
1320  }
1321  if (e2->flagged)
1322  m_comp->msg_flagged++;
1323  }
1324 #endif
1325  }
1326 #ifdef USE_NOTMUCH
1327  if (m->type == MUTT_NOTMUCH)
1328  nm_db_longrun_done(m);
1329 #endif
1330  if (rc != 0)
1331  {
1332  mx_mbox_close(m_save);
1333  m_save->append = old_append;
1334  goto errcleanup;
1335  }
1336  }
1337 
1338  const bool need_mailbox_cleanup =
1339  ((m_save->type == MUTT_MBOX) || (m_save->type == MUTT_MMDF));
1340 
1341  mx_mbox_close(m_save);
1342  m_save->append = old_append;
1343 
1344  if (need_mailbox_cleanup)
1346 
1347  mutt_clear_error();
1348  rc = 0;
1349 
1350 errcleanup:
1351  if (rc != 0)
1352  {
1353  switch (save_opt)
1354  {
1355  case SAVE_MOVE:
1356  if (msg_count > 1)
1357  {
1358  // L10N: Message when an index tagged save operation fails for some reason
1359  mutt_error(_("Error saving tagged messages"));
1360  }
1361  else
1362  {
1363  // L10N: Message when an index/pager save operation fails for some reason
1364  mutt_error(_("Error saving message"));
1365  }
1366  break;
1367  case SAVE_COPY:
1368  if (msg_count > 1)
1369  {
1370  // L10N: Message when an index tagged copy operation fails for some reason
1371  mutt_error(_("Error copying tagged messages"));
1372  }
1373  else
1374  {
1375  // L10N: Message when an index/pager copy operation fails for some reason
1376  mutt_error(_("Error copying message"));
1377  }
1378  break;
1379  }
1380  }
1381 
1382 cleanup:
1384  return rc;
1385 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
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:303
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
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2400
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 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
#define mutt_message(...)
Definition: logging.h:83
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:1069
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
Progress tracks elements, according to $write_inc
Definition: progress.h:37
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:103
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:609
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.h:44
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:602
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:1629
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:134
size_t dsize
Length of data.
Definition: buffer.h:37
bool read
Email is read.
Definition: email.h:51
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:211
bool old
Email is seen, but unread.
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
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:86
&#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:349
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:152
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
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:659
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:321
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
struct Email * email
Email in the list.
Definition: email.h:127
#define mutt_error(...)
Definition: logging.h:84
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1667
#define STAILQ_EMPTY(head)
Definition: queue.h:345
Decode message.
Definition: commands.h:43
List of Emails.
Definition: email.h:125
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:347
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 1396 of file commands.c.

1397 {
1398  char buf[1024];
1399  char obuf[1024];
1400  char tmp[256];
1401  char charset[256];
1402 
1403  bool charset_changed = false;
1404  bool type_changed = false;
1405  bool structure_changed = false;
1406 
1407  char *cp = mutt_param_get(&b->parameter, "charset");
1408  mutt_str_copy(charset, cp, sizeof(charset));
1409 
1410  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
1411  mutt_str_copy(obuf, buf, sizeof(obuf));
1412  if (!TAILQ_EMPTY(&b->parameter))
1413  {
1414  size_t l = strlen(buf);
1415  struct Parameter *np = NULL;
1416  TAILQ_FOREACH(np, &b->parameter, entries)
1417  {
1418  mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
1419  l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
1420  if (l >= sizeof(buf))
1421  {
1422  // L10N: e.g. "text/plain; charset=UTF-8; ..."
1423  mutt_error(_("Content type is too long"));
1424  return false;
1425  }
1426  }
1427  }
1428 
1429  if ((mutt_get_field("Content-Type: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
1430  false, NULL, NULL) != 0) ||
1431  (buf[0] == '\0'))
1432  {
1433  return false;
1434  }
1435 
1436  /* clean up previous junk */
1438  FREE(&b->subtype);
1439 
1440  mutt_parse_content_type(buf, b);
1441 
1442  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1443  type_changed = !mutt_istr_equal(tmp, obuf);
1444  charset_changed =
1445  !mutt_istr_equal(charset, mutt_param_get(&b->parameter, "charset"));
1446 
1447  /* if in send mode, check for conversion - current setting is default. */
1448 
1449  if (!e && (b->type == TYPE_TEXT) && charset_changed)
1450  {
1451  snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
1452  mutt_param_get(&b->parameter, "charset"));
1453  enum QuadOption ans = mutt_yesorno(tmp, b->noconv ? MUTT_NO : MUTT_YES);
1454  if (ans != MUTT_ABORT)
1455  b->noconv = (ans == MUTT_NO);
1456  }
1457 
1458  /* inform the user */
1459 
1460  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1461  if (type_changed)
1462  mutt_message(_("Content-Type changed to %s"), tmp);
1463  if ((b->type == TYPE_TEXT) && charset_changed)
1464  {
1465  if (type_changed)
1466  mutt_sleep(1);
1467  mutt_message(b->noconv ? _("Character set changed to %s; not converting") :
1468  _("Character set changed to %s; converting"),
1469  mutt_param_get(&b->parameter, "charset"));
1470  }
1471 
1472  b->force_charset |= charset_changed;
1473 
1474  if (!is_multipart(b) && b->parts)
1475  {
1476  structure_changed = true;
1477  mutt_body_free(&b->parts);
1478  }
1479  if (!mutt_is_message_type(b->type, b->subtype) && b->email)
1480  {
1481  structure_changed = true;
1482  b->email->body = NULL;
1483  email_free(&b->email);
1484  }
1485 
1486  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
1487  {
1488  structure_changed = true;
1489  mutt_parse_part(fp, b);
1490  }
1491 
1492  if ((WithCrypto != 0) && e)
1493  {
1494  if (e->body == b)
1495  e->security = SEC_NO_FLAGS;
1496 
1497  e->security |= crypt_query(b);
1498  }
1499 
1500  return structure_changed | type_changed;
1501 }
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:718
struct Body * body
List of MIME parts.
Definition: email.h:91
#define is_multipart(body)
Definition: mime.h:82
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:74
#define mutt_message(...)
Definition: logging.h:83
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:306
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
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:375
#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:883
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
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:1676
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:716
#define mutt_error(...)
Definition: logging.h:84
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:697
#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:714
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 1509 of file commands.c.

1510 {
1511  bool rc = false;
1512 
1514 
1515  struct Message *msg = mx_msg_open(m, e->msgno);
1516  if (msg)
1517  {
1518  mutt_parse_mime_message(m, e, msg->fp);
1519  if (crypt_pgp_check_traditional(msg->fp, e->body, false))
1520  {
1521  e->security = crypt_query(e->body);
1522  rc = true;
1523  }
1524 
1526  mx_msg_close(m, &msg);
1527  }
1528  return rc;
1529 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:587
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:1185
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:697
#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:1139
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 1537 of file commands.c.

1538 {
1539  bool rc = false;
1540  struct EmailNode *en = NULL;
1541  STAILQ_FOREACH(en, el, entries)
1542  {
1543  if (!(en->email->security & PGP_TRADITIONAL_CHECKED))
1544  rc = check_traditional_pgp(m, en->email) || rc;
1545  }
1546 
1547  return rc;
1548 }
static bool check_traditional_pgp(struct Mailbox *m, struct Email *e)
Check for an inline PGP content.
Definition: commands.c:1509
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
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:127
List of Emails.
Definition: email.h:125
#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 1553 of file commands.c.

1554 {
1556 }
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 83 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 86 of file commands.c.