NeoMutt  2019-12-07-60-g0cfa53
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 <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "commands.h"
#include "alias.h"
#include "context.h"
#include "copy.h"
#include "filter.h"
#include "format_flags.h"
#include "globals.h"
#include "hdrline.h"
#include "hook.h"
#include "icommands.h"
#include "keymap.h"
#include "mutt_commands.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "mutt_menu.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
#include "options.h"
#include "pager.h"
#include "protos.h"
#include "sendlib.h"
#include "sort.h"
#include "imap/imap.h"
#include "notmuch/mutt_notmuch.h"
#include <libintl.h>
#include "autocrypt/autocrypt.h"
+ Include dependency graph for commands.c:

Go to the source code of this file.

Macros

#define EXTRA_SPACE   (15 + 7 + 2)
 

Functions

static void process_protected_headers (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, FILE *fp, bool decode, bool print)
 Pipe a message. More...
 
static int pipe_message (struct Mailbox *m, struct EmailList *el, 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...
 
int mutt_select_sort (bool reverse)
 Ask the user for a sort method. More...
 
void 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, bool decode, bool decrypt, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
 Set the flags for a message copy. More...
 
int mutt_save_message_ctx (struct Email *e, bool delete_original, bool decode, bool decrypt, struct Mailbox *m)
 Save a message to a given mailbox. More...
 
int mutt_save_message (struct Mailbox *m, struct EmailList *el, bool delete_original, bool decode, bool decrypt)
 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 Email *e, MuttRedrawFlags *redraw)
 Check for an inline PGP content. More...
 
bool mutt_check_traditional_pgp (struct EmailList *el, MuttRedrawFlags *redraw)
 Check if a message has inline PGP content. More...
 
void mutt_check_stats (void)
 Forcibly update mailbox stats. More...
 

Variables

unsigned char C_CryptVerifySig
 Config: Verify PGP or SMIME signatures. More...
 
char * C_DisplayFilter
 Config: External command to pre-process an email before display. More...
 
bool C_PipeDecode
 Config: Decode the message when piping it. More...
 
char * C_PipeSep
 Config: Separator to add between multiple piped messages. More...
 
bool C_PipeSplit
 Config: Run the pipe command on each message separately. More...
 
bool C_PrintDecode
 Config: Decode message before printing it. More...
 
bool C_PrintSplit
 Config: Print multiple messages separately. More...
 
bool C_PromptAfter
 Config: Pause after running an external pager. More...
 
static const char * ExtPagerProgress = "all"
 
static char LastSaveFolder [PATH_MAX] = ""
 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

◆ process_protected_headers()

static void process_protected_headers ( struct Email e)
static

Get the protected header and update the index.

Parameters
eEmail to update

Definition at line 103 of file commands.c.

104 {
105  struct Envelope *prot_headers = NULL;
106  regmatch_t pmatch[1];
107 
108 #ifdef USE_AUTOCRYPT
110  return;
111 #else
113  return;
114 #endif
115 
116  /* Grab protected headers to update in the index */
117  if (e->security & SEC_SIGN)
118  {
119  /* Don't update on a bad signature.
120  *
121  * This is a simplification. It's possible the headers are in the
122  * encrypted part of a nested encrypt/signed. But properly handling that
123  * case would require more complexity in the decryption handlers, which
124  * I'm not sure is worth it. */
125  if (!(e->security & SEC_GOODSIGN))
126  return;
127 
129  {
130  prot_headers = e->content->parts->mime_headers;
131  }
133  {
134  prot_headers = e->content->mime_headers;
135  }
136  }
137  if (!prot_headers && (e->security & SEC_ENCRYPT))
138  {
139  if (((WithCrypto & APPLICATION_PGP) != 0) &&
142  {
143  prot_headers = e->content->mime_headers;
144  }
145  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->content))
146  {
147  prot_headers = e->content->mime_headers;
148  }
149  }
150 
151  /* Update protected headers in the index and header cache. */
152  if (C_CryptProtectedHeadersRead && prot_headers && prot_headers->subject &&
153  mutt_str_strcmp(e->env->subject, prot_headers->subject))
154  {
155  if (Context->mailbox->subj_hash && e->env->real_subj)
157 
158  mutt_str_replace(&e->env->subject, prot_headers->subject);
159  FREE(&e->env->disp_subj);
160  if (mutt_regex_capture(C_ReplyRegex, e->env->subject, 1, pmatch))
161  e->env->real_subj = e->env->subject + pmatch[0].rm_eo;
162  else
163  e->env->real_subj = e->env->subject;
164 
165  if (Context->mailbox->subj_hash)
167 
169 
170  /* Also persist back to the message headers if this is set */
172  {
174  e->changed = true;
175  Context->mailbox->changed = true;
176  }
177  }
178 
179 #ifdef USE_AUTOCRYPT
180  if (C_Autocrypt && (e->security & SEC_ENCRYPT) && prot_headers && prot_headers->autocrypt_gossip)
181  {
182  mutt_autocrypt_process_gossip_header(e, prot_headers);
183  }
184 #endif
185 }
The "current" mailbox.
Definition: context.h:36
void mutt_hash_delete(struct Hash *table, const char *strkey, const void *data)
Remove an element from a Hash table.
Definition: hash.c:443
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:68
struct Body * content
List of MIME parts.
Definition: email.h:90
int mutt_autocrypt_process_gossip_header(struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:406
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:475
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:1674
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#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
struct Mailbox * mailbox
Definition: context.h:50
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:124
struct Envelope * env
Envelope information.
Definition: email.h:89
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:410
struct Regex * C_ReplyRegex
Config: Regex to match message reply subjects like "re: ".
Definition: email_globals.c:37
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptProtectedHeadersSave
Config: Save the cleartext Subject with the headers.
Definition: globals.h:271
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:512
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:616
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:270
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
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:594
char * subject
Email&#39;s subject.
Definition: envelope.h:66
struct Hash * subj_hash
Hash table by subject.
Definition: mailbox.h:127
#define FREE(x)
Definition: memory.h:40
bool changed
Mailbox has been modified.
Definition: mailbox.h:113
struct HashElem * mutt_hash_insert(struct Hash *table, const char *strkey, void *data)
Add a new element to the Hash table (with string keys)
Definition: hash.c:351
#define WithCrypto
Definition: ncrypt.h:160
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
The header of an Email.
Definition: envelope.h:54
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 198 of file commands.c.

201 {
202  int rc = 0;
203  bool builtin = false;
205  CopyHeaderFlags chflags;
206  pid_t filterpid = -1;
207  struct Buffer *tempfile = NULL;
208  int res;
209 
212 
213  char columns[16];
214  snprintf(columns, sizeof(columns), "%d", win_pager->state.cols);
215  mutt_envlist_set("COLUMNS", columns, true);
216 
217  /* see if crypto is needed for this message. if so, we should exit curses */
218  if ((WithCrypto != 0) && e->security)
219  {
220  if (e->security & SEC_ENCRYPT)
221  {
222  if (e->security & APPLICATION_SMIME)
225  goto cleanup;
226 
227  cmflags |= MUTT_CM_VERIFY;
228  }
229  else if (e->security & SEC_SIGN)
230  {
231  /* find out whether or not the verify signature */
232  /* L10N: Used for the $crypt_verify_sig prompt */
233  if (query_quadoption(C_CryptVerifySig, _("Verify signature?")) == MUTT_YES)
234  {
235  cmflags |= MUTT_CM_VERIFY;
236  }
237  }
238  }
239 
240  if (cmflags & MUTT_CM_VERIFY || e->security & SEC_ENCRYPT)
241  {
242  if (e->security & APPLICATION_PGP)
243  {
244  if (!TAILQ_EMPTY(&e->env->from))
246 
248  }
249 
250  if (e->security & APPLICATION_SMIME)
252  }
253 
254  FILE *fp_filter_out = NULL;
255  tempfile = mutt_buffer_pool_get();
256  mutt_buffer_mktemp(tempfile);
257  FILE *fp_out = mutt_file_fopen(mutt_b2s(tempfile), "w");
258  if (!fp_out)
259  {
260  mutt_error(_("Could not create temporary file"));
261  goto cleanup;
262  }
263 
264  if (C_DisplayFilter)
265  {
266  fp_filter_out = fp_out;
267  fp_out = NULL;
268  filterpid = mutt_create_filter_fd(C_DisplayFilter, &fp_out, NULL, NULL, -1,
269  fileno(fp_filter_out), -1);
270  if (filterpid < 0)
271  {
272  mutt_error(_("Can't create display filter"));
273  mutt_file_fclose(&fp_filter_out);
274  unlink(mutt_b2s(tempfile));
275  goto cleanup;
276  }
277  }
278 
279  if (!C_Pager || (mutt_str_strcmp(C_Pager, "builtin") == 0))
280  builtin = true;
281  else
282  {
283  char buf[1024];
284  struct HdrFormatInfo hfi;
285 
286  hfi.ctx = Context;
287  hfi.mailbox = m;
288  hfi.pager_progress = ExtPagerProgress;
289  hfi.email = e;
290  mutt_make_string_info(buf, sizeof(buf), win_pager->state.cols,
292  fputs(buf, fp_out);
293  fputs("\n\n", fp_out);
294  }
295 
296  chflags = (C_Weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) | CH_DECODE | CH_FROM | CH_DISPLAY;
297 #ifdef USE_NOTMUCH
298  if (m->magic == MUTT_NOTMUCH)
299  chflags |= CH_VIRTUAL;
300 #endif
301  res = mutt_copy_message(fp_out, m, e, cmflags, chflags, win_pager->state.cols);
302 
303  if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (res < 0))
304  {
305  mutt_error(_("Could not copy message"));
306  if (fp_filter_out)
307  {
308  mutt_wait_filter(filterpid);
309  mutt_file_fclose(&fp_filter_out);
310  }
311  mutt_file_unlink(mutt_b2s(tempfile));
312  goto cleanup;
313  }
314 
315  if (fp_filter_out && (mutt_wait_filter(filterpid) != 0))
317 
318  mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
319 
320  if (WithCrypto)
321  {
322  /* update crypto information for this message */
323  e->security &= ~(SEC_GOODSIGN | SEC_BADSIGN);
324  e->security |= crypt_query(e->content);
325 
326  /* Remove color cache for this message, in case there
327  * are color patterns for both ~g and ~V */
328  e->pair = 0;
329 
330  /* Process protected headers and autocrypt gossip headers */
332  }
333 
334  if (builtin)
335  {
336  if ((WithCrypto != 0) && (e->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
337  {
338  if (e->security & SEC_GOODSIGN)
339  {
340  if (crypt_smime_verify_sender(m, e) == 0)
341  mutt_message(_("S/MIME signature successfully verified"));
342  else
343  mutt_error(_("S/MIME certificate owner does not match sender"));
344  }
345  else if (e->security & SEC_PARTSIGN)
346  mutt_message(_("Warning: Part of this message has not been signed"));
347  else if (e->security & SEC_SIGN || e->security & SEC_BADSIGN)
348  mutt_error(_("S/MIME signature could NOT be verified"));
349  }
350 
351  if ((WithCrypto != 0) && (e->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
352  {
353  if (e->security & SEC_GOODSIGN)
354  mutt_message(_("PGP signature successfully verified"));
355  else if (e->security & SEC_PARTSIGN)
356  mutt_message(_("Warning: Part of this message has not been signed"));
357  else if (e->security & SEC_SIGN)
358  mutt_message(_("PGP signature could NOT be verified"));
359  }
360 
361  struct Pager info = { 0 };
362  /* Invoke the builtin pager */
363  info.email = e;
364  info.ctx = Context;
365  info.win_ibar = win_ibar;
366  info.win_index = win_index;
367  info.win_pbar = win_pbar;
368  info.win_pager = win_pager;
369  rc = mutt_pager(NULL, mutt_b2s(tempfile), MUTT_PAGER_MESSAGE, &info);
370  }
371  else
372  {
373  mutt_endwin();
374 
375  struct Buffer *cmd = mutt_buffer_pool_get();
376  mutt_buffer_printf(cmd, "%s %s", NONULL(C_Pager), mutt_b2s(tempfile));
377  int r = mutt_system(mutt_b2s(cmd));
378  if (r == -1)
379  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
380  unlink(mutt_b2s(tempfile));
382 
383  if (!OptNoCurses)
384  keypad(stdscr, true);
385  if (r != -1)
386  mutt_set_flag(m, e, MUTT_READ, true);
387  if ((r != -1) && C_PromptAfter)
388  {
389  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
390  rc = km_dokey(MENU_PAGER);
391  }
392  else
393  rc = 0;
394  }
395 
396 cleanup:
397  mutt_envlist_unset("COLUMNS");
398  mutt_buffer_pool_release(&tempfile);
399  return rc;
400 }
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:617
struct Context * ctx
Definition: hdrline.h:47
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:78
struct MuttWindow * win_index
Definition: pager.h:74
#define NONULL(x)
Definition: string2.h:37
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
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
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
#define mutt_message(...)
Definition: logging.h:83
#define MUTT_PAGER_MESSAGE
Definition: pager.h:58
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
String manipulation buffer.
Definition: buffer.h:33
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:810
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:834
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:55
#define _(a)
Definition: message.h:28
static const char * ExtPagerProgress
Definition: commands.c:94
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:46
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:460
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
An email being displayed.
Definition: pager.h:65
unsigned char C_CryptVerifySig
Config: Verify PGP or SMIME signatures.
Definition: commands.c:85
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:126
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
#define SEC_BADSIGN
Email has a bad signature.
Definition: ncrypt.h:125
Pager pager (email viewer)
Definition: keymap.h:78
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
struct Mailbox * mailbox
Definition: context.h:50
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:38
Data passed to index_format_str()
Definition: hdrline.h:45
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:124
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
#define CH_WEED
Weed the headers?
Definition: copy.h:52
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
struct Envelope * env
Envelope information.
Definition: email.h:89
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:72
struct MuttWindow * win_pager
Definition: pager.h:76
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
void mutt_make_string_info(char *buf, size_t buflen, int cols, const char *s, struct HdrFormatInfo *hfi, MuttFormatFlags flags)
Create pager status bar string.
Definition: hdrline.c:1528
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:149
#define mutt_b2s(buf)
Definition: buffer.h:41
struct Context * ctx
Current mailbox.
Definition: pager.h:67
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE struct Context * Context
Definition: globals.h:42
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
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:50
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:451
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
pid_t mutt_create_filter_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:64
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:268
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
Messages that have been read.
Definition: mutt.h:100
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:46
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:578
bool C_PromptAfter
Config: Pause after running an external pager.
Definition: commands.c:92
struct Email * email
Current message.
Definition: pager.h:68
char * C_DisplayFilter
Config: External command to pre-process an email before display.
Definition: commands.c:86
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_error(...)
Definition: logging.h:84
static void process_protected_headers(struct Email *e)
Get the protected header and update the index.
Definition: commands.c:103
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
struct MuttWindow * win_ibar
Definition: pager.h:73
WHERE char * C_Pager
Config: External command for viewing messages, or &#39;builtin&#39; to use NeoMutt&#39;s.
Definition: globals.h:132
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
#define TAILQ_EMPTY(head)
Definition: queue.h:714
int mutt_pager(const char *banner, const char *fname, PagerFlags flags, struct Pager *extra)
Display a file, or help, in a window.
Definition: pager.c:2205
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:220
#define WithCrypto
Definition: ncrypt.h:160
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:692
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
int pair
Color-pair to use when displaying in the index.
Definition: email.h:79
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
WHERE char * C_PagerFormat
Config: printf-like format string for the pager&#39;s status bar.
Definition: globals.h:133
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
struct MuttWindow * win_pbar
Definition: pager.h:75
+ 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 407 of file commands.c.

408 {
409  if (!m || !el || STAILQ_EMPTY(el))
410  return;
411 
412  char prompt[8193];
413  char scratch[8192];
414  char buf[8192] = { 0 };
415  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
416  char *err = NULL;
417  int rc;
418  int msg_count = 0;
419 
420  struct EmailNode *en = NULL;
421  STAILQ_FOREACH(en, el, entries)
422  {
423  /* RFC5322 mandates a From: header,
424  * so warn before bouncing messages without one */
425  if (!TAILQ_EMPTY(&en->email->env->from))
426  mutt_error(_("Warning: message contains no From: header"));
427 
428  msg_count++;
429  }
430 
431  if (msg_count == 1)
432  mutt_str_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
433  else
434  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
435 
436  rc = mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS);
437  if (rc || !buf[0])
438  return;
439 
440  mutt_addrlist_parse2(&al, buf);
441  if (TAILQ_EMPTY(&al))
442  {
443  mutt_error(_("Error parsing address"));
444  return;
445  }
446 
447  mutt_expand_aliases(&al);
448 
449  if (mutt_addrlist_to_intl(&al, &err) < 0)
450  {
451  mutt_error(_("Bad IDN: '%s'"), err);
452  FREE(&err);
453  mutt_addrlist_clear(&al);
454  return;
455  }
456 
457  buf[0] = '\0';
458  mutt_addrlist_write(&al, buf, sizeof(buf), true);
459 
460 #define EXTRA_SPACE (15 + 7 + 2)
461  snprintf(scratch, sizeof(scratch),
462  ngettext("Bounce message to %s?", "Bounce messages to %s?", msg_count), buf);
463 
465  {
466  mutt_simple_format(prompt, sizeof(prompt), 0, MuttMessageWindow->state.cols - EXTRA_SPACE,
467  JUSTIFY_LEFT, 0, scratch, sizeof(scratch), false);
468  mutt_str_strcat(prompt, sizeof(prompt), "...?");
469  }
470  else
471  snprintf(prompt, sizeof(prompt), "%s", scratch);
472 
473  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
474  {
475  mutt_addrlist_clear(&al);
477  mutt_message(ngettext("Message not bounced", "Messages not bounced", msg_count));
478  return;
479  }
480 
482 
483  struct Message *msg = NULL;
484  STAILQ_FOREACH(en, el, entries)
485  {
486  msg = mx_msg_open(m, en->email->msgno);
487  if (!msg)
488  {
489  rc = -1;
490  break;
491  }
492 
493  rc = mutt_bounce_message(msg->fp, en->email, &al);
494  mx_msg_close(m, &msg);
495 
496  if (rc < 0)
497  break;
498  }
499 
500  mutt_addrlist_clear(&al);
501  /* If no error, or background, display message. */
502  if ((rc == 0) || (rc == S_BKG))
503  mutt_message(ngettext("Message bounced", "Messages bounced", msg_count));
504 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:178
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
Left justify the text.
Definition: curs_lib.h:47
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:63
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
#define _(a)
Definition: message.h:28
#define S_BKG
Definition: string2.h:43
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:607
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1140
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:113
struct Envelope * env
Envelope information.
Definition: email.h:89
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
int mutt_bounce_message(FILE *fp, struct Email *e, struct AddressList *to)
Bounce an email message.
Definition: sendlib.c:3122
A local copy of an email.
Definition: mx.h:81
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1359
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1217
struct Email * email
Email in the list.
Definition: email.h:116
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mx.h:83
#define FREE(x)
Definition: memory.h:40
#define STAILQ_EMPTY(head)
Definition: queue.h:345
List of Emails.
Definition: email.h:114
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:47
#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:1138
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1092
int msgno
Number displayed to the user.
Definition: email.h:86
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:1093
+ 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 513 of file commands.c.

515 {
516  if (decode)
517  {
518  *chflags |= CH_DECODE | CH_REORDER;
519  *cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
520 
521  if (C_Weed)
522  {
523  *chflags |= CH_WEED;
524  *cmflags |= MUTT_CM_WEED;
525  }
526 
527  /* Just as with copy-decode, we need to update the mime fields to avoid
528  * confusing programs that may process the email. However, we don't want
529  * to force those fields to appear in printouts. */
530  if (!print)
531  *chflags |= CH_MIME | CH_TXTPLAIN;
532  }
533 
534  if (print)
535  *cmflags |= MUTT_CM_PRINTING;
536 }
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
#define MUTT_CM_PRINTING
Printing the message - display light.
Definition: copy.h:42
#define CH_WEED
Weed the headers?
Definition: copy.h:52
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:62
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
+ Here is the caller graph for this function:

◆ pipe_msg()

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

Pipe a message.

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

Definition at line 546 of file commands.c.

547 {
549  CopyHeaderFlags chflags = CH_FROM;
550 
551  pipe_set_flags(decode, print, &cmflags, &chflags);
552 
553  if ((WithCrypto != 0) && decode && e->security & SEC_ENCRYPT)
554  {
556  return;
557  endwin();
558  }
559 
560  if (decode)
562 
563  mutt_copy_message(fp, m, e, cmflags, chflags, 0);
564 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:810
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:55
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
FILE * fp
pointer to the message data
Definition: mx.h:83
#define WithCrypto
Definition: ncrypt.h:160
static void pipe_set_flags(bool decode, bool print, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Generate flags for copy header/message.
Definition: commands.c:513
+ 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,
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 580 of file commands.c.

582 {
583  if (!m || !el)
584  return 1;
585 
586  struct EmailNode *en = STAILQ_FIRST(el);
587  if (!en)
588  return 1;
589 
590  int rc = 0;
591  pid_t pid;
592  FILE *fp_out = NULL;
593 
594  if (!STAILQ_NEXT(en, entries))
595  {
596  /* handle a single message */
598 
599  if ((WithCrypto != 0) && decode)
600  {
602  if ((en->email->security & SEC_ENCRYPT) &&
604  {
605  return 1;
606  }
607  }
608  mutt_endwin();
609 
610  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
611  if (pid < 0)
612  {
613  mutt_perror(_("Can't create filter process"));
614  return 1;
615  }
616 
617  OptKeepQuiet = true;
618  pipe_msg(m, en->email, fp_out, decode, print);
619  mutt_file_fclose(&fp_out);
620  rc = mutt_wait_filter(pid);
621  OptKeepQuiet = false;
622  }
623  else
624  {
625  /* handle tagged messages */
626  if ((WithCrypto != 0) && decode)
627  {
628  STAILQ_FOREACH(en, el, entries)
629  {
632  if ((en->email->security & SEC_ENCRYPT) &&
634  {
635  return 1;
636  }
637  }
638  }
639 
640  if (split)
641  {
642  STAILQ_FOREACH(en, el, entries)
643  {
645  mutt_endwin();
646  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
647  if (pid < 0)
648  {
649  mutt_perror(_("Can't create filter process"));
650  return 1;
651  }
652  OptKeepQuiet = true;
653  pipe_msg(m, en->email, fp_out, decode, print);
654  /* add the message separator */
655  if (sep)
656  fputs(sep, fp_out);
657  mutt_file_fclose(&fp_out);
658  if (mutt_wait_filter(pid) != 0)
659  rc = 1;
660  OptKeepQuiet = false;
661  }
662  }
663  else
664  {
665  mutt_endwin();
666  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
667  if (pid < 0)
668  {
669  mutt_perror(_("Can't create filter process"));
670  return 1;
671  }
672  OptKeepQuiet = true;
673  STAILQ_FOREACH(en, el, entries)
674  {
676  pipe_msg(m, en->email, fp_out, decode, print);
677  /* add the message separator */
678  if (sep)
679  fputs(sep, fp_out);
680  }
681  mutt_file_fclose(&fp_out);
682  if (mutt_wait_filter(pid) != 0)
683  rc = 1;
684  OptKeepQuiet = false;
685  }
686  }
687 
688  if ((rc != 0) || C_WaitKey)
690  return rc;
691 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:209
#define mutt_perror(...)
Definition: logging.h:85
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
#define _(a)
Definition: message.h:28
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
static void pipe_msg(struct Mailbox *m, struct Email *e, FILE *fp, bool decode, bool print)
Pipe a message.
Definition: commands.c:546
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:260
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
#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/ncrypt.h pgplib.h, smime.h
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:578
struct Email * email
Email in the list.
Definition: email.h:116
List of Emails.
Definition: email.h:114
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:220
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:37
#define STAILQ_FIRST(head)
Definition: queue.h:347
#define WithCrypto
Definition: ncrypt.h:160
+ 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 698 of file commands.c.

699 {
700  if (!m || !el)
701  return;
702 
703  char buf[1024] = { 0 };
704 
705  if ((mutt_get_field(_("Pipe to command: "), buf, sizeof(buf), MUTT_CMD) != 0) ||
706  (buf[0] == '\0'))
707  {
708  return;
709  }
710 
711  mutt_expand_path(buf, sizeof(buf));
712  pipe_message(m, el, buf, C_PipeDecode, false, C_PipeSplit, C_PipeSep);
713 }
#define _(a)
Definition: message.h:28
char * C_PipeSep
Config: Separator to add between multiple piped messages.
Definition: commands.c:88
bool C_PipeDecode
Config: Decode the message when piping it.
Definition: commands.c:87
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:133
bool C_PipeSplit
Config: Run the pipe command on each message separately.
Definition: commands.c:89
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:66
static int pipe_message(struct Mailbox *m, struct EmailList *el, char *cmd, bool decode, bool print, bool split, const char *sep)
Pipe message to a command.
Definition: commands.c:580
+ 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 720 of file commands.c.

721 {
722  if (!m || !el)
723  return;
724 
725  if (C_Print && !C_PrintCommand)
726  {
727  mutt_message(_("No printing command has been defined"));
728  return;
729  }
730 
731  int msg_count = 0;
732  struct EmailNode *en = NULL;
733  STAILQ_FOREACH(en, el, entries)
734  {
735  msg_count++;
736  }
737 
738  if (query_quadoption(C_Print, (msg_count == 1) ?
739  _("Print message?") :
740  _("Print tagged messages?")) != MUTT_YES)
741  {
742  return;
743  }
744 
745  if (pipe_message(m, el, C_PrintCommand, C_PrintDecode, true, C_PrintSplit, "\f") == 0)
746  mutt_message(ngettext("Message printed", "Messages printed", msg_count));
747  else
748  {
749  mutt_message(ngettext("Message could not be printed",
750  "Messages could not be printed", msg_count));
751  }
752 }
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: globals.h:183
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
bool C_PrintSplit
Config: Print multiple messages separately.
Definition: commands.c:91
#define _(a)
Definition: message.h:28
bool C_PrintDecode
Config: Decode message before printing it.
Definition: commands.c:90
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:136
List of Emails.
Definition: email.h:114
static int pipe_message(struct Mailbox *m, struct EmailList *el, char *cmd, bool decode, bool print, bool split, const char *sep)
Pipe message to a command.
Definition: commands.c:580
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_select_sort()

int 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 759 of file commands.c.

760 {
761  enum SortType method = C_Sort; /* save the current method in case of abort */
762  enum SortType new_sort = C_Sort;
763 
764  switch (mutt_multi_choice(reverse ?
765  /* L10N: The highlighted letters must match the "Sort" options */
766  _("Rev-Sort "
767  "(d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/"
768  "(u)nsort/si(z)e/s(c)ore/s(p)am/(l)abel?") :
769  /* L10N: The highlighted letters must match the "Rev-Sort" options */
770  _("Sort "
771  "(d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/"
772  "(u)nsort/si(z)e/s(c)ore/s(p)am/(l)abel?"),
773  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
774  _("dfrsotuzcpl")))
775  {
776  case -1: /* abort - don't resort */
777  return -1;
778 
779  case 1: /* (d)ate */
780  new_sort = SORT_DATE;
781  break;
782 
783  case 2: /* (f)rm */
784  new_sort = SORT_FROM;
785  break;
786 
787  case 3: /* (r)ecv */
788  new_sort = SORT_RECEIVED;
789  break;
790 
791  case 4: /* (s)ubj */
792  new_sort = SORT_SUBJECT;
793  break;
794 
795  case 5: /* t(o) */
796  new_sort = SORT_TO;
797  break;
798 
799  case 6: /* (t)hread */
800  new_sort = SORT_THREADS;
801  break;
802 
803  case 7: /* (u)nsort */
804  new_sort = SORT_ORDER;
805  break;
806 
807  case 8: /* si(z)e */
808  new_sort = SORT_SIZE;
809  break;
810 
811  case 9: /* s(c)ore */
812  new_sort = SORT_SCORE;
813  break;
814 
815  case 10: /* s(p)am */
816  new_sort = SORT_SPAM;
817  break;
818 
819  case 11: /* (l)abel */
820  new_sort = SORT_LABEL;
821  break;
822  }
823  if (reverse)
824  new_sort |= SORT_REVERSE;
825 
826  cs_subset_str_native_set(NeoMutt->sub, "sort", new_sort, NULL);
827  return (C_Sort != method) ? 0 : -1; /* no need to resort if it's the same */
828 }
SortType
Methods for sorting.
Definition: sort2.h:48
Sort by the email&#39;s From field.
Definition: sort2.h:54
#define _(a)
Definition: message.h:28
Sort by the email&#39;s score.
Definition: sort2.h:59
Sort by the emails label.
Definition: sort2.h:69
Container for Accounts, Notifications.
Definition: neomutt.h:35
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:243
Sort by the size of the email.
Definition: sort2.h:51
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:933
Sort by email threads.
Definition: sort2.h:56
Sort by the email&#39;s spam score.
Definition: sort2.h:64
Sort by the email&#39;s To field.
Definition: sort2.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
Sort by when the message were delivered locally.
Definition: sort2.h:57
Sort by the date the email was sent.
Definition: sort2.h:50
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
Sort by the email&#39;s subject.
Definition: sort2.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_shell_escape()

void mutt_shell_escape ( void  )

invoke a command in a subshell

Definition at line 833 of file commands.c.

834 {
835  char buf[1024];
836 
837  buf[0] = '\0';
838  if (mutt_get_field(_("Shell command: "), buf, sizeof(buf), MUTT_CMD) != 0)
839  return;
840 
841  if ((buf[0] == '\0') && C_Shell)
842  mutt_str_strfcpy(buf, C_Shell, sizeof(buf));
843  if (buf[0] == '\0')
844  return;
845 
847  mutt_endwin();
848  fflush(stdout);
849  int rc = mutt_system(buf);
850  if (rc == -1)
851  mutt_debug(LL_DEBUG1, "Error running \"%s\"", buf);
852 
853  if ((rc != 0) || C_WaitKey)
856 }
The "current" mailbox.
Definition: context.h:36
#define _(a)
Definition: message.h:28
WHERE char * C_Shell
Config: External command to run subshells in.
Definition: globals.h:139
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
struct Mailbox * mailbox
Definition: context.h:50
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:113
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:66
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:260
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:125
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mutt_mailbox.h:17
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:578
Log at debug level 1.
Definition: logging.h:40
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:47
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
+ 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 861 of file commands.c.

862 {
863  char buf[1024] = { 0 };
864 
865  /* if enter is pressed after : with no command, just return */
866  if ((mutt_get_field(":", buf, sizeof(buf), MUTT_COMMAND) != 0) || !buf[0])
867  return;
868 
869  struct Buffer err = mutt_buffer_make(256);
870  struct Buffer token = mutt_buffer_make(256);
871 
872  /* check if buf is a valid icommand, else fall back quietly to parse_rc_lines */
873  enum CommandResult rc = mutt_parse_icommand(buf, &err);
874  if (!mutt_buffer_is_empty(&err))
875  {
876  /* since errbuf could potentially contain printf() sequences in it,
877  * we must call mutt_error() in this fashion so that vsprintf()
878  * doesn't expect more arguments that we passed */
879  if (rc == MUTT_CMD_ERROR)
880  mutt_error("%s", err.data);
881  else
882  mutt_warning("%s", err.data);
883  }
884  else if (rc != MUTT_CMD_SUCCESS)
885  {
886  rc = mutt_parse_rc_line(buf, &token, &err);
887  if (!mutt_buffer_is_empty(&err))
888  {
889  if (rc == MUTT_CMD_SUCCESS) /* command succeeded with message */
890  mutt_message("%s", err.data);
891  else if (rc == MUTT_CMD_ERROR)
892  mutt_error("%s", err.data);
893  else if (rc == MUTT_CMD_WARNING)
894  mutt_warning("%s", err.data);
895  }
896  }
897  /* else successful command */
898 
899  mutt_buffer_dealloc(&token);
900  mutt_buffer_dealloc(&err);
901 }
#define mutt_warning(...)
Definition: logging.h:82
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:33
Error: Can&#39;t help the user.
Definition: mutt_commands.h:35
#define mutt_message(...)
Definition: logging.h:83
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_icommand(char *line, struct Buffer *err)
Parse an informational command.
Definition: icommands.c:76
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
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:69
char * data
Pointer to data.
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:37
Warning: Help given to the user.
Definition: mutt_commands.h:36
#define mutt_error(...)
Definition: logging.h:84
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:3252
+ 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 907 of file commands.c.

908 {
909  const char *pfx = NULL;
910  char buf[128];
911 
912  struct AddressList *al = mutt_get_address(env, &pfx);
913  if (!al)
914  return;
915 
916  /* Note: We don't convert IDNA to local representation this time.
917  * That is intentional, so the user has an opportunity to copy &
918  * paste the on-the-wire form of the address to other, IDN-unable
919  * software. */
920  buf[0] = '\0';
921  mutt_addrlist_write(al, buf, sizeof(buf), false);
922  mutt_message("%s: %s", pfx, buf);
923 }
#define mutt_message(...)
Definition: logging.h:83
struct AddressList * mutt_get_address(struct Envelope *env, const char **pfxp)
Get an Address from an Envelope.
Definition: alias.c:335
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_copy_flags()

static void set_copy_flags ( struct Email e,
bool  decode,
bool  decrypt,
CopyMessageFlags cmflags,
CopyHeaderFlags chflags 
)
static

Set the flags for a message copy.

Parameters
[in]eEmail
[in]decodeIf true, decode the message
[in]decryptIf true, decrypt the message
[out]cmflagsFlags, see CopyMessageFlags
[out]chflagsFlags, see CopyHeaderFlags

Definition at line 933 of file commands.c.

935 {
936  *cmflags = MUTT_CM_NO_FLAGS;
937  *chflags = CH_UPDATE_LEN;
938 
939  if ((WithCrypto != 0) && !decode && decrypt && (e->security & SEC_ENCRYPT))
940  {
942  {
943  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
944  *cmflags = MUTT_CM_DECODE_PGP;
945  }
946  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
948  {
949  decode = 1;
950  }
951  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
953  {
954  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
955  *cmflags = MUTT_CM_DECODE_SMIME;
956  }
957  }
958 
959  if (decode)
960  {
961  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN;
962  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
963 
964  if (!decrypt) /* If decode doesn't kick in for decrypt, */
965  {
966  *chflags |= CH_DECODE; /* then decode RFC2047 headers, */
967 
968  if (C_Weed)
969  {
970  *chflags |= CH_WEED; /* and respect $weed. */
971  *cmflags |= MUTT_CM_WEED;
972  }
973  }
974  }
975 }
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
struct Body * content
List of MIME parts.
Definition: email.h:90
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:451
#define CH_WEED
Weed the headers?
Definition: copy.h:52
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:62
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:557
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:616
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
#define MUTT_CM_DECODE_PGP
Used for decoding PGP messages.
Definition: copy.h:44
#define WithCrypto
Definition: ncrypt.h:160
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_message_ctx()

int mutt_save_message_ctx ( struct Email e,
bool  delete_original,
bool  decode,
bool  decrypt,
struct Mailbox m 
)

Save a message to a given mailbox.

Parameters
eEmail
delete_originalIf true, delete the original
decodeIf true, decode the message
decryptIf true, decrypt the message
mMailbox to save to
Return values
0Success
-1Error

Definition at line 987 of file commands.c.

989 {
991  CopyHeaderFlags chflags = CH_NO_FLAGS;
992  int rc;
993 
994  set_copy_flags(e, decode, decrypt, &cmflags, &chflags);
995 
996  if (decode || decrypt)
998 
999  rc = mutt_append_message(m, Context->mailbox, e, cmflags, chflags);
1000  if (rc != 0)
1001  return rc;
1002 
1003  if (delete_original)
1004  {
1007  if (C_DeleteUntag)
1008  mutt_set_flag(Context->mailbox, e, MUTT_TAG, false);
1009  }
1010 
1011  return 0;
1012 }
The "current" mailbox.
Definition: context.h:36
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
static void set_copy_flags(struct Email *e, bool decode, bool decrypt, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Set the flags for a message copy.
Definition: commands.c:933
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
Messages to be purged (bypass trash)
Definition: mutt.h:104
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
struct Mailbox * mailbox
Definition: context.h:50
Messages to be deleted.
Definition: mutt.h:102
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
Tagged messages.
Definition: mutt.h:107
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: globals.h:209
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
int mutt_append_message(struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:880
+ 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,
bool  delete_original,
bool  decode,
bool  decrypt 
)

Save an email.

Parameters
mMailbox
elList of Emails to save
delete_originalIf true, delete the original (save)
decodeIf true, decode the message
decryptIf true, decrypt the message
Return values
0Copy/save was successful
-1Error/abort

Definition at line 1024 of file commands.c.

1026 {
1027  if (!el || STAILQ_EMPTY(el))
1028  return -1;
1029 
1030  bool need_passphrase = false;
1031  int app = 0;
1032  int rc = -1;
1033  const char *prompt = NULL;
1034  struct stat st;
1035  struct EmailNode *en = STAILQ_FIRST(el);
1036  bool single = !STAILQ_NEXT(en, entries);
1037 
1038  struct Buffer *buf = mutt_buffer_pool_get();
1039 
1040  if (delete_original)
1041  {
1042  if (decode)
1043  prompt = single ? _("Decode-save to mailbox") : _("Decode-save tagged to mailbox");
1044  else if (decrypt)
1045  prompt = single ? _("Decrypt-save to mailbox") : _("Decrypt-save tagged to mailbox");
1046  else
1047  prompt = single ? _("Save to mailbox") : _("Save tagged to mailbox");
1048  }
1049  else
1050  {
1051  if (decode)
1052  prompt = single ? _("Decode-copy to mailbox") : _("Decode-copy tagged to mailbox");
1053  else if (decrypt)
1054  prompt = single ? _("Decrypt-copy to mailbox") : _("Decrypt-copy tagged to mailbox");
1055  else
1056  prompt = single ? _("Copy to mailbox") : _("Copy tagged to mailbox");
1057  }
1058 
1059  if (WithCrypto)
1060  {
1061  need_passphrase = (en->email->security & SEC_ENCRYPT);
1062  app = en->email->security;
1063  }
1065  mutt_default_save(buf->data, buf->dsize, en->email);
1066  mutt_buffer_fix_dptr(buf);
1067 
1069  if (mutt_buffer_enter_fname(prompt, buf, 0) == -1)
1070  goto cleanup;
1071 
1072  size_t pathlen = mutt_buffer_len(buf);
1073  if (pathlen == 0)
1074  goto cleanup;
1075 
1076  /* Trim any trailing '/' */
1077  if (buf->data[pathlen - 1] == '/')
1078  buf->data[pathlen - 1] = '\0';
1079 
1080  /* This is an undocumented feature of ELM pointed out to me by Felix von
1081  * Leitner <leitner@prz.fu-berlin.de> */
1082  if (mutt_str_strcmp(mutt_b2s(buf), ".") == 0)
1084  else
1086 
1088 
1089  /* check to make sure that this file is really the one the user wants */
1090  if (mutt_save_confirm(mutt_b2s(buf), &st) != 0)
1091  goto cleanup;
1092 
1093  if ((WithCrypto != 0) && need_passphrase && (decode || decrypt) &&
1094  !crypt_valid_passphrase(app))
1095  {
1096  goto cleanup;
1097  }
1098 
1099  mutt_message(_("Copying to %s..."), mutt_b2s(buf));
1100 
1101 #ifdef USE_IMAP
1102  if ((m->magic == MUTT_IMAP) && !(decode || decrypt) &&
1103  (imap_path_probe(mutt_b2s(buf), NULL) == MUTT_IMAP))
1104  {
1105  switch (imap_copy_messages(m, el, mutt_b2s(buf), delete_original))
1106  {
1107  /* success */
1108  case 0:
1109  mutt_clear_error();
1110  rc = 0;
1111  goto cleanup;
1112  /* non-fatal error: continue to fetch/append */
1113  case 1:
1114  break;
1115  /* fatal error, abort */
1116  case -1:
1117  goto cleanup;
1118  }
1119  }
1120 #endif
1121 
1122  struct Mailbox *m_save = mx_path_resolve(mutt_b2s(buf));
1123  bool old_append = m_save->append;
1124  struct Context *ctx_save = mx_mbox_open(m_save, MUTT_NEWFOLDER);
1125  if (!ctx_save)
1126  {
1127  mailbox_free(&m_save);
1128  goto cleanup;
1129  }
1130  m_save->append = true;
1131 
1132 #ifdef USE_COMPRESSED
1133  /* If we're saving to a compressed mailbox, the stats won't be updated
1134  * until the next open. Until then, improvise. */
1135  struct Mailbox *m_comp = NULL;
1136  if (ctx_save->mailbox->compress_info)
1137  {
1138  m_comp = mailbox_find(ctx_save->mailbox->realpath);
1139  }
1140  /* We probably haven't been opened yet */
1141  if (m_comp && (m_comp->msg_count == 0))
1142  m_comp = NULL;
1143 #endif
1144  if (single)
1145  {
1146  if (mutt_save_message_ctx(en->email, delete_original, decode, decrypt,
1147  ctx_save->mailbox) != 0)
1148  {
1149  m_save->append = old_append;
1150  mx_mbox_close(&ctx_save);
1151  goto cleanup;
1152  }
1153 #ifdef USE_COMPRESSED
1154  if (m_comp)
1155  {
1156  m_comp->msg_count++;
1157  if (!en->email->read)
1158  {
1159  m_comp->msg_unread++;
1160  if (!en->email->old)
1161  m_comp->msg_new++;
1162  }
1163  if (en->email->flagged)
1164  m_comp->msg_flagged++;
1165  }
1166 #endif
1167  }
1168  else
1169  {
1170  rc = 0;
1171 
1172 #ifdef USE_NOTMUCH
1173  if (m->magic == MUTT_NOTMUCH)
1174  nm_db_longrun_init(m, true);
1175 #endif
1176  STAILQ_FOREACH(en, el, entries)
1177  {
1179  rc = mutt_save_message_ctx(en->email, delete_original, decode, decrypt,
1180  ctx_save->mailbox);
1181  if (rc != 0)
1182  break;
1183 #ifdef USE_COMPRESSED
1184  if (m_comp)
1185  {
1186  struct Email *e2 = en->email;
1187  m_comp->msg_count++;
1188  if (!e2->read)
1189  {
1190  m_comp->msg_unread++;
1191  if (!e2->old)
1192  m_comp->msg_new++;
1193  }
1194  if (e2->flagged)
1195  m_comp->msg_flagged++;
1196  }
1197 #endif
1198  }
1199 #ifdef USE_NOTMUCH
1200  if (m->magic == MUTT_NOTMUCH)
1201  nm_db_longrun_done(m);
1202 #endif
1203  if (rc != 0)
1204  {
1205  m_save->append = old_append;
1206  mx_mbox_close(&ctx_save);
1207  goto cleanup;
1208  }
1209  }
1210 
1211  const bool need_mailbox_cleanup = ((ctx_save->mailbox->magic == MUTT_MBOX) ||
1212  (ctx_save->mailbox->magic == MUTT_MMDF));
1213 
1214  m_save->append = old_append;
1215  mx_mbox_close(&ctx_save);
1216 
1217  if (need_mailbox_cleanup)
1218  mutt_mailbox_cleanup(mutt_b2s(buf), &st);
1219 
1220  mutt_clear_error();
1221  rc = 0;
1222 
1223 cleanup:
1225  return rc;
1226 }
int mutt_save_message_ctx(struct Email *e, bool delete_original, bool decode, bool decrypt, struct Mailbox *m)
Save a message to a given mailbox.
Definition: commands.c:987
The "current" mailbox.
Definition: context.h:36
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:2474
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:583
void mutt_mailbox_cleanup(const char *path, struct stat *st)
Restore the timestamp of a mailbox.
Definition: mutt_mailbox.c:354
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:90
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:83
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
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:253
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:656
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:703
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1448
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
size_t dsize
Length of data.
Definition: buffer.h:37
bool read
Email is read.
Definition: email.h:51
struct Mailbox * mailbox
Definition: context.h:50
bool old
Email is seen, but unread.
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:60
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
#define mutt_b2s(buf)
Definition: buffer.h:41
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: nm_db.c:304
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
A mailbox.
Definition: mailbox.h:80
char * data
Pointer to data.
Definition: buffer.h:35
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:48
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:112
int imap_copy_messages(struct Mailbox *m, struct EmailList *el, const char *dest, bool delete_original)
Server COPY messages to another folder.
Definition: message.c:1587
#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/ncrypt.h pgplib.h, smime.h
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:53
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:47
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:342
bool flagged
Marked important?
Definition: email.h:43
int msg_new
Number of new messages.
Definition: mailbox.h:94
struct Email * email
Email in the list.
Definition: email.h:116
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:123
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1603
#define STAILQ_EMPTY(head)
Definition: queue.h:345
List of Emails.
Definition: email.h:114
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: nm_db.c:289
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mx.h:55
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
#define STAILQ_FIRST(head)
Definition: queue.h:347
#define WithCrypto
Definition: ncrypt.h:160
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:88
static char LastSaveFolder[PATH_MAX]
The folder the user last saved to.
Definition: commands.c:97
+ 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
booltrue if a structural change is made

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

Definition at line 1237 of file commands.c.

1238 {
1239  char buf[1024];
1240  char obuf[1024];
1241  char tmp[256];
1242  char charset[256];
1243 
1244  bool charset_changed = false;
1245  bool type_changed = false;
1246  bool structure_changed = false;
1247 
1248  char *cp = mutt_param_get(&b->parameter, "charset");
1249  mutt_str_strfcpy(charset, cp, sizeof(charset));
1250 
1251  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
1252  mutt_str_strfcpy(obuf, buf, sizeof(obuf));
1253  if (!TAILQ_EMPTY(&b->parameter))
1254  {
1255  size_t l = strlen(buf);
1256  struct Parameter *np = NULL;
1257  TAILQ_FOREACH(np, &b->parameter, entries)
1258  {
1259  mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
1260  l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
1261  if (l >= sizeof(buf))
1262  {
1263  // L10N: e.g. "text/plain; charset=UTF-8; ..."
1264  mutt_error(_("Content type is too long"));
1265  return false;
1266  }
1267  }
1268  }
1269 
1270  if ((mutt_get_field("Content-Type: ", buf, sizeof(buf), 0) != 0) || (buf[0] == '\0'))
1271  return false;
1272 
1273  /* clean up previous junk */
1275  FREE(&b->subtype);
1276 
1277  mutt_parse_content_type(buf, b);
1278 
1279  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1280  type_changed = (mutt_str_strcasecmp(tmp, obuf) != 0);
1281  charset_changed =
1282  (mutt_str_strcasecmp(charset, mutt_param_get(&b->parameter, "charset")) != 0);
1283 
1284  /* if in send mode, check for conversion - current setting is default. */
1285 
1286  if (!e && (b->type == TYPE_TEXT) && charset_changed)
1287  {
1288  snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
1289  mutt_param_get(&b->parameter, "charset"));
1290  int ans = mutt_yesorno(tmp, b->noconv ? MUTT_NO : MUTT_YES);
1291  if (ans != MUTT_ABORT)
1292  b->noconv = (ans == MUTT_NO);
1293  }
1294 
1295  /* inform the user */
1296 
1297  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1298  if (type_changed)
1299  mutt_message(_("Content-Type changed to %s"), tmp);
1300  if ((b->type == TYPE_TEXT) && charset_changed)
1301  {
1302  if (type_changed)
1303  mutt_sleep(1);
1304  mutt_message(b->noconv ? _("Character set changed to %s; not converting") :
1305  _("Character set changed to %s; converting"),
1306  mutt_param_get(&b->parameter, "charset"));
1307  }
1308 
1309  b->force_charset |= charset_changed;
1310 
1311  if (!is_multipart(b) && b->parts)
1312  {
1313  structure_changed = true;
1314  mutt_body_free(&b->parts);
1315  }
1316  if (!mutt_is_message_type(b->type, b->subtype) && b->email)
1317  {
1318  structure_changed = true;
1319  b->email->content = NULL;
1320  email_free(&b->email);
1321  }
1322 
1323  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
1324  {
1325  structure_changed = true;
1326  mutt_parse_part(fp, b);
1327  }
1328 
1329  if ((WithCrypto != 0) && e)
1330  {
1331  if (e->content == b)
1332  e->security = SEC_NO_FLAGS;
1333 
1334  e->security |= crypt_query(b);
1335  }
1336 
1337  return structure_changed;
1338 }
char * attribute
Parameter name.
Definition: parameter.h:34
#define NONULL(x)
Definition: string2.h:37
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1391
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
#define is_multipart(body)
Definition: mime.h:77
User aborted the question (with Ctrl-G)
Definition: quad.h:38
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * content
List of MIME parts.
Definition: email.h:90
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1545
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:376
bool force_charset
Send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:74
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:61
char * subtype
content-type subtype
Definition: body.h:37
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
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
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:65
#define TYPE(body)
Definition: mime.h:83
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:456
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1406
char * value
Parameter value.
Definition: parameter.h:35
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
Attribute associated with a MIME part.
Definition: parameter.h:32
#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
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
#define TAILQ_EMPTY(head)
Definition: queue.h:714
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:692
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:672
+ 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 Email e,
MuttRedrawFlags redraw 
)
static

Check for an inline PGP content.

Parameters
[in]eEmail to check
[out]redrawFlags if the screen needs redrawing, see MuttRedrawFlags
Return values
trueIf message contains inline PGP content

Definition at line 1346 of file commands.c.

1347 {
1348  bool rc = false;
1349 
1351 
1353  struct Message *msg = mx_msg_open(Context->mailbox, e->msgno);
1354  if (!msg)
1355  return 0;
1356  if (crypt_pgp_check_traditional(msg->fp, e->content, false))
1357  {
1358  e->security = crypt_query(e->content);
1359  *redraw |= REDRAW_FULL;
1360  rc = true;
1361  }
1362 
1364  mx_msg_close(Context->mailbox, &msg);
1365  return rc;
1366 }
The "current" mailbox.
Definition: context.h:36
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:136
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1140
struct Mailbox * mailbox
Definition: context.h:50
A local copy of an email.
Definition: mx.h:81
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:277
FILE * fp
pointer to the message data
Definition: mx.h:83
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:692
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1092
int msgno
Number displayed to the user.
Definition: email.h:86
+ 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 EmailList *  el,
MuttRedrawFlags redraw 
)

Check if a message has inline PGP content.

Parameters
[in]elList of Emails to check
[out]redrawFlags if the screen needs redrawing, see MuttRedrawFlags
Return values
trueIf message contains inline PGP content

Definition at line 1374 of file commands.c.

1375 {
1376  bool rc = false;
1377  struct EmailNode *en = NULL;
1378  STAILQ_FOREACH(en, el, entries)
1379  {
1380  if (!(en->email->security & PGP_TRADITIONAL_CHECKED))
1381  rc = check_traditional_pgp(en->email, redraw) || rc;
1382  }
1383 
1384  return rc;
1385 }
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:136
static bool check_traditional_pgp(struct Email *e, MuttRedrawFlags *redraw)
Check for an inline PGP content.
Definition: commands.c:1346
#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/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
struct Email * email
Email in the list.
Definition: email.h:116
List of Emails.
Definition: email.h:114
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_stats()

void mutt_check_stats ( void  )

Forcibly update mailbox stats.

Definition at line 1390 of file commands.c.

1391 {
1393 }
The "current" mailbox.
Definition: context.h:36
struct Mailbox * mailbox
Definition: context.h:50
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:125
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mutt_mailbox.h:17
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Definition: mutt_mailbox.h:18
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_CryptVerifySig

unsigned char C_CryptVerifySig

Config: Verify PGP or SMIME signatures.

Definition at line 85 of file commands.c.

◆ C_DisplayFilter

char* C_DisplayFilter

Config: External command to pre-process an email before display.

Definition at line 86 of file commands.c.

◆ C_PipeDecode

bool C_PipeDecode

Config: Decode the message when piping it.

Definition at line 87 of file commands.c.

◆ C_PipeSep

char* C_PipeSep

Config: Separator to add between multiple piped messages.

Definition at line 88 of file commands.c.

◆ C_PipeSplit

bool C_PipeSplit

Config: Run the pipe command on each message separately.

Definition at line 89 of file commands.c.

◆ C_PrintDecode

bool C_PrintDecode

Config: Decode message before printing it.

Definition at line 90 of file commands.c.

◆ C_PrintSplit

bool C_PrintSplit

Config: Print multiple messages separately.

Definition at line 91 of file commands.c.

◆ C_PromptAfter

bool C_PromptAfter

Config: Pause after running an external pager.

Definition at line 92 of file commands.c.

◆ ExtPagerProgress

const char* ExtPagerProgress = "all"
static

Definition at line 94 of file commands.c.

◆ LastSaveFolder

char LastSaveFolder[PATH_MAX] = ""
static

The folder the user last saved to.

Used by ci_save_message()

Definition at line 97 of file commands.c.