NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
commands.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <errno.h>
33 #include <limits.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include "mutt/lib.h"
40 #include "address/lib.h"
41 #include "config/lib.h"
42 #include "email/lib.h"
43 #include "core/lib.h"
44 #include "alias/lib.h"
45 #include "gui/lib.h"
46 #include "mutt.h"
47 #include "commands.h"
48 #include "ncrypt/lib.h"
49 #include "send/lib.h"
50 #include "context.h"
51 #include "copy.h"
52 #include "format_flags.h"
53 #include "hdrline.h"
54 #include "hook.h"
55 #include "icommands.h"
56 #include "init.h"
57 #include "keymap.h"
58 #include "mutt_commands.h"
59 #include "mutt_globals.h"
60 #include "mutt_logging.h"
61 #include "mutt_mailbox.h"
62 #include "mutt_menu.h"
63 #include "mutt_parse.h"
64 #include "muttlib.h"
65 #include "mx.h"
66 #include "options.h"
67 #include "pager.h"
68 #include "progress.h"
69 #include "protos.h"
70 #include "sort.h"
71 #ifdef USE_IMAP
72 #include "imap/lib.h"
73 #endif
74 #ifdef USE_NOTMUCH
75 #include "notmuch/lib.h"
76 #endif
77 #ifdef ENABLE_NLS
78 #include <libintl.h>
79 #endif
80 #ifdef USE_AUTOCRYPT
81 #include "autocrypt/lib.h"
82 #endif
83 
84 /* These Config Variables are only used in commands.c */
87 char *C_PipeSep;
92 
93 static const char *ExtPagerProgress = "all";
94 
96 static struct Buffer LastSaveFolder = { 0 };
97 
102 {
103  mutt_buffer_dealloc(&LastSaveFolder);
104 }
105 
110 static void process_protected_headers(struct Email *e)
111 {
112  struct Envelope *prot_headers = NULL;
113  regmatch_t pmatch[1];
114 
115 #ifdef USE_AUTOCRYPT
117  return;
118 #else
120  return;
121 #endif
122 
123  /* Grab protected headers to update in the index */
124  if (e->security & SEC_SIGN)
125  {
126  /* Don't update on a bad signature.
127  *
128  * This is a simplification. It's possible the headers are in the
129  * encrypted part of a nested encrypt/signed. But properly handling that
130  * case would require more complexity in the decryption handlers, which
131  * I'm not sure is worth it. */
132  if (!(e->security & SEC_GOODSIGN))
133  return;
134 
135  if (mutt_is_multipart_signed(e->body) && e->body->parts)
136  {
137  prot_headers = e->body->parts->mime_headers;
138  }
139  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
140  {
141  prot_headers = e->body->mime_headers;
142  }
143  }
144  if (!prot_headers && (e->security & SEC_ENCRYPT))
145  {
146  if (((WithCrypto & APPLICATION_PGP) != 0) &&
149  {
150  prot_headers = e->body->mime_headers;
151  }
152  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(e->body))
153  {
154  prot_headers = e->body->mime_headers;
155  }
156  }
157 
158  /* Update protected headers in the index and header cache. */
159  if (C_CryptProtectedHeadersRead && prot_headers && prot_headers->subject &&
160  !mutt_str_equal(e->env->subject, prot_headers->subject))
161  {
162  if (Context->mailbox->subj_hash && e->env->real_subj)
164 
165  mutt_str_replace(&e->env->subject, prot_headers->subject);
166  FREE(&e->env->disp_subj);
167  if (mutt_regex_capture(C_ReplyRegex, e->env->subject, 1, pmatch))
168  e->env->real_subj = e->env->subject + pmatch[0].rm_eo;
169  else
170  e->env->real_subj = e->env->subject;
171 
172  if (Context->mailbox->subj_hash)
174 
176 
177  /* Also persist back to the message headers if this is set */
179  {
181  e->changed = true;
182  Context->mailbox->changed = true;
183  }
184  }
185 
186 #ifdef USE_AUTOCRYPT
187  if (C_Autocrypt && (e->security & SEC_ENCRYPT) && prot_headers && prot_headers->autocrypt_gossip)
188  {
189  mutt_autocrypt_process_gossip_header(e, prot_headers);
190  }
191 #endif
192 }
193 
205 int mutt_display_message(struct MuttWindow *win_index, struct MuttWindow *win_ibar,
206  struct MuttWindow *win_pager, struct MuttWindow *win_pbar,
207  struct Mailbox *m, struct Email *e)
208 {
209  int rc = 0;
210  bool builtin = false;
212  CopyHeaderFlags chflags;
213  pid_t filterpid = -1;
214  struct Buffer *tempfile = NULL;
215  int res;
216 
219 
220  char columns[16];
221  // win_pager might not be visible and have a size yet, so use win_index
222  snprintf(columns, sizeof(columns), "%d", win_index->state.cols);
223  mutt_envlist_set("COLUMNS", columns, true);
224 
225  /* see if crypto is needed for this message. if so, we should exit curses */
226  if ((WithCrypto != 0) && e->security)
227  {
228  if (e->security & SEC_ENCRYPT)
229  {
230  if (e->security & APPLICATION_SMIME)
233  goto cleanup;
234 
235  cmflags |= MUTT_CM_VERIFY;
236  }
237  else if (e->security & SEC_SIGN)
238  {
239  /* find out whether or not the verify signature */
240  /* L10N: Used for the $crypt_verify_sig prompt */
241  if (query_quadoption(C_CryptVerifySig, _("Verify signature?")) == MUTT_YES)
242  {
243  cmflags |= MUTT_CM_VERIFY;
244  }
245  }
246  }
247 
248  if (cmflags & MUTT_CM_VERIFY || e->security & SEC_ENCRYPT)
249  {
250  if (e->security & APPLICATION_PGP)
251  {
252  if (!TAILQ_EMPTY(&e->env->from))
254 
256  }
257 
258  if (e->security & APPLICATION_SMIME)
260  }
261 
262  FILE *fp_filter_out = NULL;
263  tempfile = mutt_buffer_pool_get();
264  mutt_buffer_mktemp(tempfile);
265  FILE *fp_out = mutt_file_fopen(mutt_b2s(tempfile), "w");
266  if (!fp_out)
267  {
268  mutt_error(_("Could not create temporary file"));
269  goto cleanup;
270  }
271 
272  if (C_DisplayFilter)
273  {
274  fp_filter_out = fp_out;
275  fp_out = NULL;
276  filterpid = filter_create_fd(C_DisplayFilter, &fp_out, NULL, NULL, -1,
277  fileno(fp_filter_out), -1);
278  if (filterpid < 0)
279  {
280  mutt_error(_("Can't create display filter"));
281  mutt_file_fclose(&fp_filter_out);
282  unlink(mutt_b2s(tempfile));
283  goto cleanup;
284  }
285  }
286 
287  if (!C_Pager || mutt_str_equal(C_Pager, "builtin"))
288  builtin = true;
289  else
290  {
291  char buf[1024];
292  struct HdrFormatInfo hfi;
293 
294  hfi.mailbox = m;
297  hfi.email = e;
298  mutt_make_string_info(buf, sizeof(buf), win_index->state.cols,
300  fputs(buf, fp_out);
301  fputs("\n\n", fp_out);
302  }
303 
304  chflags = (C_Weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) | CH_DECODE | CH_FROM | CH_DISPLAY;
305 #ifdef USE_NOTMUCH
306  if (m->type == MUTT_NOTMUCH)
307  chflags |= CH_VIRTUAL;
308 #endif
309  res = mutt_copy_message(fp_out, m, e, cmflags, chflags, win_index->state.cols);
310 
311  if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (res < 0))
312  {
313  mutt_error(_("Could not copy message"));
314  if (fp_filter_out)
315  {
316  filter_wait(filterpid);
317  mutt_file_fclose(&fp_filter_out);
318  }
319  mutt_file_unlink(mutt_b2s(tempfile));
320  goto cleanup;
321  }
322 
323  if (fp_filter_out && (filter_wait(filterpid) != 0))
325 
326  mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
327 
328  if (WithCrypto)
329  {
330  /* update crypto information for this message */
331  e->security &= ~(SEC_GOODSIGN | SEC_BADSIGN);
332  e->security |= crypt_query(e->body);
333 
334  /* Remove color cache for this message, in case there
335  * are color patterns for both ~g and ~V */
336  e->pair = 0;
337 
338  /* Process protected headers and autocrypt gossip headers */
340  }
341 
342  if (builtin)
343  {
344  if ((WithCrypto != 0) && (e->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
345  {
346  if (e->security & SEC_GOODSIGN)
347  {
348  if (crypt_smime_verify_sender(m, e) == 0)
349  mutt_message(_("S/MIME signature successfully verified"));
350  else
351  mutt_error(_("S/MIME certificate owner does not match sender"));
352  }
353  else if (e->security & SEC_PARTSIGN)
354  mutt_message(_("Warning: Part of this message has not been signed"));
355  else if (e->security & SEC_SIGN || e->security & SEC_BADSIGN)
356  mutt_error(_("S/MIME signature could NOT be verified"));
357  }
358 
359  if ((WithCrypto != 0) && (e->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
360  {
361  if (e->security & SEC_GOODSIGN)
362  mutt_message(_("PGP signature successfully verified"));
363  else if (e->security & SEC_PARTSIGN)
364  mutt_message(_("Warning: Part of this message has not been signed"));
365  else if (e->security & SEC_SIGN)
366  mutt_message(_("PGP signature could NOT be verified"));
367  }
368 
369  struct Pager info = { 0 };
370  /* Invoke the builtin pager */
371  info.email = e;
372  info.ctx = Context;
373  info.win_ibar = win_ibar;
374  info.win_index = win_index;
375  info.win_pbar = win_pbar;
376  info.win_pager = win_pager;
377  rc = mutt_pager(NULL, mutt_b2s(tempfile), MUTT_PAGER_MESSAGE, &info);
378  }
379  else
380  {
381  mutt_endwin();
382 
383  struct Buffer *cmd = mutt_buffer_pool_get();
384  mutt_buffer_printf(cmd, "%s %s", NONULL(C_Pager), mutt_b2s(tempfile));
385  int r = mutt_system(mutt_b2s(cmd));
386  if (r == -1)
387  mutt_error(_("Error running \"%s\""), mutt_b2s(cmd));
388  unlink(mutt_b2s(tempfile));
390 
391  if (!OptNoCurses)
392  keypad(stdscr, true);
393  if (r != -1)
394  mutt_set_flag(m, e, MUTT_READ, true);
395  if ((r != -1) && C_PromptAfter)
396  {
397  mutt_unget_event(mutt_any_key_to_continue(_("Command: ")), 0);
398  rc = km_dokey(MENU_PAGER);
399  }
400  else
401  rc = 0;
402  }
403 
404 cleanup:
405  mutt_envlist_unset("COLUMNS");
406  mutt_buffer_pool_release(&tempfile);
407  return rc;
408 }
409 
415 void ci_bounce_message(struct Mailbox *m, struct EmailList *el)
416 {
417  if (!m || !el || STAILQ_EMPTY(el))
418  return;
419 
420  char prompt[8193];
421  char scratch[8192];
422  char buf[8192] = { 0 };
423  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
424  char *err = NULL;
425  int rc;
426  int msg_count = 0;
427 
428  struct EmailNode *en = NULL;
429  STAILQ_FOREACH(en, el, entries)
430  {
431  /* RFC5322 mandates a From: header,
432  * so warn before bouncing messages without one */
433  if (TAILQ_EMPTY(&en->email->env->from))
434  mutt_error(_("Warning: message contains no From: header"));
435 
436  msg_count++;
437  }
438 
439  if (msg_count == 1)
440  mutt_str_copy(prompt, _("Bounce message to: "), sizeof(prompt));
441  else
442  mutt_str_copy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
443 
444  rc = mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS);
445  if (rc || (buf[0] == '\0'))
446  return;
447 
448  mutt_addrlist_parse2(&al, buf);
449  if (TAILQ_EMPTY(&al))
450  {
451  mutt_error(_("Error parsing address"));
452  return;
453  }
454 
455  mutt_expand_aliases(&al);
456 
457  if (mutt_addrlist_to_intl(&al, &err) < 0)
458  {
459  mutt_error(_("Bad IDN: '%s'"), err);
460  FREE(&err);
461  mutt_addrlist_clear(&al);
462  return;
463  }
464 
465  buf[0] = '\0';
466  mutt_addrlist_write(&al, buf, sizeof(buf), true);
467 
468 #define EXTRA_SPACE (15 + 7 + 2)
469  snprintf(scratch, sizeof(scratch),
470  ngettext("Bounce message to %s?", "Bounce messages to %s?", msg_count), buf);
471 
472  if (mutt_strwidth(scratch) > (MessageWindow->state.cols - EXTRA_SPACE))
473  {
474  mutt_simple_format(prompt, sizeof(prompt), 0, MessageWindow->state.cols - EXTRA_SPACE,
475  JUSTIFY_LEFT, 0, scratch, sizeof(scratch), false);
476  mutt_str_cat(prompt, sizeof(prompt), "...?");
477  }
478  else
479  mutt_str_copy(prompt, scratch, sizeof(prompt));
480 
481  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
482  {
483  mutt_addrlist_clear(&al);
485  mutt_message(ngettext("Message not bounced", "Messages not bounced", msg_count));
486  return;
487  }
488 
490 
491  struct Message *msg = NULL;
492  STAILQ_FOREACH(en, el, entries)
493  {
494  msg = mx_msg_open(m, en->email->msgno);
495  if (!msg)
496  {
497  rc = -1;
498  break;
499  }
500 
501  rc = mutt_bounce_message(msg->fp, en->email, &al, NeoMutt->sub);
502  mx_msg_close(m, &msg);
503 
504  if (rc < 0)
505  break;
506  }
507 
508  mutt_addrlist_clear(&al);
509  /* If no error, or background, display message. */
510  if ((rc == 0) || (rc == S_BKG))
511  mutt_message(ngettext("Message bounced", "Messages bounced", msg_count));
512 }
513 
521 static void pipe_set_flags(bool decode, bool print, CopyMessageFlags *cmflags,
522  CopyHeaderFlags *chflags)
523 {
524  if (decode)
525  {
526  *chflags |= CH_DECODE | CH_REORDER;
527  *cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
528 
529  if (print ? C_PrintDecodeWeed : C_PipeDecodeWeed)
530  {
531  *chflags |= CH_WEED;
532  *cmflags |= MUTT_CM_WEED;
533  }
534 
535  /* Just as with copy-decode, we need to update the mime fields to avoid
536  * confusing programs that may process the email. However, we don't want
537  * to force those fields to appear in printouts. */
538  if (!print)
539  *chflags |= CH_MIME | CH_TXTPLAIN;
540  }
541 
542  if (print)
543  *cmflags |= MUTT_CM_PRINTING;
544 }
545 
554 static void pipe_msg(struct Mailbox *m, struct Email *e, FILE *fp, bool decode, bool print)
555 {
557  CopyHeaderFlags chflags = CH_FROM;
558 
559  pipe_set_flags(decode, print, &cmflags, &chflags);
560 
561  if ((WithCrypto != 0) && decode && e->security & SEC_ENCRYPT)
562  {
564  return;
565  endwin();
566  }
567 
568  if (decode)
570 
571  mutt_copy_message(fp, m, e, cmflags, chflags, 0);
572 }
573 
588 static int pipe_message(struct Mailbox *m, struct EmailList *el, const char *cmd,
589  bool decode, bool print, bool split, const char *sep)
590 {
591  if (!m || !el)
592  return 1;
593 
594  struct EmailNode *en = STAILQ_FIRST(el);
595  if (!en)
596  return 1;
597 
598  int rc = 0;
599  pid_t pid;
600  FILE *fp_out = NULL;
601 
602  if (!STAILQ_NEXT(en, entries))
603  {
604  /* handle a single message */
606 
607  if ((WithCrypto != 0) && decode)
608  {
610  if ((en->email->security & SEC_ENCRYPT) &&
612  {
613  return 1;
614  }
615  }
616  mutt_endwin();
617 
618  pid = filter_create(cmd, &fp_out, NULL, NULL);
619  if (pid < 0)
620  {
621  mutt_perror(_("Can't create filter process"));
622  return 1;
623  }
624 
625  OptKeepQuiet = true;
626  pipe_msg(m, en->email, fp_out, decode, print);
627  mutt_file_fclose(&fp_out);
628  rc = filter_wait(pid);
629  OptKeepQuiet = false;
630  }
631  else
632  {
633  /* handle tagged messages */
634  if ((WithCrypto != 0) && decode)
635  {
636  STAILQ_FOREACH(en, el, entries)
637  {
640  if ((en->email->security & SEC_ENCRYPT) &&
642  {
643  return 1;
644  }
645  }
646  }
647 
648  if (split)
649  {
650  STAILQ_FOREACH(en, el, entries)
651  {
653  mutt_endwin();
654  pid = filter_create(cmd, &fp_out, NULL, NULL);
655  if (pid < 0)
656  {
657  mutt_perror(_("Can't create filter process"));
658  return 1;
659  }
660  OptKeepQuiet = true;
661  pipe_msg(m, en->email, fp_out, decode, print);
662  /* add the message separator */
663  if (sep)
664  fputs(sep, fp_out);
665  mutt_file_fclose(&fp_out);
666  if (filter_wait(pid) != 0)
667  rc = 1;
668  OptKeepQuiet = false;
669  }
670  }
671  else
672  {
673  mutt_endwin();
674  pid = filter_create(cmd, &fp_out, NULL, NULL);
675  if (pid < 0)
676  {
677  mutt_perror(_("Can't create filter process"));
678  return 1;
679  }
680  OptKeepQuiet = true;
681  STAILQ_FOREACH(en, el, entries)
682  {
684  pipe_msg(m, en->email, fp_out, decode, print);
685  /* add the message separator */
686  if (sep)
687  fputs(sep, fp_out);
688  }
689  mutt_file_fclose(&fp_out);
690  if (filter_wait(pid) != 0)
691  rc = 1;
692  OptKeepQuiet = false;
693  }
694  }
695 
696  if ((rc != 0) || C_WaitKey)
698  return rc;
699 }
700 
706 void mutt_pipe_message(struct Mailbox *m, struct EmailList *el)
707 {
708  if (!m || !el)
709  return;
710 
711  struct Buffer *buf = mutt_buffer_pool_get();
712 
713  if (mutt_buffer_get_field(_("Pipe to command: "), buf, MUTT_CMD) != 0)
714  goto cleanup;
715 
716  if (mutt_buffer_len(buf) == 0)
717  goto cleanup;
718 
720  pipe_message(m, el, mutt_b2s(buf), C_PipeDecode, false, C_PipeSplit, C_PipeSep);
721 
722 cleanup:
724 }
725 
731 void mutt_print_message(struct Mailbox *m, struct EmailList *el)
732 {
733  if (!m || !el)
734  return;
735 
736  if (C_Print && !C_PrintCommand)
737  {
738  mutt_message(_("No printing command has been defined"));
739  return;
740  }
741 
742  int msg_count = 0;
743  struct EmailNode *en = NULL;
744  STAILQ_FOREACH(en, el, entries)
745  {
746  msg_count++;
747  }
748 
749  if (query_quadoption(C_Print, (msg_count == 1) ?
750  _("Print message?") :
751  _("Print tagged messages?")) != MUTT_YES)
752  {
753  return;
754  }
755 
756  if (pipe_message(m, el, C_PrintCommand, C_PrintDecode, true, C_PrintSplit, "\f") == 0)
757  mutt_message(ngettext("Message printed", "Messages printed", msg_count));
758  else
759  {
760  mutt_message(ngettext("Message could not be printed",
761  "Messages could not be printed", msg_count));
762  }
763 }
764 
770 int mutt_select_sort(bool reverse)
771 {
772  enum SortType method = C_Sort; /* save the current method in case of abort */
773  enum SortType new_sort = C_Sort;
774 
775  switch (mutt_multi_choice(reverse ?
776  /* L10N: The highlighted letters must match the "Sort" options */
777  _("Rev-Sort "
778  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
779  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?") :
780  /* L10N: The highlighted letters must match the "Rev-Sort" options */
781  _("Sort "
782  "(d)ate,(f)rm,(r)ecv,(s)ubj,t(o),(t)hread,(u)"
783  "nsort,si(z)e,s(c)ore,s(p)am,(l)abel?"),
784  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
785  _("dfrsotuzcpl")))
786  {
787  case -1: /* abort - don't resort */
788  return -1;
789 
790  case 1: /* (d)ate */
791  new_sort = SORT_DATE;
792  break;
793 
794  case 2: /* (f)rm */
795  new_sort = SORT_FROM;
796  break;
797 
798  case 3: /* (r)ecv */
799  new_sort = SORT_RECEIVED;
800  break;
801 
802  case 4: /* (s)ubj */
803  new_sort = SORT_SUBJECT;
804  break;
805 
806  case 5: /* t(o) */
807  new_sort = SORT_TO;
808  break;
809 
810  case 6: /* (t)hread */
811  new_sort = SORT_THREADS;
812  break;
813 
814  case 7: /* (u)nsort */
815  new_sort = SORT_ORDER;
816  break;
817 
818  case 8: /* si(z)e */
819  new_sort = SORT_SIZE;
820  break;
821 
822  case 9: /* s(c)ore */
823  new_sort = SORT_SCORE;
824  break;
825 
826  case 10: /* s(p)am */
827  new_sort = SORT_SPAM;
828  break;
829 
830  case 11: /* (l)abel */
831  new_sort = SORT_LABEL;
832  break;
833  }
834  if (reverse)
835  new_sort |= SORT_REVERSE;
836 
837  cs_subset_str_native_set(NeoMutt->sub, "sort", new_sort, NULL);
838  return (C_Sort != method) ? 0 : -1; /* no need to resort if it's the same */
839 }
840 
845 {
846  char buf[1024];
847 
848  buf[0] = '\0';
849  if (mutt_get_field(_("Shell command: "), buf, sizeof(buf), MUTT_CMD) != 0)
850  return;
851 
852  if ((buf[0] == '\0') && C_Shell)
853  mutt_str_copy(buf, C_Shell, sizeof(buf));
854  if (buf[0] == '\0')
855  return;
856 
858  mutt_endwin();
859  fflush(stdout);
860  int rc = mutt_system(buf);
861  if (rc == -1)
862  mutt_debug(LL_DEBUG1, "Error running \"%s\"", buf);
863 
864  if ((rc != 0) || C_WaitKey)
867 }
868 
873 {
874  char buf[1024] = { 0 };
875 
877  window_redraw(RootWindow, true);
878  /* if enter is pressed after : with no command, just return */
879  if ((mutt_get_field(":", buf, sizeof(buf), MUTT_COMMAND) != 0) || (buf[0] == '\0'))
880  return;
881 
882  struct Buffer err = mutt_buffer_make(256);
883 
884  /* check if buf is a valid icommand, else fall back quietly to parse_rc_lines */
885  enum CommandResult rc = mutt_parse_icommand(buf, &err);
886  if (!mutt_buffer_is_empty(&err))
887  {
888  /* since errbuf could potentially contain printf() sequences in it,
889  * we must call mutt_error() in this fashion so that vsprintf()
890  * doesn't expect more arguments that we passed */
891  if (rc == MUTT_CMD_ERROR)
892  mutt_error("%s", err.data);
893  else
894  mutt_warning("%s", err.data);
895  }
896  else if (rc != MUTT_CMD_SUCCESS)
897  {
898  rc = mutt_parse_rc_line(buf, &err);
899  if (!mutt_buffer_is_empty(&err))
900  {
901  if (rc == MUTT_CMD_SUCCESS) /* command succeeded with message */
902  mutt_message("%s", err.data);
903  else if (rc == MUTT_CMD_ERROR)
904  mutt_error("%s", err.data);
905  else if (rc == MUTT_CMD_WARNING)
906  mutt_warning("%s", err.data);
907  }
908  }
909  /* else successful command */
910 
911  mutt_buffer_dealloc(&err);
912 }
913 
919 {
920  const char *pfx = NULL;
921  char buf[128];
922 
923  struct AddressList *al = mutt_get_address(env, &pfx);
924  if (!al)
925  return;
926 
927  /* Note: We don't convert IDNA to local representation this time.
928  * That is intentional, so the user has an opportunity to copy &
929  * paste the on-the-wire form of the address to other, IDN-unable
930  * software. */
931  buf[0] = '\0';
932  mutt_addrlist_write(al, buf, sizeof(buf), false);
933  mutt_message("%s: %s", pfx, buf);
934 }
935 
944 static void set_copy_flags(struct Email *e, bool decode, bool decrypt,
945  CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
946 {
947  *cmflags = MUTT_CM_NO_FLAGS;
948  *chflags = CH_UPDATE_LEN;
949 
950  if ((WithCrypto != 0) && !decode && decrypt && (e->security & SEC_ENCRYPT))
951  {
953  {
954  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
955  *cmflags = MUTT_CM_DECODE_PGP;
956  }
957  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
959  {
960  decode = 1;
961  }
962  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
964  {
965  *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME;
966  *cmflags = MUTT_CM_DECODE_SMIME;
967  }
968  }
969 
970  if (decode)
971  {
972  *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN;
973  *cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
974 
975  if (!decrypt) /* If decode doesn't kick in for decrypt, */
976  {
977  *chflags |= CH_DECODE; /* then decode RFC2047 headers, */
978 
979  if (C_CopyDecodeWeed)
980  {
981  *chflags |= CH_WEED; /* and respect $weed. */
982  *cmflags |= MUTT_CM_WEED;
983  }
984  }
985  }
986 }
987 
998 int mutt_save_message_ctx(struct Email *e, bool delete_original, bool decode,
999  bool decrypt, struct Mailbox *m)
1000 {
1002  CopyHeaderFlags chflags = CH_NO_FLAGS;
1003  int rc;
1004 
1005  set_copy_flags(e, decode, decrypt, &cmflags, &chflags);
1006 
1007  if (decode || decrypt)
1009 
1010  rc = mutt_append_message(m, Context->mailbox, e, cmflags, chflags);
1011  if (rc != 0)
1012  return rc;
1013 
1014  if (delete_original)
1015  {
1018  if (C_DeleteUntag)
1019  mutt_set_flag(Context->mailbox, e, MUTT_TAG, false);
1020  }
1021 
1022  return 0;
1023 }
1024 
1035 int mutt_save_message(struct Mailbox *m, struct EmailList *el,
1036  bool delete_original, bool decode, bool decrypt)
1037 {
1038  if (!el || STAILQ_EMPTY(el))
1039  return -1;
1040 
1041  bool need_passphrase = false;
1042  int app = 0;
1043  int rc = -1;
1044  const char *prompt = NULL;
1045  const char *progress_msg = NULL;
1046  struct Progress progress;
1047  int tagged_progress_count = 0;
1048  struct stat st;
1049  struct EmailNode *en = STAILQ_FIRST(el);
1050  bool single = !STAILQ_NEXT(en, entries);
1051 
1052  struct Buffer *buf = mutt_buffer_pool_get();
1053 
1054  if (delete_original)
1055  {
1056  if (decode)
1057  prompt = single ? _("Decode-save to mailbox") : _("Decode-save tagged to mailbox");
1058  else if (decrypt)
1059  prompt = single ? _("Decrypt-save to mailbox") : _("Decrypt-save tagged to mailbox");
1060  else
1061  prompt = single ? _("Save to mailbox") : _("Save tagged to mailbox");
1062  }
1063  else
1064  {
1065  if (decode)
1066  prompt = single ? _("Decode-copy to mailbox") : _("Decode-copy tagged to mailbox");
1067  else if (decrypt)
1068  prompt = single ? _("Decrypt-copy to mailbox") : _("Decrypt-copy tagged to mailbox");
1069  else
1070  prompt = single ? _("Copy to mailbox") : _("Copy tagged to mailbox");
1071  }
1072 
1073  if (WithCrypto)
1074  {
1075  need_passphrase = (en->email->security & SEC_ENCRYPT);
1076  app = en->email->security;
1077  }
1079  mutt_default_save(buf->data, buf->dsize, en->email);
1080  mutt_buffer_fix_dptr(buf);
1081 
1083  if (mutt_buffer_enter_fname(prompt, buf, false) == -1)
1084  goto cleanup;
1085 
1086  size_t pathlen = mutt_buffer_len(buf);
1087  if (pathlen == 0)
1088  goto cleanup;
1089 
1090  /* Trim any trailing '/' */
1091  if (buf->data[pathlen - 1] == '/')
1092  buf->data[pathlen - 1] = '\0';
1093 
1094  /* This is an undocumented feature of ELM pointed out to me by Felix von
1095  * Leitner <leitner@prz.fu-berlin.de> */
1096  if (mutt_buffer_len(&LastSaveFolder) == 0)
1097  mutt_buffer_alloc(&LastSaveFolder, PATH_MAX);
1098  if (mutt_str_equal(mutt_b2s(buf), "."))
1099  mutt_buffer_copy(buf, &LastSaveFolder);
1100  else
1101  mutt_buffer_strcpy(&LastSaveFolder, mutt_b2s(buf));
1102 
1104 
1105  /* check to make sure that this file is really the one the user wants */
1106  if (mutt_save_confirm(mutt_b2s(buf), &st) != 0)
1107  goto cleanup;
1108 
1109  if ((WithCrypto != 0) && need_passphrase && (decode || decrypt) &&
1110  !crypt_valid_passphrase(app))
1111  {
1112  goto cleanup;
1113  }
1114 
1115  mutt_message(_("Copying to %s..."), mutt_b2s(buf));
1116 
1117 #ifdef USE_IMAP
1118  if ((m->type == MUTT_IMAP) && !(decode || decrypt) &&
1119  (imap_path_probe(mutt_b2s(buf), NULL) == MUTT_IMAP))
1120  {
1121  switch (imap_copy_messages(m, el, mutt_b2s(buf), delete_original))
1122  {
1123  /* success */
1124  case 0:
1125  mutt_clear_error();
1126  rc = 0;
1127  goto cleanup;
1128  /* non-fatal error: continue to fetch/append */
1129  case 1:
1130  break;
1131  /* fatal error, abort */
1132  case -1:
1133  goto cleanup;
1134  }
1135  }
1136 #endif
1137 
1139  struct Mailbox *m_save = mx_path_resolve(mutt_b2s(buf));
1140  bool old_append = m_save->append;
1141  OpenMailboxFlags mbox_flags = MUTT_NEWFOLDER;
1142  /* Display a tagged message progress counter, rather than (for
1143  * IMAP) a per-message progress counter */
1144  if (!single)
1145  mbox_flags |= MUTT_QUIET;
1146  struct Context *ctx_save = mx_mbox_open(m_save, mbox_flags);
1147  if (!ctx_save)
1148  {
1149  mailbox_free(&m_save);
1150  goto cleanup;
1151  }
1152  m_save->append = true;
1153 
1154 #ifdef USE_COMP_MBOX
1155  /* If we're saving to a compressed mailbox, the stats won't be updated
1156  * until the next open. Until then, improvise. */
1157  struct Mailbox *m_comp = NULL;
1158  if (ctx_save->mailbox->compress_info)
1159  {
1160  m_comp = mailbox_find(ctx_save->mailbox->realpath);
1161  }
1162  /* We probably haven't been opened yet */
1163  if (m_comp && (m_comp->msg_count == 0))
1164  m_comp = NULL;
1165 #endif
1166  if (single)
1167  {
1168  if (mutt_save_message_ctx(en->email, delete_original, decode, decrypt,
1169  ctx_save->mailbox) != 0)
1170  {
1171  mx_mbox_close(&ctx_save);
1172  m_save->append = old_append;
1173  goto cleanup;
1174  }
1175 #ifdef USE_COMP_MBOX
1176  if (m_comp)
1177  {
1178  m_comp->msg_count++;
1179  if (!en->email->read)
1180  {
1181  m_comp->msg_unread++;
1182  if (!en->email->old)
1183  m_comp->msg_new++;
1184  }
1185  if (en->email->flagged)
1186  m_comp->msg_flagged++;
1187  }
1188 #endif
1189  }
1190  else
1191  {
1192  rc = 0;
1193 
1194  // L10N: Progress meter message when saving tagged messages
1195  progress_msg = delete_original ? _("Saving tagged messages...") :
1196  // L10N: Progress meter message when copying tagged messages
1197  _("Copying tagged messages...");
1198 
1199  int msg_count = 0;
1200  STAILQ_FOREACH(en, el, entries)
1201  {
1202  msg_count++;
1203  }
1204  mutt_progress_init(&progress, progress_msg, MUTT_PROGRESS_WRITE, msg_count);
1205 
1206 #ifdef USE_NOTMUCH
1207  if (m->type == MUTT_NOTMUCH)
1208  nm_db_longrun_init(m, true);
1209 #endif
1210  STAILQ_FOREACH(en, el, entries)
1211  {
1212  mutt_progress_update(&progress, ++tagged_progress_count, -1);
1214  rc = mutt_save_message_ctx(en->email, delete_original, decode, decrypt,
1215  ctx_save->mailbox);
1216  if (rc != 0)
1217  break;
1218 #ifdef USE_COMP_MBOX
1219  if (m_comp)
1220  {
1221  struct Email *e2 = en->email;
1222  m_comp->msg_count++;
1223  if (!e2->read)
1224  {
1225  m_comp->msg_unread++;
1226  if (!e2->old)
1227  m_comp->msg_new++;
1228  }
1229  if (e2->flagged)
1230  m_comp->msg_flagged++;
1231  }
1232 #endif
1233  }
1234 #ifdef USE_NOTMUCH
1235  if (m->type == MUTT_NOTMUCH)
1236  nm_db_longrun_done(m);
1237 #endif
1238  if (rc != 0)
1239  {
1240  mx_mbox_close(&ctx_save);
1241  m_save->append = old_append;
1242  goto cleanup;
1243  }
1244  }
1245 
1246  const bool need_mailbox_cleanup = ((ctx_save->mailbox->type == MUTT_MBOX) ||
1247  (ctx_save->mailbox->type == MUTT_MMDF));
1248 
1249  mx_mbox_close(&ctx_save);
1250  m_save->append = old_append;
1251 
1252  if (need_mailbox_cleanup)
1253  mutt_mailbox_cleanup(mutt_b2s(buf), &st);
1254 
1255  mutt_clear_error();
1256  rc = 0;
1257 
1258 cleanup:
1260  return rc;
1261 }
1262 
1272 bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
1273 {
1274  char buf[1024];
1275  char obuf[1024];
1276  char tmp[256];
1277  char charset[256];
1278 
1279  bool charset_changed = false;
1280  bool type_changed = false;
1281  bool structure_changed = false;
1282 
1283  char *cp = mutt_param_get(&b->parameter, "charset");
1284  mutt_str_copy(charset, cp, sizeof(charset));
1285 
1286  snprintf(buf, sizeof(buf), "%s/%s", TYPE(b), b->subtype);
1287  mutt_str_copy(obuf, buf, sizeof(obuf));
1288  if (!TAILQ_EMPTY(&b->parameter))
1289  {
1290  size_t l = strlen(buf);
1291  struct Parameter *np = NULL;
1292  TAILQ_FOREACH(np, &b->parameter, entries)
1293  {
1294  mutt_addr_cat(tmp, sizeof(tmp), np->value, MimeSpecials);
1295  l += snprintf(buf + l, sizeof(buf) - l, "; %s=%s", np->attribute, tmp);
1296  if (l >= sizeof(buf))
1297  {
1298  // L10N: e.g. "text/plain; charset=UTF-8; ..."
1299  mutt_error(_("Content type is too long"));
1300  return false;
1301  }
1302  }
1303  }
1304 
1305  if ((mutt_get_field("Content-Type: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0) ||
1306  (buf[0] == '\0'))
1307  {
1308  return false;
1309  }
1310 
1311  /* clean up previous junk */
1313  FREE(&b->subtype);
1314 
1315  mutt_parse_content_type(buf, b);
1316 
1317  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1318  type_changed = !mutt_istr_equal(tmp, obuf);
1319  charset_changed =
1320  !mutt_istr_equal(charset, mutt_param_get(&b->parameter, "charset"));
1321 
1322  /* if in send mode, check for conversion - current setting is default. */
1323 
1324  if (!e && (b->type == TYPE_TEXT) && charset_changed)
1325  {
1326  snprintf(tmp, sizeof(tmp), _("Convert to %s upon sending?"),
1327  mutt_param_get(&b->parameter, "charset"));
1328  enum QuadOption ans = mutt_yesorno(tmp, b->noconv ? MUTT_NO : MUTT_YES);
1329  if (ans != MUTT_ABORT)
1330  b->noconv = (ans == MUTT_NO);
1331  }
1332 
1333  /* inform the user */
1334 
1335  snprintf(tmp, sizeof(tmp), "%s/%s", TYPE(b), NONULL(b->subtype));
1336  if (type_changed)
1337  mutt_message(_("Content-Type changed to %s"), tmp);
1338  if ((b->type == TYPE_TEXT) && charset_changed)
1339  {
1340  if (type_changed)
1341  mutt_sleep(1);
1342  mutt_message(b->noconv ? _("Character set changed to %s; not converting") :
1343  _("Character set changed to %s; converting"),
1344  mutt_param_get(&b->parameter, "charset"));
1345  }
1346 
1347  b->force_charset |= charset_changed;
1348 
1349  if (!is_multipart(b) && b->parts)
1350  {
1351  structure_changed = true;
1352  mutt_body_free(&b->parts);
1353  }
1354  if (!mutt_is_message_type(b->type, b->subtype) && b->email)
1355  {
1356  structure_changed = true;
1357  b->email->body = NULL;
1358  email_free(&b->email);
1359  }
1360 
1361  if (fp && !b->parts && (is_multipart(b) || mutt_is_message_type(b->type, b->subtype)))
1362  {
1363  structure_changed = true;
1364  mutt_parse_part(fp, b);
1365  }
1366 
1367  if ((WithCrypto != 0) && e)
1368  {
1369  if (e->body == b)
1370  e->security = SEC_NO_FLAGS;
1371 
1372  e->security |= crypt_query(b);
1373  }
1374 
1375  return structure_changed;
1376 }
1377 
1384 static bool check_traditional_pgp(struct Email *e, MuttRedrawFlags *redraw)
1385 {
1386  bool rc = false;
1387 
1389 
1391  struct Message *msg = mx_msg_open(Context->mailbox, e->msgno);
1392  if (!msg)
1393  return 0;
1394  if (crypt_pgp_check_traditional(msg->fp, e->body, false))
1395  {
1396  e->security = crypt_query(e->body);
1397  *redraw |= REDRAW_FULL;
1398  rc = true;
1399  }
1400 
1402  mx_msg_close(Context->mailbox, &msg);
1403  return rc;
1404 }
1405 
1412 bool mutt_check_traditional_pgp(struct EmailList *el, MuttRedrawFlags *redraw)
1413 {
1414  bool rc = false;
1415  struct EmailNode *en = NULL;
1416  STAILQ_FOREACH(en, el, entries)
1417  {
1418  if (!(en->email->security & PGP_TRADITIONAL_CHECKED))
1419  rc = check_traditional_pgp(en->email, redraw) || rc;
1420  }
1421 
1422  return rc;
1423 }
1424 
1429 {
1431 }
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:658
char * attribute
Parameter name.
Definition: parameter.h:34
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
Convenience wrapper for the gui headers.
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:998
int mutt_save_message(struct Mailbox *m, struct EmailList *el, bool delete_original, bool decode, bool decrypt)
Save an email.
Definition: commands.c:1035
int mutt_bounce_message(FILE *fp, struct Email *e, struct AddressList *to, struct ConfigSubset *sub)
Bounce an email message.
Definition: sendlib.c:1371
#define mutt_warning(...)
Definition: logging.h:82
The "current" mailbox.
Definition: context.h:38
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
struct MuttWindow * win_index
Definition: pager.h:74
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
unsigned char C_CryptVerifySig
Config: Verify PGP or SMIME signatures.
Definition: config.c:123
Manage keymappings.
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
Miscellaneous email parsing routines.
int msg_count
Total number of messages.
Definition: mailbox.h:91
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
#define WithCrypto
Definition: lib.h:123
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1366
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:44
IMAP network mailbox.
void mutt_pipe_message(struct Mailbox *m, struct EmailList *el)
Pipe a message.
Definition: commands.c:706
Left justify the text.
Definition: curs_lib.h:47
The envelope/body of an email.
Definition: email.h:37
SortType
Methods for sorting.
Definition: sort2.h:43
WHERE bool C_DeleteUntag
Config: Untag messages when they are marked for deletion.
Definition: mutt_globals.h:145
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:944
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
#define mutt_perror(...)
Definition: logging.h:85
CommandResult
Error codes for command_t parse functions.
Definition: mutt_commands.h:34
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2367
Config/command parsing.
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct Body * body
List of MIME parts.
Definition: email.h:91
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
Error: Can&#39;t help the user.
Definition: mutt_commands.h:36
struct AutocryptHeader * autocrypt_gossip
Definition: envelope.h:86
void window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:763
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:630
Structs that make up an email.
String processing routines to generate the mail index.
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
The "currently-open" mailbox.
#define is_multipart(body)
Definition: mime.h:82
Autocrypt end-to-end encryption.
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:84
void mutt_mailbox_cleanup(const char *path, struct stat *st)
Restore the timestamp of a mailbox.
Definition: mutt_mailbox.c:354
Convenience wrapper for the send headers.
#define mutt_message(...)
Definition: logging.h:83
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
#define MUTT_PAGER_MESSAGE
Definition: pager.h:58
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
void mutt_display_address(struct Envelope *env)
Display the address of a message.
Definition: commands.c:918
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:68
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
Progress tracks elements, according to $write_inc
Definition: progress.h:43
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:94
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
NeoMutt Logging.
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_check_stats(void)
Forcibly update mailbox stats.
Definition: commands.c:1428
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
struct Regex * C_ReplyRegex
Config: Regex to match message reply subjects like "re: ".
Definition: globals.c:37
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
void mutt_enter_command(void)
enter a neomutt command
Definition: commands.c:872
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
String manipulation buffer.
Definition: buffer.h:33
int mutt_autocrypt_process_gossip_header(struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:398
bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: config.c:58
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1039
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:471
Sort by the email&#39;s From field.
Definition: sort2.h:49
bool C_PrintSplit
Config: Print multiple messages separately.
Definition: commands.c:90
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:835
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
char * C_PipeSep
Config: Separator to add between multiple piped messages.
Definition: commands.c:87
Sort by the email&#39;s score.
Definition: sort2.h:54
char * real_subj
Offset of the real subject.
Definition: envelope.h:67
bool changed
Email has been edited.
Definition: email.h:48
static const char * ExtPagerProgress
Definition: commands.c:93
bool C_PipeDecode
Config: Decode the message when piping it.
Definition: commands.c:86
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:303
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
bool mutt_check_traditional_pgp(struct EmailList *el, MuttRedrawFlags *redraw)
Check if a message has inline PGP content.
Definition: commands.c:1412
Messages to be purged (bypass trash)
Definition: mutt.h:100
A division of the screen.
Definition: mutt_window.h:115
void nm_db_longrun_init(struct Mailbox *m, bool writable)
Start a long transaction.
Definition: db.c:289
#define S_BKG
Definition: string2.h:42
#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
Sort by the emails label.
Definition: sort2.h:64
Information commands.
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mx.h:50
WHERE struct Context * Context
Definition: mutt_globals.h:42
int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
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
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
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:1819
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:654
Flags to control mutt_expando_format()
#define MUTT_CM_PRINTING
Printing the message - display light.
Definition: copy.h:42
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
Container for Accounts, Notifications.
Definition: neomutt.h:36
A progress bar.
Definition: progress.h:50
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:598
static int pipe_message(struct Mailbox *m, struct EmailList *el, const char *cmd, bool decode, bool print, bool split, const char *sep)
Pipe message to a command.
Definition: commands.c:588
enum CommandResult mutt_parse_icommand(char *line, struct Buffer *err)
Parse an informational command.
Definition: icommands.c:78
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:35
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1349
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
The body of an email.
Definition: body.h:34
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
static void pipe_msg(struct Mailbox *m, struct Email *e, FILE *fp, bool decode, bool print)
Pipe a message.
Definition: commands.c:554
Convenience wrapper for the config headers.
WHERE char * C_Shell
Config: External command to run subshells in.
Definition: mutt_globals.h:106
Email Address Handling.
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
Assorted sorting methods.
void mutt_print_message(struct Mailbox *m, struct EmailList *el)
Print a message.
Definition: commands.c:731
Some miscellaneous functions.
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:292
Pager pager (email viewer)
Definition: keymap.h:81
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1204
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
Sort by the size of the email.
Definition: sort2.h:46
size_t dsize
Length of data.
Definition: buffer.h:37
bool read
Email is read.
Definition: email.h:51
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
struct Mailbox * mailbox
Definition: context.h:50
Parse and execute user-defined hooks.
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:447
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:38
Many unsorted constants and some structs.
API for mailboxes.
bool old
Email is seen, but unread.
Definition: email.h:50
Data passed to index_format_str()
Definition: hdrline.h:44
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:63
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:50
#define CH_WEED
Weed the headers?
Definition: copy.h:52
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
bool force_charset
Send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:74
struct Envelope * env
Envelope information.
Definition: email.h:90
bool C_PrintDecode
Config: Decode message before printing it.
Definition: commands.c:89
Convenience wrapper for the core headers.
struct Mailbox * mailbox
Definition: hdrline.h:46
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:72
void mutt_shell_escape(void)
invoke a command in a subshell
Definition: commands.c:844
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:63
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.
Definition: commands.c:205
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:61
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:407
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:60
Email Aliases.
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
User aborted the question (with Ctrl-G)
Definition: quad.h:38
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: mutt_globals.h:103
Progress bar.
WHERE bool C_PrintDecodeWeed
Config: Control whether to weed headers when printing an email.
Definition: mutt_globals.h:153
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:128
bool C_PipeSplit
Config: Run the pipe command on each message separately.
Definition: commands.c:88
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
struct MuttWindow * win_pager
Definition: pager.h:76
char * subtype
content-type subtype
Definition: body.h:37
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:62
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:60
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:1438
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:153
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
struct Context * ctx
Current mailbox.
Definition: pager.h:67
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:933
Prototypes for many functions.
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:552
Notmuch virtual mailbox type.
Sort by email threads.
Definition: sort2.h:51
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
Definition: alias.c:326
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
A local copy of an email.
Definition: mx.h:82
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:571
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: mutt_window.c:45
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: mutt_globals.h:124
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:1560
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
Messages to be deleted.
Definition: mutt.h:98
A mailbox.
Definition: mailbox.h:81
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1359
#define PATH_MAX
Definition: mutt.h:44
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:138
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
Manage where the email is piped to external commands.
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
Type: &#39;text/*&#39;.
Definition: mime.h:38
const char MimeSpecials[]
Characters that need special treatment in MIME.
Definition: mime.c:67
#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:455
static bool check_traditional_pgp(struct Email *e, MuttRedrawFlags *redraw)
Check for an inline PGP content.
Definition: commands.c:1384
Tagged messages.
Definition: mutt.h:103
char * data
Pointer to data.
Definition: buffer.h:35
#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
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:272
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
void nm_db_longrun_done(struct Mailbox *m)
Finish a long transaction.
Definition: db.c:304
Messages that have been read.
Definition: mutt.h:96
Definitions of NeoMutt commands.
GUI present the user with a selectable list.
void mutt_file_resolve_symlink(struct Buffer *buf)
Resolve a symlink in place.
Definition: file.c:1617
int msg_in_pager
Definition: hdrline.h:47
API for encryption/signing of emails.
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:508
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
Sort by the email&#39;s spam score.
Definition: sort2.h:59
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:610
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:55
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
Sort by the email&#39;s To field.
Definition: sort2.h:53
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:46
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:88
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
#define MUTT_MAILBOX_CHECK_FORCE
Definition: mutt_mailbox.h:16
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:85
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
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:593
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:281
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
bool C_PromptAfter
Config: Pause after running an external pager.
Definition: commands.c:91
#define TYPE(body)
Definition: mime.h:89
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:517
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:425
GUI display a file/email/help in a viewport with paging.
WHERE bool C_CopyDecodeWeed
Config: Controls whether to weed headers when copying or saving emails.
Definition: mutt_globals.h:143
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1657
struct Email * email
Current message.
Definition: pager.h:68
void ci_bounce_message(struct Mailbox *m, struct EmailList *el)
Bounce an email.
Definition: commands.c:415
Success: Command worked.
Definition: mutt_commands.h:38
char * subject
Email&#39;s subject.
Definition: envelope.h:66
char * value
Parameter value.
Definition: parameter.h:35
Duplicate the structure of an entire email.
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
Log at debug level 1.
Definition: logging.h:40
WHERE char * C_Pager
Config: External command for viewing messages, or &#39;builtin&#39; to use NeoMutt&#39;s.
Definition: mutt_globals.h:99
Warning: Help given to the user.
Definition: mutt_commands.h:37
bool flagged
Marked important?
Definition: email.h:43
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
char * C_DisplayFilter
Config: External command to pre-process an email before display.
Definition: commands.c:85
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
int msg_new
Number of new messages.
Definition: mailbox.h:95
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
struct Email * email
Email in the list.
Definition: email.h:127
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_error(...)
Definition: logging.h:84
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
int mutt_append_message(struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Append a message.
Definition: copy.c:905
FILE * fp
pointer to the message data
Definition: mx.h:84
int mutt_select_sort(bool reverse)
Ask the user for a sort method.
Definition: commands.c:770
Attribute associated with a MIME part.
Definition: parameter.h:32
#define MUTT_CM_DECODE_PGP
Used for decoding PGP messages.
Definition: copy.h:44
#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
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
const char * pager_progress
Definition: hdrline.h:49
WHERE bool C_PipeDecodeWeed
Config: Control whether to weed headers when piping an email.
Definition: mutt_globals.h:152
static void process_protected_headers(struct Email *e)
Get the protected header and update the index.
Definition: commands.c:110
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: globals.c:40
#define STAILQ_EMPTY(head)
Definition: queue.h:345
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:419
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
void mutt_commands_cleanup(void)
Clean up commands globals.
Definition: commands.c:101
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:747
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
List of Emails.
Definition: email.h:125
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:99
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: mutt_globals.h:128
Sort by when the message were delivered locally.
Definition: sort2.h:52
#define TAILQ_EMPTY(head)
Definition: queue.h:714
#define MUTT_NEWFOLDER
Create a new folder - same as MUTT_APPEND,.
Definition: mx.h:56
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:2239
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1272
#define EXTRA_SPACE
Sort by the date the email was sent.
Definition: sort2.h:45
Convenience wrapper for the library headers.
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:81
WHERE char * C_PagerFormat
Config: printf-like format string for the pager&#39;s status bar.
Definition: mutt_globals.h:100
struct Email * email
Definition: hdrline.h:48
bool C_CryptProtectedHeadersSave
Config: Save the cleartext Subject with the headers.
Definition: config.c:59
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define STAILQ_FIRST(head)
Definition: queue.h:347
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:685
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:87
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
int pair
Color-pair to use when displaying in the index.
Definition: email.h:80
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:681
Sort by the email&#39;s subject.
Definition: sort2.h:48
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:88
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1158
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:89
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
The header of an Email.
Definition: envelope.h:54
int msgno
Number displayed to the user.
Definition: email.h:87
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:1093
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: mutt_globals.h:169
#define MUTT_MAILBOX_CHECK_FORCE_STATS
Definition: mutt_mailbox.h:17
uint16_t MuttRedrawFlags
Flags, e.g. REDRAW_INDEX.
Definition: mutt_menu.h:38
static void pipe_set_flags(bool decode, bool print, CopyMessageFlags *cmflags, CopyHeaderFlags *chflags)
Generate flags for copy header/message.
Definition: commands.c:521
struct MuttWindow * win_pbar
Definition: pager.h:75