NeoMutt  2018-07-16 +1783-b00bd9
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/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "conn/conn.h"
#include "mutt.h"
#include "alias.h"
#include "context.h"
#include "copy.h"
#include "curs_lib.h"
#include "filter.h"
#include "format_flags.h"
#include "globals.h"
#include "hdrline.h"
#include "hook.h"
#include "icommands.h"
#include "keymap.h"
#include "mailbox.h"
#include "mutt_curses.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "mutt_parse.h"
#include "mutt_window.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 dependency graph for commands.c:

Go to the source code of this file.

Macros

#define EXTRA_SPACE   (15 + 7 + 2)
 

Functions

static void update_protected_headers (struct Email *cur)
 Get the protected header and update the index. More...
 
int mutt_display_message (struct Email *cur)
 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, 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, 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

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

#define EXTRA_SPACE   (15 + 7 + 2)

Function Documentation

static void update_protected_headers ( struct Email cur)
static

Get the protected header and update the index.

Parameters
curEmail to update

Definition at line 98 of file commands.c.

99 {
100  struct Envelope *prot_headers = NULL;
101  regmatch_t pmatch[1];
102 
104  return;
105 
106  /* Grab protected headers to update in the index */
107  if (cur->security & SEC_SIGN)
108  {
109  /* Don't update on a bad signature.
110  *
111  * This is a simplification. It's possible the headers are in the
112  * encrypted part of a nested encrypt/signed. But properly handling that
113  * case would require more complexity in the decryption handlers, which
114  * I'm not sure is worth it. */
115  if (!(cur->security & SEC_GOODSIGN))
116  return;
117 
118  if (mutt_is_multipart_signed(cur->content) && cur->content->parts)
119  {
120  prot_headers = cur->content->parts->mime_headers;
121  }
122  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(cur->content))
123  {
124  prot_headers = cur->content->mime_headers;
125  }
126  }
127  if (!prot_headers && (cur->security & SEC_ENCRYPT))
128  {
129  if (((WithCrypto & APPLICATION_PGP) != 0) &&
132  {
133  prot_headers = cur->content->mime_headers;
134  }
135  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(cur->content))
136  {
137  prot_headers = cur->content->mime_headers;
138  }
139  }
140 
141  /* Update protected headers in the index and header cache. */
142  if (prot_headers && prot_headers->subject &&
143  mutt_str_strcmp(cur->env->subject, prot_headers->subject))
144  {
145  if (Context->mailbox->subj_hash && cur->env->real_subj)
147 
148  mutt_str_replace(&cur->env->subject, prot_headers->subject);
149  FREE(&cur->env->disp_subj);
150  if (regexec(C_ReplyRegex->regex, cur->env->subject, 1, pmatch, 0) == 0)
151  cur->env->real_subj = cur->env->subject + pmatch[0].rm_eo;
152  else
153  cur->env->real_subj = cur->env->subject;
154 
155  if (Context->mailbox->subj_hash)
157 
159 
160  /* Also persist back to the message headers if this is set */
162  {
164  cur->changed = 1;
165  Context->mailbox->changed = 1;
166  }
167  }
168 }
The "current" mailbox.
Definition: context.h:38
void mutt_hash_delete(struct Hash *table, const char *strkey, const void *data)
Remove an element from a Hash table.
Definition: hash.c:444
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:70
char * disp_subj
display subject (modified copy of subject)
Definition: envelope.h:52
regex_t * regex
compiled expression
Definition: regex3.h:60
struct Body * content
list of MIME parts
Definition: email.h:93
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:441
char * real_subj
offset of the real subject
Definition: envelope.h:51
bool changed
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:1599
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:33
unsigned char changed
Definition: envelope.h:69
struct Mailbox * mailbox
Definition: context.h:52
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:122
struct Envelope * env
envelope information
Definition: email.h:92
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:376
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:121
WHERE bool C_CryptProtectedHeadersSave
Config: Save the cleartext Subject with the headers.
Definition: globals.h:269
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:61
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:479
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:583
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:268
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:456
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
char * subject
Definition: envelope.h:50
struct Hash * subj_hash
hash table by subject
Definition: mailbox.h:128
#define FREE(x)
Definition: memory.h:40
bool changed
mailbox has been modified
Definition: mailbox.h:114
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:352
#define WithCrypto
Definition: ncrypt.h:155
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
The header of an email.
Definition: envelope.h:38
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_display_message ( struct Email cur)

Display a message in the pager.

Parameters
curHeader of current message
Return values
0Success
-1Error

Definition at line 176 of file commands.c.

177 {
178  char tempfile[PATH_MAX], buf[1024];
179  int rc = 0;
180  bool builtin = false;
182  CopyHeaderFlags chflags;
183  pid_t filterpid = -1;
184  int res;
185 
186  snprintf(buf, sizeof(buf), "%s/%s", TYPE(cur->content), cur->content->subtype);
187 
190 
191  /* see if crypto is needed for this message. if so, we should exit curses */
192  if ((WithCrypto != 0) && cur->security)
193  {
194  if (cur->security & SEC_ENCRYPT)
195  {
196  if (cur->security & APPLICATION_SMIME)
197  crypt_smime_getkeys(cur->env);
198  if (!crypt_valid_passphrase(cur->security))
199  return 0;
200 
201  cmflags |= MUTT_CM_VERIFY;
202  }
203  else if (cur->security & SEC_SIGN)
204  {
205  /* find out whether or not the verify signature */
206  /* L10N: Used for the $crypt_verify_sig prompt */
207  if (query_quadoption(C_CryptVerifySig, _("Verify signature?")) == MUTT_YES)
208  {
209  cmflags |= MUTT_CM_VERIFY;
210  }
211  }
212  }
213 
214  if (cmflags & MUTT_CM_VERIFY || cur->security & SEC_ENCRYPT)
215  {
216  if (cur->security & APPLICATION_PGP)
217  {
218  if (cur->env->from)
220 
222  }
223 
224  if (cur->security & APPLICATION_SMIME)
226  }
227 
228  mutt_mktemp(tempfile, sizeof(tempfile));
229  FILE *fp_filter_out = NULL;
230  FILE *fp_out = mutt_file_fopen(tempfile, "w");
231  if (!fp_out)
232  {
233  mutt_error(_("Could not create temporary file"));
234  return 0;
235  }
236 
238  {
239  fp_filter_out = fp_out;
240  fp_out = NULL;
241  filterpid = mutt_create_filter_fd(C_DisplayFilter, &fp_out, NULL, NULL, -1,
242  fileno(fp_filter_out), -1);
243  if (filterpid < 0)
244  {
245  mutt_error(_("Can't create display filter"));
246  mutt_file_fclose(&fp_filter_out);
247  unlink(tempfile);
248  return 0;
249  }
250  }
251 
252  if (!C_Pager || (mutt_str_strcmp(C_Pager, "builtin") == 0))
253  builtin = true;
254  else
255  {
256  struct HdrFormatInfo hfi;
257  hfi.ctx = Context;
258  hfi.mailbox = Context->mailbox;
259  hfi.pager_progress = ExtPagerProgress;
260  hfi.email = cur;
261  mutt_make_string_info(buf, sizeof(buf), MuttIndexWindow->cols,
263  fputs(buf, fp_out);
264  fputs("\n\n", fp_out);
265  }
266 
267  chflags = (C_Weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) | CH_DECODE | CH_FROM | CH_DISPLAY;
268 #ifdef USE_NOTMUCH
270  chflags |= CH_VIRTUAL;
271 #endif
272  res = mutt_copy_message_ctx(fp_out, Context->mailbox, cur, cmflags, chflags);
273 
274  if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (res < 0))
275  {
276  mutt_error(_("Could not copy message"));
277  if (fp_filter_out)
278  {
279  mutt_wait_filter(filterpid);
280  mutt_file_fclose(&fp_filter_out);
281  }
282  mutt_file_unlink(tempfile);
283  return 0;
284  }
285 
286  if (fp_filter_out && (mutt_wait_filter(filterpid) != 0))
288 
289  mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
290 
291  if (WithCrypto)
292  {
293  /* update crypto information for this message */
294  cur->security &= ~(SEC_GOODSIGN | SEC_BADSIGN);
295  cur->security |= crypt_query(cur->content);
296 
297  /* Remove color cache for this message, in case there
298  * are color patterns for both ~g and ~V */
299  cur->pair = 0;
300 
301  /* Grab protected headers and update the header and index */
303  }
304 
305  if (builtin)
306  {
307  if ((WithCrypto != 0) && (cur->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
308  {
309  if (cur->security & SEC_GOODSIGN)
310  {
311  if (crypt_smime_verify_sender(cur) == 0)
312  mutt_message(_("S/MIME signature successfully verified"));
313  else
314  mutt_error(_("S/MIME certificate owner does not match sender"));
315  }
316  else if (cur->security & SEC_PARTSIGN)
317  mutt_message(_("Warning: Part of this message has not been signed"));
318  else if (cur->security & SEC_SIGN || cur->security & SEC_BADSIGN)
319  mutt_error(_("S/MIME signature could NOT be verified"));
320  }
321 
322  if ((WithCrypto != 0) && (cur->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
323  {
324  if (cur->security & SEC_GOODSIGN)
325  mutt_message(_("PGP signature successfully verified"));
326  else if (cur->security & SEC_PARTSIGN)
327  mutt_message(_("Warning: Part of this message has not been signed"));
328  else if (cur->security & SEC_SIGN)
329  mutt_message(_("PGP signature could NOT be verified"));
330  }
331 
332  struct Pager info = { 0 };
333  /* Invoke the builtin pager */
334  info.email = cur;
335  info.ctx = Context;
336  rc = mutt_pager(NULL, tempfile, MUTT_PAGER_MESSAGE, &info);
337  }
338  else
339  {
340  int r;
341 
342  char cmd[STR_COMMAND];
343  mutt_endwin();
344  snprintf(cmd, sizeof(cmd), "%s %s", NONULL(C_Pager), tempfile);
345  r = mutt_system(cmd);
346  if (r == -1)
347  mutt_error(_("Error running \"%s\""), cmd);
348  unlink(tempfile);
349  if (!OptNoCurses)
350  keypad(stdscr, true);
351  if (r != -1)
352  mutt_set_flag(Context->mailbox, cur, MUTT_READ, true);
353  if ((r != -1) && C_PromptAfter)
354  {
355  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
356  rc = km_dokey(MENU_PAGER);
357  }
358  else
359  rc = 0;
360  }
361 
362  return rc;
363 }
struct Context * ctx
Definition: hdrline.h:45
The "current" mailbox.
Definition: context.h:38
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: magic.h:43
#define NONULL(x)
Definition: string2.h:36
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:68
int km_dokey(int menu)
Determine what a keypress should do.
Definition: keymap.c:569
static void update_protected_headers(struct Email *cur)
Get the protected header and update the index.
Definition: commands.c:98
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
#define mutt_message(...)
Definition: logging.h:82
#define MUTT_PAGER_MESSAGE
Definition: pager.h:58
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
list of MIME parts
Definition: email.h:93
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:191
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:700
#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:89
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:45
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
An email being displayed.
Definition: pager.h:65
unsigned char C_CryptVerifySig
Config: Verify PGP or SMIME signatures.
Definition: commands.c:80
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:124
#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:123
Pager pager (email viewer)
Definition: keymap.h:77
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:143
struct Mailbox * mailbox
Definition: context.h:52
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:38
Data passed to index_format_str()
Definition: hdrline.h:43
int mutt_copy_message_ctx(FILE *fp_out, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Copy a message from a Context.
Definition: copy.c:801
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:122
enum MailboxType magic
mailbox type
Definition: mailbox.h:105
#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:149
struct Envelope * env
envelope information
Definition: email.h:92
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:72
struct Address * from
Definition: envelope.h:41
char * subtype
content-type subtype
Definition: body.h:37
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:1514
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:137
struct Context * ctx
current mailbox
Definition: pager.h:67
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:121
WHERE struct Context * Context
Definition: globals.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
#define PATH_MAX
Definition: mutt.h:49
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
#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:405
#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:228
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
Messages that have been read.
Definition: mutt.h:99
int crypt_smime_verify_sender(struct Email *e)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:414
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:46
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
#define STR_COMMAND
Enough space for a long command line.
Definition: string2.h:34
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:532
bool C_PromptAfter
Config: Pause after running an external pager.
Definition: commands.c:87
#define TYPE(body)
Definition: mime.h:83
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:81
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_error(...)
Definition: logging.h:83
WHERE char * C_Pager
Config: External command for viewing messages, or &#39;builtin&#39; to use NeoMutt&#39;s.
Definition: globals.h:130
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
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:2233
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227
#define WithCrypto
Definition: ncrypt.h:155
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:660
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
int pair
color-pair to use when displaying in the index
Definition: email.h:82
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:50
WHERE char * C_PagerFormat
Config: printf-like format string for the pager&#39;s status bar.
Definition: globals.h:131
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:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Bounce an email.

Parameters
mMailbox
elList of Emails to bounce

Definition at line 370 of file commands.c.

371 {
372  if (!m || !el || STAILQ_EMPTY(el))
373  return;
374 
375  char prompt[129];
376  char scratch[128];
377  char buf[8192] = { 0 };
378  struct Address *addr = NULL;
379  char *err = NULL;
380  int rc;
381  int msg_count = 0;
382 
383  struct EmailNode *en = NULL;
384  STAILQ_FOREACH(en, el, entries)
385  {
386  /* RFC5322 mandates a From: header,
387  * so warn before bouncing messages without one */
388  if (!en->email->env->from)
389  mutt_error(_("Warning: message contains no From: header"));
390 
391  msg_count++;
392  }
393 
394  if (msg_count == 1)
395  mutt_str_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
396  else
397  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
398 
399  rc = mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS);
400  if (rc || !buf[0])
401  return;
402 
403  addr = mutt_addr_parse_list2(addr, buf);
404  if (!addr)
405  {
406  mutt_error(_("Error parsing address"));
407  return;
408  }
409 
410  addr = mutt_expand_aliases(addr);
411 
412  if (mutt_addrlist_to_intl(addr, &err) < 0)
413  {
414  mutt_error(_("Bad IDN: '%s'"), err);
415  FREE(&err);
416  mutt_addr_free(&addr);
417  return;
418  }
419 
420  buf[0] = '\0';
421  mutt_addr_write(buf, sizeof(buf), addr, true);
422 
423 #define EXTRA_SPACE (15 + 7 + 2)
424  snprintf(scratch, sizeof(scratch),
425  ngettext("Bounce message to %s?", "Bounce messages to %s?", msg_count), buf);
426 
428  {
429  mutt_simple_format(prompt, sizeof(prompt), 0, MuttMessageWindow->cols - EXTRA_SPACE,
430  JUSTIFY_LEFT, 0, scratch, sizeof(scratch), false);
431  mutt_str_strcat(prompt, sizeof(prompt), "...?");
432  }
433  else
434  snprintf(prompt, sizeof(prompt), "%s?", scratch);
435 
436  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
437  {
438  mutt_addr_free(&addr);
440  mutt_message(ngettext("Message not bounced", "Messages not bounced", msg_count));
441  return;
442  }
443 
445 
446  struct Message *msg = NULL;
447  STAILQ_FOREACH(en, el, entries)
448  {
449  msg = mx_msg_open(m, en->email->msgno);
450  if (!msg)
451  {
452  rc = -1;
453  break;
454  }
455 
456  rc = mutt_bounce_message(msg->fp, en->email, addr);
457  mx_msg_close(m, &msg);
458 
459  if (rc < 0)
460  break;
461  }
462 
463  mutt_addr_free(&addr);
464  /* If no error, or background, display message. */
465  if ((rc == 0) || (rc == S_BKG))
466  mutt_message(ngettext("Message bounced", "Messages bounced", msg_count));
467 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:180
struct Address * mutt_addr_parse_list2(struct Address *p, const char *s)
Parse a list of email addresses.
Definition: address.c:641
int mutt_bounce_message(FILE *fp, struct Email *e, struct Address *to)
Bounce an email message.
Definition: sendlib.c:3022
Left justify the text.
Definition: curs_lib.h:46
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:62
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
#define mutt_message(...)
Definition: logging.h:82
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:32
#define S_BKG
Definition: string2.h:42
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1077
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
struct Envelope * env
envelope information
Definition: email.h:92
struct Address * from
Definition: envelope.h:41
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1184
A local copy of an email.
Definition: mx.h:79
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1239
int mutt_addrlist_to_intl(struct Address *a, char **err)
Convert an Address list to Punycode.
Definition: address.c:1249
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:753
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:398
struct Address * mutt_expand_aliases(struct Address *a)
Expand aliases in a List of Addresses.
Definition: alias.c:298
struct Email * email
Definition: email.h:123
#define mutt_error(...)
Definition: logging.h:83
FILE * fp
pointer to the message data
Definition: mx.h:81
#define FREE(x)
Definition: memory.h:40
#define STAILQ_EMPTY(head)
Definition: queue.h:346
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451
List of Emails.
Definition: email.h:121
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
#define EXTRA_SPACE
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1029
int msgno
number displayed to the user
Definition: email.h:89
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:973

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

478 {
479  if (decode)
480  {
481  *cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
482  *chflags |= CH_DECODE | CH_REORDER;
483 
484  if (C_Weed)
485  {
486  *chflags |= CH_WEED;
487  *cmflags |= MUTT_CM_WEED;
488  }
489  }
490 
491  if (print)
492  *cmflags |= MUTT_CM_PRINTING;
493 }
#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 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:

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

504 {
506  CopyHeaderFlags chflags = CH_FROM;
507 
508  pipe_set_flags(decode, print, &cmflags, &chflags);
509 
510  if ((WithCrypto != 0) && decode && e->security & SEC_ENCRYPT)
511  {
513  return;
514  endwin();
515  }
516 
517  if (decode)
519 
520  mutt_copy_message_ctx(fp, m, e, cmflags, chflags);
521 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#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:120
#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:143
int mutt_copy_message_ctx(FILE *fp_out, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Copy a message from a Context.
Definition: copy.c:801
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
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:81
#define WithCrypto
Definition: ncrypt.h:155
static void pipe_set_flags(bool decode, bool print, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Generate flags for copy header/message.
Definition: commands.c:476

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

539 {
540  if (!m || !el)
541  return 1;
542 
543  struct EmailNode *en = STAILQ_FIRST(el);
544  if (!en)
545  return 1;
546 
547  int rc = 0;
548  pid_t pid;
549  FILE *fp_out = NULL;
550 
551  if (!STAILQ_NEXT(en, entries))
552  {
553  /* handle a single message */
555 
556  if ((WithCrypto != 0) && decode)
557  {
559  if ((en->email->security & SEC_ENCRYPT) &&
561  {
562  return 1;
563  }
564  }
565  mutt_endwin();
566 
567  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
568  if (pid < 0)
569  {
570  mutt_perror(_("Can't create filter process"));
571  return 1;
572  }
573 
574  OptKeepQuiet = true;
575  pipe_msg(m, en->email, fp_out, decode, print);
576  mutt_file_fclose(&fp_out);
577  rc = mutt_wait_filter(pid);
578  OptKeepQuiet = false;
579  }
580  else
581  {
582  /* handle tagged messages */
583  if ((WithCrypto != 0) && decode)
584  {
585  STAILQ_FOREACH(en, el, entries)
586  {
589  if ((en->email->security & SEC_ENCRYPT) &&
591  {
592  return 1;
593  }
594  }
595  }
596 
597  if (split)
598  {
599  STAILQ_FOREACH(en, el, entries)
600  {
602  mutt_endwin();
603  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
604  if (pid < 0)
605  {
606  mutt_perror(_("Can't create filter process"));
607  return 1;
608  }
609  OptKeepQuiet = true;
610  pipe_msg(m, en->email, fp_out, decode, print);
611  /* add the message separator */
612  if (sep)
613  fputs(sep, fp_out);
614  mutt_file_fclose(&fp_out);
615  if (mutt_wait_filter(pid) != 0)
616  rc = 1;
617  OptKeepQuiet = false;
618  }
619  }
620  else
621  {
622  mutt_endwin();
623  pid = mutt_create_filter(cmd, &fp_out, NULL, NULL);
624  if (pid < 0)
625  {
626  mutt_perror(_("Can't create filter process"));
627  return 1;
628  }
629  OptKeepQuiet = true;
630  STAILQ_FOREACH(en, el, entries)
631  {
633  pipe_msg(m, en->email, fp_out, decode, print);
634  /* add the message separator */
635  if (sep)
636  fputs(sep, fp_out);
637  }
638  mutt_file_fclose(&fp_out);
639  if (mutt_wait_filter(pid) != 0)
640  rc = 1;
641  OptKeepQuiet = false;
642  }
643  }
644 
645  if ((rc != 0) || C_WaitKey)
647  return rc;
648 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:216
#define mutt_perror(...)
Definition: logging.h:84
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define _(a)
Definition: message.h:28
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
static void pipe_msg(struct Mailbox *m, struct Email *e, FILE *fp, bool decode, bool print)
Pipe a message.
Definition: commands.c:503
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:143
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:258
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
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:532
struct Email * email
Definition: email.h:123
List of Emails.
Definition: email.h:121
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program...
Definition: options.h:36
#define STAILQ_FIRST(head)
Definition: queue.h:348
#define WithCrypto
Definition: ncrypt.h:155

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Pipe a message.

Parameters
mMailbox
elList of Emails to pipe

Definition at line 655 of file commands.c.

656 {
657  if (!m || !el)
658  return;
659 
660  char buf[1024] = { 0 };
661 
662  if ((mutt_get_field(_("Pipe to command: "), buf, sizeof(buf), MUTT_CMD) != 0) ||
663  (buf[0] == '\0'))
664  {
665  return;
666  }
667 
668  mutt_expand_path(buf, sizeof(buf));
669  pipe_message(m, el, buf, C_PipeDecode, false, C_PipeSplit, C_PipeSep);
670 }
#define _(a)
Definition: message.h:28
char * C_PipeSep
Config: Separator to add between multiple piped messages.
Definition: commands.c:83
bool C_PipeDecode
Config: Decode the message when piping it.
Definition: commands.c:82
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:127
bool C_PipeSplit
Config: Run the pipe command on each message separately.
Definition: commands.c:84
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:65
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:537

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Print a message.

Parameters
mMailbox
elList of Emails to print

Definition at line 677 of file commands.c.

678 {
679  if (!m || !el)
680  return;
681 
682  if (C_Print && (!C_PrintCommand || !*C_PrintCommand))
683  {
684  mutt_message(_("No printing command has been defined"));
685  return;
686  }
687 
688  int msg_count = 0;
689  struct EmailNode *en = NULL;
690  STAILQ_FOREACH(en, el, entries)
691  {
692  msg_count++;
693  }
694 
695  if (query_quadoption(C_Print, (msg_count == 1) ?
696  _("Print message?") :
697  _("Print tagged messages?")) != MUTT_YES)
698  {
699  return;
700  }
701 
702  if (pipe_message(m, el, C_PrintCommand, C_PrintDecode, true, C_PrintSplit, "\f") == 0)
703  mutt_message(ngettext("Message printed", "Messages printed", msg_count));
704  else
705  {
706  mutt_message(ngettext("Message could not be printed",
707  "Messages could not be printed", msg_count));
708  }
709 }
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: globals.h:185
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
#define mutt_message(...)
Definition: logging.h:82
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
bool C_PrintSplit
Config: Print multiple messages separately.
Definition: commands.c:86
#define _(a)
Definition: message.h:28
bool C_PrintDecode
Config: Decode message before printing it.
Definition: commands.c:85
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:134
List of Emails.
Definition: email.h:121
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:537

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

717 {
718  enum SortType method = C_Sort; /* save the current method in case of abort */
719  enum SortType new_sort = C_Sort;
720 
721  switch (mutt_multi_choice(reverse ?
722  /* L10N: The highlighted letters must match the "Sort" options */
723  _("Rev-Sort "
724  "(d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/"
725  "(u)nsort/si(z)e/s(c)ore/s(p)am/(l)abel?") :
726  /* L10N: The highlighted letters must match the "Rev-Sort" options */
727  _("Sort "
728  "(d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/"
729  "(u)nsort/si(z)e/s(c)ore/s(p)am/(l)abel?"),
730  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
731  _("dfrsotuzcpl")))
732  {
733  case -1: /* abort - don't resort */
734  return -1;
735 
736  case 1: /* (d)ate */
737  new_sort = SORT_DATE;
738  break;
739 
740  case 2: /* (f)rm */
741  new_sort = SORT_FROM;
742  break;
743 
744  case 3: /* (r)ecv */
745  new_sort = SORT_RECEIVED;
746  break;
747 
748  case 4: /* (s)ubj */
749  new_sort = SORT_SUBJECT;
750  break;
751 
752  case 5: /* t(o) */
753  new_sort = SORT_TO;
754  break;
755 
756  case 6: /* (t)hread */
757  new_sort = SORT_THREADS;
758  break;
759 
760  case 7: /* (u)nsort */
761  new_sort = SORT_ORDER;
762  break;
763 
764  case 8: /* si(z)e */
765  new_sort = SORT_SIZE;
766  break;
767 
768  case 9: /* s(c)ore */
769  new_sort = SORT_SCORE;
770  break;
771 
772  case 10: /* s(p)am */
773  new_sort = SORT_SPAM;
774  break;
775 
776  case 11: /* (l)abel */
777  new_sort = SORT_LABEL;
778  break;
779  }
780  if (reverse)
781  new_sort |= SORT_REVERSE;
782 
783  cs_str_native_set(Config, "sort", new_sort, NULL);
784  return (C_Sort != method) ? 0 : -1; /* no need to resort if it's the same */
785 }
Sort by the date the email was sent.
Definition: sort.h:50
#define _(a)
Definition: message.h:28
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
Sort by the email&#39;s subject.
Definition: sort.h:53
Sort by the email&#39;s spam score.
Definition: sort.h:64
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:824
Sort by the email&#39;s To field.
Definition: sort.h:58
Sort by the emails label.
Definition: sort.h:69
Sort by the email&#39;s From field.
Definition: sort.h:54
Sort by the size of the email.
Definition: sort.h:51
SortType
Methods for sorting.
Definition: sort.h:48
Sort by when the message were delivered locally.
Definition: sort.h:57
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort.h:86
Sort by email threads.
Definition: sort.h:56
Sort by the order the messages appear in the mailbox.
Definition: sort.h:55
Sort by the email&#39;s score.
Definition: sort.h:59
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: set.c:789

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_shell_escape ( void  )

invoke a command in a subshell

Definition at line 790 of file commands.c.

791 {
792  char buf[1024];
793 
794  buf[0] = '\0';
795  if (mutt_get_field(_("Shell command: "), buf, sizeof(buf), MUTT_CMD) != 0)
796  return;
797 
798  if ((buf[0] == '\0') && C_Shell)
799  mutt_str_strfcpy(buf, C_Shell, sizeof(buf));
800  if (buf[0] == '\0')
801  return;
802 
804  mutt_endwin();
805  fflush(stdout);
806  int rc = mutt_system(buf);
807  if (rc == -1)
808  mutt_debug(LL_DEBUG1, "Error running \"%s\"", buf);
809 
810  if ((rc != 0) || C_WaitKey)
813 }
The "current" mailbox.
Definition: context.h:38
#define _(a)
Definition: message.h:28
WHERE char * C_Shell
Config: External command to run subshells in.
Definition: globals.h:137
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
struct Mailbox * mailbox
Definition: context.h:52
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all AllMailboxes for new mail.
Definition: mailbox.c:341
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:65
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:258
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
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:753
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mailbox.h:168
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:532
Log at debug level 1.
Definition: logging.h:56
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:50

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_enter_command ( void  )

enter a neomutt command

Definition at line 818 of file commands.c.

819 {
820  char buf[1024] = { 0 };
821 
822  /* if enter is pressed after : with no command, just return */
823  if ((mutt_get_field(":", buf, sizeof(buf), MUTT_COMMAND) != 0) || !buf[0])
824  return;
825 
826  struct Buffer *err = mutt_buffer_alloc(256);
827  struct Buffer *token = mutt_buffer_alloc(256);
828 
829  /* check if buf is a valid icommand, else fall back quietly to parse_rc_lines */
830  enum CommandResult rc = mutt_parse_icommand(buf, err);
831  if (!mutt_buffer_is_empty(err))
832  {
833  /* since errbuf could potentially contain printf() sequences in it,
834  * we must call mutt_error() in this fashion so that vsprintf()
835  * doesn't expect more arguments that we passed */
836  if (rc == MUTT_CMD_ERROR)
837  mutt_error("%s", err->data);
838  else
839  mutt_warning("%s", err->data);
840  }
841  else if (rc != MUTT_CMD_SUCCESS)
842  {
843  rc = mutt_parse_rc_line(buf, token, err);
844  if (!mutt_buffer_is_empty(err))
845  {
846  if (rc == MUTT_CMD_SUCCESS) /* command succeeded with message */
847  mutt_message("%s", err->data);
848  else /* error executing command */
849  mutt_error("%s", err->data);
850  }
851  }
852  /* else successful command */
853 
854  mutt_buffer_free(&token);
855  mutt_buffer_free(&err);
856 }
#define mutt_warning(...)
Definition: logging.h:81
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:31
Error: Can&#39;t help the user.
Definition: mutt_commands.h:33
#define mutt_message(...)
Definition: logging.h:82
String manipulation buffer.
Definition: buffer.h:33
enum CommandResult mutt_parse_icommand(char *line, struct Buffer *err)
Parse an informational command.
Definition: icommands.c:73
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
struct Buffer * mutt_buffer_alloc(size_t size)
Create a new Buffer.
Definition: buffer.c:304
#define MUTT_COMMAND
Do command completion.
Definition: mutt.h:68
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:138
char * data
pointer to data
Definition: buffer.h:35
Success: Command worked.
Definition: mutt_commands.h:35
#define mutt_error(...)
Definition: logging.h:83
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
enum CommandResult mutt_parse_rc_line(char *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: init.c:3257

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_display_address ( struct Envelope env)

Display the address of a message.

Parameters
envEnvelope containing address

Definition at line 862 of file commands.c.

863 {
864  const char *pfx = NULL;
865  char buf[128];
866 
867  struct Address *addr = mutt_get_address(env, &pfx);
868  if (!addr)
869  return;
870 
871  /* Note: We don't convert IDNA to local representation this time.
872  * That is intentional, so the user has an opportunity to copy &
873  * paste the on-the-wire form of the address to other, IDN-unable
874  * software. */
875  buf[0] = '\0';
876  mutt_addr_write(buf, sizeof(buf), addr, false);
877  mutt_message("%s: %s", pfx, buf);
878 }
struct Address * mutt_get_address(struct Envelope *env, const char **pfxp)
Get an Address from an Envelope.
Definition: alias.c:329
#define mutt_message(...)
Definition: logging.h:82
An email address.
Definition: address.h:32
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1184

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

890 {
891  *cmflags = MUTT_CM_NO_FLAGS;
892  *chflags = CH_UPDATE_LEN;
893 
894  if ((WithCrypto != 0) && !decode && decrypt && (e->security & SEC_ENCRYPT))
895  {
897  {
898  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
899  *cmflags = MUTT_CM_DECODE_PGP;
900  }
901  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
903  {
904  decode = 1;
905  }
906  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
908  {
909  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
910  *cmflags = MUTT_CM_DECODE_SMIME;
911  }
912  }
913 
914  if (decode)
915  {
916  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN;
917  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
918 
919  if (!decrypt) /* If decode doesn't kick in for decrypt, */
920  {
921  *chflags |= CH_DECODE; /* then decode RFC2047 headers, */
922 
923  if (C_Weed)
924  {
925  *chflags |= CH_WEED; /* and respect $weed. */
926  *cmflags |= MUTT_CM_WEED;
927  }
928  }
929  }
930 }
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
struct Body * content
list of MIME parts
Definition: email.h:93
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#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:417
#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:524
#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:583
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
#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:155
#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:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Save a message to a given mailbox.

Parameters
eEmail
deleteIf 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 942 of file commands.c.

944 {
946  CopyHeaderFlags chflags = CH_NO_FLAGS;
947  int rc;
948 
949  set_copy_flags(e, decode, decrypt, &cmflags, &chflags);
950 
951  if (decode || decrypt)
953 
954  rc = mutt_append_message(m, Context->mailbox, e, cmflags, chflags);
955  if (rc != 0)
956  return rc;
957 
958  if (delete)
959  {
962  if (C_DeleteUntag)
963  mutt_set_flag(Context->mailbox, e, MUTT_TAG, false);
964  }
965 
966  return 0;
967 }
The "current" mailbox.
Definition: context.h:38
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:68
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:888
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
Messages to be purged (bypass trash)
Definition: mutt.h:103
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:52
Messages to be deleted.
Definition: mutt.h:101
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
Tagged messages.
Definition: mutt.h:106
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: globals.h:207
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:871

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_save_message ( struct Mailbox m,
struct EmailList *  el,
bool  delete,
bool  decode,
bool  decrypt 
)

Save an email.

Parameters
mMailbox
elList of Emails to save
deleteIf 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 979 of file commands.c.

981 {
982  if (!el || STAILQ_EMPTY(el))
983  return -1;
984 
985  bool need_passphrase = false;
986  int app = 0;
987  char buf[PATH_MAX];
988  const char *prompt = NULL;
989  struct stat st;
990  struct EmailNode *en = STAILQ_FIRST(el);
991  bool single = !STAILQ_NEXT(en, entries);
992 
993  if (delete)
994  {
995  if (decode)
996  prompt = single ? _("Decode-save to mailbox") : _("Decode-save tagged to mailbox");
997  else if (decrypt)
998  prompt = single ? _("Decrypt-save to mailbox") : _("Decrypt-save tagged to mailbox");
999  else
1000  prompt = single ? _("Save to mailbox") : _("Save tagged to mailbox");
1001  }
1002  else
1003  {
1004  if (decode)
1005  prompt = single ? _("Decode-copy to mailbox") : _("Decode-copy tagged to mailbox");
1006  else if (decrypt)
1007  prompt = single ? _("Decrypt-copy to mailbox") : _("Decrypt-copy tagged to mailbox");
1008  else
1009  prompt = single ? _("Copy to mailbox") : _("Copy tagged to mailbox");
1010  }
1011 
1012  if (WithCrypto)
1013  {
1014  need_passphrase = (en->email->security & SEC_ENCRYPT);
1015  app = en->email->security;
1016  }
1018  mutt_default_save(buf, sizeof(buf), en->email);
1019 
1020  mutt_pretty_mailbox(buf, sizeof(buf));
1021  if (mutt_enter_fname(prompt, buf, sizeof(buf), false) == -1)
1022  return -1;
1023 
1024  size_t pathlen = strlen(buf);
1025  if (pathlen == 0)
1026  return -1;
1027 
1028  /* Trim any trailing '/' */
1029  if (buf[pathlen - 1] == '/')
1030  buf[pathlen - 1] = '\0';
1031 
1032  /* This is an undocumented feature of ELM pointed out to me by Felix von
1033  * Leitner <leitner@prz.fu-berlin.de> */
1034  if (mutt_str_strcmp(buf, ".") == 0)
1035  mutt_str_strfcpy(buf, LastSaveFolder, sizeof(buf));
1036  else
1038 
1039  mutt_expand_path(buf, sizeof(buf));
1040 
1041  /* check to make sure that this file is really the one the user wants */
1042  if (mutt_save_confirm(buf, &st) != 0)
1043  return -1;
1044 
1045  if ((WithCrypto != 0) && need_passphrase && (decode || decrypt) &&
1046  !crypt_valid_passphrase(app))
1047  {
1048  return -1;
1049  }
1050 
1051  mutt_message(_("Copying to %s..."), buf);
1052 
1053 #ifdef USE_IMAP
1054  if ((m->magic == MUTT_IMAP) && !(decode || decrypt) &&
1055  (imap_path_probe(buf, NULL) == MUTT_IMAP))
1056  {
1057  switch (imap_copy_messages(m, el, buf, delete))
1058  {
1059  /* success */
1060  case 0:
1061  mutt_clear_error();
1062  return 0;
1063  /* non-fatal error: continue to fetch/append */
1064  case 1:
1065  break;
1066  /* fatal error, abort */
1067  case -1:
1068  return -1;
1069  }
1070  }
1071 #endif
1072 
1073  struct Mailbox *m_save = mx_path_resolve(buf);
1074  struct Context *ctx_save = mx_mbox_open(m_save, MUTT_OPEN_NO_FLAGS);
1075  if (!ctx_save)
1076  {
1077  mailbox_free(&m_save);
1078  return -1;
1079  }
1080  bool old_append = m_save->append;
1081  m_save->append = true;
1082 
1083 #ifdef USE_COMPRESSED
1084  /* If we're saving to a compressed mailbox, the stats won't be updated
1085  * until the next open. Until then, improvise. */
1086  struct Mailbox *m_comp = NULL;
1087  if (ctx_save->mailbox->compress_info)
1088  {
1089  m_comp = mutt_find_mailbox(ctx_save->mailbox->realpath);
1090  }
1091  /* We probably haven't been opened yet */
1092  if (m_comp && (m_comp->msg_count == 0))
1093  m_comp = NULL;
1094 #endif
1095  if (single)
1096  {
1097  if (mutt_save_message_ctx(en->email, delete, decode, decrypt, ctx_save->mailbox) != 0)
1098  {
1099  m_save->append = old_append;
1100  mx_mbox_close(&ctx_save);
1101  return -1;
1102  }
1103 #ifdef USE_COMPRESSED
1104  if (m_comp)
1105  {
1106  m_comp->msg_count++;
1107  if (!en->email->read)
1108  {
1109  m_comp->msg_unread++;
1110  if (!en->email->old)
1111  m_comp->msg_new++;
1112  }
1113  if (en->email->flagged)
1114  m_comp->msg_flagged++;
1115  }
1116 #endif
1117  }
1118  else
1119  {
1120  int rc = 0;
1121 
1122 #ifdef USE_NOTMUCH
1123  if (m->magic == MUTT_NOTMUCH)
1124  nm_db_longrun_init(m, true);
1125 #endif
1126  STAILQ_FOREACH(en, el, entries)
1127  {
1129  rc = mutt_save_message_ctx(en->email, delete, decode, decrypt, ctx_save->mailbox);
1130  if (rc != 0)
1131  break;
1132 #ifdef USE_COMPRESSED
1133  if (m_comp)
1134  {
1135  struct Email *e2 = en->email;
1136  m_comp->msg_count++;
1137  if (!e2->read)
1138  {
1139  m_comp->msg_unread++;
1140  if (!e2->old)
1141  m_comp->msg_new++;
1142  }
1143  if (e2->flagged)
1144  m_comp->msg_flagged++;
1145  }
1146 #endif
1147  }
1148 #ifdef USE_NOTMUCH
1149  if (m->magic == MUTT_NOTMUCH)
1150  nm_db_longrun_done(m);
1151 #endif
1152  if (rc != 0)
1153  {
1154  m_save->append = old_append;
1155  mx_mbox_close(&ctx_save);
1156  return -1;
1157  }
1158  }
1159 
1160  const bool need_mailbox_cleanup = ((ctx_save->mailbox->magic == MUTT_MBOX) ||
1161  (ctx_save->mailbox->magic == MUTT_MMDF));
1162 
1163  m_save->append = old_append;
1164  mx_mbox_close(&ctx_save);
1165 
1166  if (need_mailbox_cleanup)
1167  mutt_mailbox_cleanup(buf, &st);
1168 
1169  mutt_clear_error();
1170  return 0;
1171 }
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mx.h:48
The "current" mailbox.
Definition: context.h:38
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: magic.h:43
int msg_count
total number of messages
Definition: mailbox.h:92
struct Mailbox * mutt_find_mailbox(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:267
The envelope/body of an email.
Definition: email.h:37
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2440
int msg_unread
number of unread messages
Definition: mailbox.h:93
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:546
#define mutt_message(...)
Definition: logging.h:82
int msg_flagged
number of flagged messages
Definition: mailbox.h:94
char * realpath
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:86
&#39;mmdf&#39; Mailbox type
Definition: magic.h:38
void mutt_mailbox_cleanup(const char *path, struct stat *st)
Restore the timestamp of a mailbox.
Definition: mailbox.c:216
#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:247
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:661
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1404
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:143
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:127
bool read
Definition: email.h:51
struct Mailbox * mailbox
Definition: context.h:52
bool old
Definition: email.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:105
enum MailboxType magic
mailbox type
Definition: mailbox.h:105
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: nm_db.c:307
&#39;mbox&#39; Mailbox type
Definition: magic.h:37
A mailbox.
Definition: mailbox.h:83
#define PATH_MAX
Definition: mutt.h:49
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:753
bool append
mailbox is opened in append mode
Definition: mailbox.h:113
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:615
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
bool flagged
marked important?
Definition: email.h:43
int msg_new
number of new messages
Definition: mailbox.h:95
struct Email * email
Definition: email.h:123
void * compress_info
compressed mbox module private data
Definition: mailbox.h:124
#define mutt_enter_fname(prompt, buf, buflen, mailbox)
Definition: curs_lib.h:85
int mutt_save_message_ctx(struct Email *e, bool delete, bool decode, bool decrypt, struct Mailbox *m)
Save a message to a given mailbox.
Definition: commands.c:942
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1531
int imap_copy_messages(struct Mailbox *m, struct EmailList *el, char *dest, bool delete)
Server COPY messages to another folder.
Definition: message.c:1564
#define STAILQ_EMPTY(head)
Definition: queue.h:346
List of Emails.
Definition: email.h:121
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: nm_db.c:292
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
#define STAILQ_FIRST(head)
Definition: queue.h:348
#define WithCrypto
Definition: ncrypt.h:155
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
static char LastSaveFolder[PATH_MAX]
The folder the user last saved to.
Definition: commands.c:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1183 {
1184  char buf[1024];
1185  char obuf[1024];
1186  char tmp[256];
1187  char charset[256];
1188 
1189  bool charset_changed = false;
1190  bool type_changed = false;
1191  bool structure_changed = false;
1192 
1193  char *cp = mutt_param_get(&b->parameter, "charset");
1194  mutt_str_strfcpy(charset, cp, sizeof(charset));
1195 
1196  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
1197  mutt_str_strfcpy(obuf, buf, sizeof(obuf));
1198  if (!TAILQ_EMPTY(&b->parameter))
1199  {
1200  size_t l = strlen(buf);
1201  struct Parameter *np = NULL;
1202  TAILQ_FOREACH(np, &b->parameter, entries)
1203  {
1204  mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
1205  l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
1206  }
1207  }
1208 
1209  if ((mutt_get_field("Content-Type: ", buf, sizeof(buf), 0) != 0) || (buf[0] == '\0'))
1210  return false;
1211 
1212  /* clean up previous junk */
1214  FREE(&b->subtype);
1215 
1216  mutt_parse_content_type(buf, b);
1217 
1218  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1219  type_changed = (mutt_str_strcasecmp(tmp, obuf) != 0);
1220  charset_changed =
1221  (mutt_str_strcasecmp(charset, mutt_param_get(&b->parameter, "charset")) != 0);
1222 
1223  /* if in send mode, check for conversion - current setting is default. */
1224 
1225  if (!e && (b->type == TYPE_TEXT) && charset_changed)
1226  {
1227  snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
1228  mutt_param_get(&b->parameter, "charset"));
1229  int ans = mutt_yesorno(tmp, b->noconv ? MUTT_NO : MUTT_YES);
1230  if (ans != MUTT_ABORT)
1231  b->noconv = (ans == MUTT_NO);
1232  }
1233 
1234  /* inform the user */
1235 
1236  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1237  if (type_changed)
1238  mutt_message(_("Content-Type changed to %s"), tmp);
1239  if ((b->type == TYPE_TEXT) && charset_changed)
1240  {
1241  if (type_changed)
1242  mutt_sleep(1);
1243  mutt_message(b->noconv ? _("Character set changed to %s; not converting") :
1244  _("Character set changed to %s; converting"),
1245  mutt_param_get(&b->parameter, "charset"));
1246  }
1247 
1248  b->force_charset |= charset_changed;
1249 
1250  if (!is_multipart(b) && b->parts)
1251  {
1252  structure_changed = true;
1253  mutt_body_free(&b->parts);
1254  }
1255  if (!mutt_is_message_type(b->type, b->subtype) && b->email)
1256  {
1257  structure_changed = true;
1258  b->email->content = NULL;
1259  mutt_email_free(&b->email);
1260  }
1261 
1262  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
1263  {
1264  structure_changed = true;
1265  mutt_parse_part(fp, b);
1266  }
1267 
1268  if ((WithCrypto != 0) && e)
1269  {
1270  if (e->content == b)
1271  e->security = SEC_NO_FLAGS;
1272 
1273  e->security |= crypt_query(b);
1274  }
1275 
1276  return structure_changed;
1277 }
char * attribute
Definition: parameter.h:34
#define NONULL(x)
Definition: string2.h:36
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1260
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:719
#define is_multipart(body)
Definition: mime.h:77
User aborted the question (with Ctrl-G)
Definition: quad.h:37
#define mutt_message(...)
Definition: logging.h:82
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:119
struct Body * content
list of MIME parts
Definition: email.h:93
bool noconv
don&#39;t do character set conversion
Definition: body.h:82
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1498
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:332
bool force_charset
send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:83
char * subtype
content-type subtype
Definition: body.h:37
void mutt_param_free(struct ParameterList *p)
Free a ParameterList.
Definition: parameter.c:61
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
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:61
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:753
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
unsigned int type
content-type primary type
Definition: body.h:72
#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:425
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1275
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:83
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * value
Definition: parameter.h:35
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
Attribute associated with a MIME part.
Definition: parameter.h:32
#define FREE(x)
Definition: memory.h:40
#define TAILQ_EMPTY(head)
Definition: queue.h:715
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
struct Email * email
header information for message/rfc822
Definition: body.h:62
#define WithCrypto
Definition: ncrypt.h:155
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:660
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and escape the specified characters.
Definition: address.c:695

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool check_traditional_pgp ( struct Email e,
MuttRedrawFlags redraw 
)
static

Check for an inline PGP content.

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

Definition at line 1285 of file commands.c.

1286 {
1287  bool rc = false;
1288 
1290 
1292  struct Message *msg = mx_msg_open(Context->mailbox, e->msgno);
1293  if (!msg)
1294  return 0;
1295  if (crypt_pgp_check_traditional(msg->fp, e->content, false))
1296  {
1297  e->security = crypt_query(e->content);
1298  *redraw |= REDRAW_FULL;
1299  rc = true;
1300  }
1301 
1303  mx_msg_close(Context->mailbox, &msg);
1304  return rc;
1305 }
The "current" mailbox.
Definition: context.h:38
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
struct Body * content
list of MIME parts
Definition: email.h:93
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:131
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1077
struct Mailbox * mailbox
Definition: context.h:52
A local copy of an email.
Definition: mx.h:79
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
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:237
FILE * fp
pointer to the message data
Definition: mx.h:81
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:660
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1029
int msgno
number displayed to the user
Definition: email.h:89

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1314 {
1315  bool rc = false;
1316  struct EmailNode *en = NULL;
1317  STAILQ_FOREACH(en, el, entries)
1318  {
1319  if (!(en->email->security & PGP_TRADITIONAL_CHECKED))
1320  rc = check_traditional_pgp(en->email, redraw) || rc;
1321  }
1322 
1323  return rc;
1324 }
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:131
static bool check_traditional_pgp(struct Email *e, MuttRedrawFlags *redraw)
Check for an inline PGP content.
Definition: commands.c:1285
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
struct Email * email
Definition: email.h:123
List of Emails.
Definition: email.h:121

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_check_stats ( void  )

Forcibly update mailbox stats.

Definition at line 1329 of file commands.c.

1330 {
1332 }
The "current" mailbox.
Definition: context.h:38
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Definition: mailbox.h:169
struct Mailbox * mailbox
Definition: context.h:52
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all AllMailboxes for new mail.
Definition: mailbox.c:341
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mailbox.h:168

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

unsigned char C_CryptVerifySig

Config: Verify PGP or SMIME signatures.

Definition at line 80 of file commands.c.

char* C_DisplayFilter

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

Definition at line 81 of file commands.c.

bool C_PipeDecode

Config: Decode the message when piping it.

Definition at line 82 of file commands.c.

char* C_PipeSep

Config: Separator to add between multiple piped messages.

Definition at line 83 of file commands.c.

bool C_PipeSplit

Config: Run the pipe command on each message separately.

Definition at line 84 of file commands.c.

bool C_PrintDecode

Config: Decode message before printing it.

Definition at line 85 of file commands.c.

bool C_PrintSplit

Config: Print multiple messages separately.

Definition at line 86 of file commands.c.

bool C_PromptAfter

Config: Pause after running an external pager.

Definition at line 87 of file commands.c.

const char* ExtPagerProgress = "all"
static

Definition at line 89 of file commands.c.

char LastSaveFolder[PATH_MAX] = ""
static

The folder the user last saved to.

Used by ci_save_message()

Definition at line 92 of file commands.c.