NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
postpone.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <limits.h>
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <time.h>
37 #include <unistd.h>
38 #include "mutt/mutt.h"
39 #include "config/lib.h"
40 #include "email/lib.h"
41 #include "core/lib.h"
42 #include "mutt.h"
43 #include "context.h"
44 #include "format_flags.h"
45 #include "globals.h"
46 #include "handler.h"
47 #include "hdrline.h"
48 #include "keymap.h"
49 #include "mutt_logging.h"
50 #include "mutt_menu.h"
51 #include "mutt_thread.h"
52 #include "muttlib.h"
53 #include "mx.h"
54 #include "ncrypt/ncrypt.h"
55 #include "opcodes.h"
56 #include "options.h"
57 #include "protos.h"
58 #include "send.h"
59 #include "sendlib.h"
60 #include "sort.h"
61 #include "state.h"
62 #ifdef USE_IMAP
63 #include "imap/imap.h"
64 #endif
65 
66 static const struct Mapping PostponeHelp[] = {
67  { N_("Exit"), OP_EXIT },
68  { N_("Del"), OP_DELETE },
69  { N_("Undel"), OP_UNDELETE },
70  { N_("Help"), OP_HELP },
71  { NULL, 0 },
72 };
73 
74 static short PostCount = 0;
75 static bool UpdateNumPostponed = false;
76 
85 int mutt_num_postponed(struct Mailbox *m, bool force)
86 {
87  struct stat st;
88 
89  static time_t LastModify = 0;
90  static char *OldPostponed = NULL;
91 
93  {
94  UpdateNumPostponed = false;
95  force = true;
96  }
97 
98  if (mutt_str_strcmp(C_Postponed, OldPostponed) != 0)
99  {
100  FREE(&OldPostponed);
101  OldPostponed = mutt_str_strdup(C_Postponed);
102  LastModify = 0;
103  force = true;
104  }
105 
106  if (!C_Postponed)
107  return 0;
108 
109  // We currently are in the C_Postponed mailbox so just pick the current status
110  if (m && (mutt_str_strcmp(C_Postponed, m->realpath) == 0))
111  {
112  PostCount = m->msg_count - m->msg_deleted;
113  return PostCount;
114  }
115 
116 #ifdef USE_IMAP
117  /* LastModify is useless for IMAP */
118  if (imap_path_probe(C_Postponed, NULL) == MUTT_IMAP)
119  {
120  if (force)
121  {
122  short newpc;
123 
124  newpc = imap_path_status(C_Postponed, false);
125  if (newpc >= 0)
126  {
127  PostCount = newpc;
128  mutt_debug(LL_DEBUG3, "%d postponed IMAP messages found\n", PostCount);
129  }
130  else
131  mutt_debug(LL_DEBUG3, "using old IMAP postponed count\n");
132  }
133  return PostCount;
134  }
135 #endif
136 
137  if (stat(C_Postponed, &st) == -1)
138  {
139  PostCount = 0;
140  LastModify = 0;
141  return 0;
142  }
143 
144  if (S_ISDIR(st.st_mode))
145  {
146  /* if we have a maildir mailbox, we need to stat the "new" dir */
147 
148  char buf[PATH_MAX];
149 
150  snprintf(buf, sizeof(buf), "%s/new", C_Postponed);
151  if ((access(buf, F_OK) == 0) && (stat(buf, &st) == -1))
152  {
153  PostCount = 0;
154  LastModify = 0;
155  return 0;
156  }
157  }
158 
159  if (LastModify < st.st_mtime)
160  {
161 #ifdef USE_NNTP
162  int optnews = OptNews;
163 #endif
164  LastModify = st.st_mtime;
165 
166  if (access(C_Postponed, R_OK | F_OK) != 0)
167  return PostCount = 0;
168 #ifdef USE_NNTP
169  if (optnews)
170  OptNews = false;
171 #endif
172  struct Mailbox *m_post = mx_path_resolve(C_Postponed);
173  struct Context *ctx = mx_mbox_open(m_post, MUTT_NOSORT | MUTT_QUIET);
174  if (!ctx)
175  {
176  mailbox_free(&m_post);
177  PostCount = 0;
178  }
179  else
180  PostCount = ctx->mailbox->msg_count;
181  mx_fastclose_mailbox(m_post);
182  ctx_free(&ctx);
183 #ifdef USE_NNTP
184  if (optnews)
185  OptNews = true;
186 #endif
187  }
188 
189  return PostCount;
190 }
191 
196 {
197  UpdateNumPostponed = true;
198 }
199 
203 static void post_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
204 {
205  struct Context *ctx = menu->data;
206 
207  mutt_make_string_flags(buf, buflen, NONULL(C_IndexFormat), ctx, ctx->mailbox,
208  ctx->mailbox->emails[line], MUTT_FORMAT_ARROWCURSOR);
209 }
210 
215 static struct Email *select_msg(struct Context *ctx)
216 {
217  int r = -1;
218  bool done = false;
219  char helpstr[1024];
220 
221  struct Menu *menu = mutt_menu_new(MENU_POSTPONE);
223  menu->max = ctx->mailbox->msg_count;
224  menu->title = _("Postponed Messages");
225  menu->data = ctx;
226  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_POSTPONE, PostponeHelp);
228 
229  /* The postponed mailbox is setup to have sorting disabled, but the global
230  * C_Sort variable may indicate something different. Sorting has to be
231  * disabled while the postpone menu is being displayed. */
232  const short orig_sort = C_Sort;
233  C_Sort = SORT_ORDER;
234 
235  while (!done)
236  {
237  const int op = mutt_menu_loop(menu);
238  switch (op)
239  {
240  case OP_DELETE:
241  case OP_UNDELETE:
242  /* should deleted draft messages be saved in the trash folder? */
243  mutt_set_flag(ctx->mailbox, ctx->mailbox->emails[menu->current],
244  MUTT_DELETE, (op == OP_DELETE));
246  if (C_Resolve && (menu->current < menu->max - 1))
247  {
248  menu->oldcurrent = menu->current;
249  menu->current++;
250  if (menu->current >= menu->top + menu->pagelen)
251  {
252  menu->top = menu->current;
253  menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
254  }
255  else
256  menu->redraw |= REDRAW_MOTION_RESYNC;
257  }
258  else
259  menu->redraw |= REDRAW_CURRENT;
260  break;
261 
262  case OP_GENERIC_SELECT_ENTRY:
263  r = menu->current;
264  done = true;
265  break;
266 
267  case OP_EXIT:
268  done = true;
269  break;
270  }
271  }
272 
273  C_Sort = orig_sort;
274  mutt_menu_pop_current(menu);
275  mutt_menu_free(&menu);
276  return (r > -1) ? ctx->mailbox->emails[r] : NULL;
277 }
278 
290 int mutt_get_postponed(struct Context *ctx, struct Email *hdr,
291  struct Email **cur, char *fcc, size_t fcclen)
292 {
293  if (!C_Postponed)
294  return -1;
295 
296  struct Email *e = NULL;
297  int rc = SEND_POSTPONED;
298  const char *p = NULL;
299  struct Context *ctx_post = NULL;
300 
301  struct Mailbox *m = mx_path_resolve(C_Postponed);
302  if (ctx->mailbox == m)
303  ctx_post = ctx;
304  else
305  ctx_post = mx_mbox_open(m, MUTT_NOSORT);
306 
307  if (!ctx_post)
308  {
309  PostCount = 0;
310  mutt_error(_("No postponed messages"));
311  mailbox_free(&m);
312  return -1;
313  }
314 
315  if (ctx_post->mailbox->msg_count == 0)
316  {
317  PostCount = 0;
318  if (ctx_post == ctx)
319  ctx_post = NULL;
320  else
321  mx_mbox_close(&ctx_post);
322  mutt_error(_("No postponed messages"));
323  return -1;
324  }
325 
326  if (ctx_post->mailbox->msg_count == 1)
327  {
328  /* only one message, so just use that one. */
329  e = ctx_post->mailbox->emails[0];
330  }
331  else if (!(e = select_msg(ctx_post)))
332  {
333  if (ctx_post == ctx)
334  ctx_post = NULL;
335  else
336  mx_mbox_close(&ctx_post);
337  return -1;
338  }
339 
340  if (mutt_prepare_template(NULL, ctx_post->mailbox, hdr, e, false) < 0)
341  {
342  if (ctx_post != ctx)
343  {
344  mx_fastclose_mailbox(ctx_post->mailbox);
345  FREE(&ctx_post);
346  }
347  return -1;
348  }
349 
350  /* finished with this message, so delete it. */
351  mutt_set_flag(ctx_post->mailbox, e, MUTT_DELETE, true);
352  mutt_set_flag(ctx_post->mailbox, e, MUTT_PURGE, true);
353 
354  /* update the count for the status display */
355  PostCount = ctx_post->mailbox->msg_count - ctx_post->mailbox->msg_deleted;
356 
357  /* avoid the "purge deleted messages" prompt */
358  int opt_delete = C_Delete;
359  C_Delete = MUTT_YES;
360  if (ctx_post == ctx)
361  ctx_post = NULL;
362  else
363  mx_mbox_close(&ctx_post);
364  C_Delete = opt_delete;
365 
366  struct ListNode *np = NULL, *tmp = NULL;
367  STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
368  {
369  size_t plen = mutt_str_startswith(np->data, "X-Mutt-References:", CASE_IGNORE);
370  if (plen)
371  {
372  /* if a mailbox is currently open, look to see if the original message
373  * the user attempted to reply to is in this mailbox */
374  p = mutt_str_skip_email_wsp(np->data + plen);
375  if (!ctx->mailbox->id_hash)
377  *cur = mutt_hash_find(ctx->mailbox->id_hash, p);
378 
379  if (*cur)
380  rc |= SEND_REPLY;
381  }
382  else if ((plen = mutt_str_startswith(np->data, "X-Mutt-Fcc:", CASE_IGNORE)))
383  {
384  p = mutt_str_skip_email_wsp(np->data + plen);
385  mutt_str_strfcpy(fcc, p, fcclen);
386  mutt_pretty_mailbox(fcc, fcclen);
387 
388  /* note that x-mutt-fcc was present. we do this because we want to add a
389  * default fcc if the header was missing, but preserve the request of the
390  * user to not make a copy if the header field is present, but empty.
391  * see http://dev.mutt.org/trac/ticket/3653 */
392  rc |= SEND_POSTPONED_FCC;
393  }
394  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
395  /* this is generated by old neomutt versions */
396  (mutt_str_startswith(np->data, "Pgp:", CASE_MATCH) ||
397  /* this is the new way */
398  mutt_str_startswith(np->data, "X-Mutt-PGP:", CASE_MATCH)))
399  {
400  hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_PGP);
401  hdr->security |= APPLICATION_PGP;
402  }
403  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
404  mutt_str_startswith(np->data, "X-Mutt-SMIME:", CASE_MATCH))
405  {
406  hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_SMIME);
407  hdr->security |= APPLICATION_SMIME;
408  }
409 
410 #ifdef MIXMASTER
411  else if (mutt_str_startswith(np->data, "X-Mutt-Mix:", CASE_MATCH))
412  {
413  mutt_list_free(&hdr->chain);
414 
415  char *t = strtok(np->data + 11, " \t\n");
416  while (t)
417  {
418  mutt_list_insert_tail(&hdr->chain, mutt_str_strdup(t));
419  t = strtok(NULL, " \t\n");
420  }
421  }
422 #endif
423 
424  else
425  {
426  // skip header removal
427  continue;
428  }
429 
430  // remove the header
431  STAILQ_REMOVE(&hdr->env->userhdrs, np, ListNode, entries);
432  FREE(&np->data);
433  FREE(&np);
434  }
435 
438 
439  return rc;
440 }
441 
449 SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
450 {
451  char smime_cryptalg[1024] = { 0 };
452  char sign_as[1024] = { 0 };
453  char *q = NULL;
454  SecurityFlags flags = SEC_NO_FLAGS;
455 
456  if (!WithCrypto)
457  return SEC_NO_FLAGS;
458 
460  for (; p[0] != '\0'; p++)
461  {
462  switch (p[0])
463  {
464  case 'c':
465  case 'C':
466  q = smime_cryptalg;
467 
468  if (p[1] == '<')
469  {
470  for (p += 2; (p[0] != '\0') && (p[0] != '>') &&
471  (q < (smime_cryptalg + sizeof(smime_cryptalg) - 1));
472  *q++ = *p++)
473  {
474  }
475 
476  if (p[0] != '>')
477  {
478  mutt_error(_("Illegal S/MIME header"));
479  return SEC_NO_FLAGS;
480  }
481  }
482 
483  *q = '\0';
484  break;
485 
486  case 'e':
487  case 'E':
488  flags |= SEC_ENCRYPT;
489  break;
490 
491  case 'i':
492  case 'I':
493  flags |= SEC_INLINE;
494  break;
495 
496  /* This used to be the micalg parameter.
497  *
498  * It's no longer needed, so we just skip the parameter in order
499  * to be able to recall old messages. */
500  case 'm':
501  case 'M':
502  if (p[1] == '<')
503  {
504  for (p += 2; (p[0] != '\0') && (p[0] != '>'); p++)
505  ;
506  if (p[0] != '>')
507  {
508  mutt_error(_("Illegal crypto header"));
509  return SEC_NO_FLAGS;
510  }
511  }
512 
513  break;
514 
515  case 'o':
516  case 'O':
517  flags |= SEC_OPPENCRYPT;
518  break;
519 
520  case 'a':
521  case 'A':
522 #ifdef USE_AUTOCRYPT
523  flags |= SEC_AUTOCRYPT;
524 #endif
525  break;
526 
527  case 'z':
528  case 'Z':
529 #ifdef USE_AUTOCRYPT
530  flags |= SEC_AUTOCRYPT_OVERRIDE;
531 #endif
532  break;
533 
534  case 's':
535  case 'S':
536  flags |= SEC_SIGN;
537  q = sign_as;
538 
539  if (p[1] == '<')
540  {
541  for (p += 2;
542  (p[0] != '\0') && (*p != '>') && (q < (sign_as + sizeof(sign_as) - 1));
543  *q++ = *p++)
544  {
545  }
546 
547  if (p[0] != '>')
548  {
549  mutt_error(_("Illegal crypto header"));
550  return SEC_NO_FLAGS;
551  }
552  }
553 
554  q[0] = '\0';
555  break;
556 
557  default:
558  mutt_error(_("Illegal crypto header"));
559  return SEC_NO_FLAGS;
560  }
561  }
562 
563  /* the cryptalg field must not be empty */
564  if (((WithCrypto & APPLICATION_SMIME) != 0) && *smime_cryptalg)
565  mutt_str_replace(&C_SmimeEncryptWith, smime_cryptalg);
566 
567  /* Set {Smime,Pgp}SignAs, if desired. */
568 
569  if (((WithCrypto & APPLICATION_PGP) != 0) && (crypt_app == APPLICATION_PGP) &&
570  (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
571  {
572  mutt_str_replace(&C_PgpSignAs, sign_as);
573  }
574 
575  if (((WithCrypto & APPLICATION_SMIME) != 0) && (crypt_app == APPLICATION_SMIME) &&
576  (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
577  {
578  mutt_str_replace(&C_SmimeSignAs, sign_as);
579  }
580 
581  return flags;
582 }
583 
596 int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new,
597  struct Email *e, bool resend)
598 {
599  struct Message *msg = NULL;
600  struct Body *b = NULL;
601  FILE *fp_body = NULL;
602  int rc = -1;
603  struct State s = { 0 };
604  SecurityFlags sec_type;
605  struct Envelope *protected_headers = NULL;
606 
607  if (!fp && !(msg = mx_msg_open(m, e->msgno)))
608  return -1;
609 
610  if (!fp)
611  fp = msg->fp;
612 
613  fp_body = fp;
614 
615  /* parse the message header and MIME structure */
616 
617  fseeko(fp, e->offset, SEEK_SET);
618  e_new->offset = e->offset;
619  /* enable header weeding for resent messages */
620  e_new->env = mutt_rfc822_read_header(fp, e_new, true, resend);
621  e_new->content->length = e->content->length;
622  mutt_parse_part(fp, e_new->content);
623 
624  /* If resending a message, don't keep message_id or mail_followup_to.
625  * Otherwise, we are resuming a postponed message, and want to keep those
626  * headers if they exist. */
627  if (resend)
628  {
629  FREE(&e_new->env->message_id);
630  FREE(&e_new->env->mail_followup_to);
631  }
632 
633  /* decrypt pgp/mime encoded messages */
634 
635  if (((WithCrypto & APPLICATION_PGP) != 0) &&
636  (sec_type = mutt_is_multipart_encrypted(e_new->content)))
637  {
638  e_new->security |= sec_type;
639  if (!crypt_valid_passphrase(sec_type))
640  goto bail;
641 
642  mutt_message(_("Decrypting message..."));
643  if ((crypt_pgp_decrypt_mime(fp, &fp_body, e_new->content, &b) == -1) || !b)
644  {
645  goto bail;
646  }
647 
648  mutt_body_free(&e_new->content);
649  e_new->content = b;
650 
651  if (b->mime_headers)
652  {
653  protected_headers = b->mime_headers;
654  b->mime_headers = NULL;
655  }
656 
658  }
659 
660  /* remove a potential multipart/signed layer - useful when
661  * resending messages */
662  if ((WithCrypto != 0) && mutt_is_multipart_signed(e_new->content))
663  {
664  e_new->security |= SEC_SIGN;
665  if (((WithCrypto & APPLICATION_PGP) != 0) &&
667  mutt_param_get(&e_new->content->parameter, "protocol"),
668  "application/pgp-signature") == 0))
669  {
670  e_new->security |= APPLICATION_PGP;
671  }
672  else if (WithCrypto & APPLICATION_SMIME)
673  e_new->security |= APPLICATION_SMIME;
674 
675  /* destroy the signature */
676  mutt_body_free(&e_new->content->parts->next);
677  e_new->content = mutt_remove_multipart(e_new->content);
678 
679  if (e_new->content->mime_headers)
680  {
681  mutt_env_free(&protected_headers);
682  protected_headers = e_new->content->mime_headers;
683  e_new->content->mime_headers = NULL;
684  }
685  }
686 
687  /* We don't need no primary multipart.
688  * Note: We _do_ preserve messages!
689  *
690  * XXX - we don't handle multipart/alternative in any
691  * smart way when sending messages. However, one may
692  * consider this a feature. */
693  if (e_new->content->type == TYPE_MULTIPART)
694  e_new->content = mutt_remove_multipart(e_new->content);
695 
696  s.fp_in = fp_body;
697 
698  struct Buffer *file = mutt_buffer_pool_get();
699 
700  /* create temporary files for all attachments */
701  for (b = e_new->content; b; b = b->next)
702  {
703  /* what follows is roughly a receive-mode variant of
704  * mutt_get_tmp_attachment () from muttlib.c */
705 
706  mutt_buffer_reset(file);
707  if (b->filename)
708  {
709  mutt_buffer_strcpy(file, b->filename);
711  }
712  else
713  {
714  /* avoid Content-Disposition: header with temporary filename */
715  b->use_disp = false;
716  }
717 
718  /* set up state flags */
719 
720  s.flags = 0;
721 
722  if (b->type == TYPE_TEXT)
723  {
724  if (mutt_str_strcasecmp("yes",
725  mutt_param_get(&b->parameter, "x-mutt-noconv")) == 0)
726  {
727  b->noconv = true;
728  }
729  else
730  {
731  s.flags |= MUTT_CHARCONV;
732  b->noconv = false;
733  }
734 
735  mutt_param_delete(&b->parameter, "x-mutt-noconv");
736  }
737 
738  mutt_adv_mktemp(file);
739  s.fp_out = mutt_file_fopen(mutt_b2s(file), "w");
740  if (!s.fp_out)
741  goto bail;
742 
743  if (((WithCrypto & APPLICATION_PGP) != 0) &&
744  ((sec_type = mutt_is_application_pgp(b)) & (SEC_ENCRYPT | SEC_SIGN)))
745  {
746  if (sec_type & SEC_ENCRYPT)
747  {
748  if (!crypt_valid_passphrase(APPLICATION_PGP))
749  goto bail;
750  mutt_message(_("Decrypting message..."));
751  }
752 
753  if (mutt_body_handler(b, &s) < 0)
754  {
755  mutt_error(_("Decryption failed"));
756  goto bail;
757  }
758 
759  if ((b == e_new->content) && !protected_headers)
760  {
761  protected_headers = b->mime_headers;
762  b->mime_headers = NULL;
763  }
764 
765  e_new->security |= sec_type;
766  b->type = TYPE_TEXT;
767  mutt_str_replace(&b->subtype, "plain");
768  mutt_param_delete(&b->parameter, "x-action");
769  }
770  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
771  ((sec_type = mutt_is_application_smime(b)) & (SEC_ENCRYPT | SEC_SIGN)))
772  {
773  if (sec_type & SEC_ENCRYPT)
774  {
775  if (!crypt_valid_passphrase(APPLICATION_SMIME))
776  goto bail;
777  crypt_smime_getkeys(e_new->env);
778  mutt_message(_("Decrypting message..."));
779  }
780 
781  if (mutt_body_handler(b, &s) < 0)
782  {
783  mutt_error(_("Decryption failed"));
784  goto bail;
785  }
786 
787  e_new->security |= sec_type;
788  b->type = TYPE_TEXT;
789  mutt_str_replace(&b->subtype, "plain");
790  }
791  else
792  mutt_decode_attachment(b, &s);
793 
794  if (mutt_file_fclose(&s.fp_out) != 0)
795  goto bail;
796 
797  mutt_str_replace(&b->filename, mutt_b2s(file));
798  b->unlink = true;
799 
801 
802  mutt_body_free(&b->parts);
803  if (b->email)
804  b->email->content = NULL; /* avoid dangling pointer */
805  }
806 
807  if (C_CryptProtectedHeadersRead && protected_headers && protected_headers->subject &&
808  (mutt_str_strcmp(e_new->env->subject, protected_headers->subject) != 0))
809  {
810  mutt_str_replace(&e_new->env->subject, protected_headers->subject);
811  }
812  mutt_env_free(&protected_headers);
813 
814  /* Fix encryption flags. */
815 
816  /* No inline if multipart. */
817  if ((WithCrypto != 0) && (e_new->security & SEC_INLINE) && e_new->content->next)
818  e_new->security &= ~SEC_INLINE;
819 
820  /* Do we even support multiple mechanisms? */
821  e_new->security &= WithCrypto | ~(APPLICATION_PGP | APPLICATION_SMIME);
822 
823  /* Theoretically, both could be set. Take the one the user wants to set by default. */
824  if ((e_new->security & APPLICATION_PGP) && (e_new->security & APPLICATION_SMIME))
825  {
826  if (C_SmimeIsDefault)
827  e_new->security &= ~APPLICATION_PGP;
828  else
829  e_new->security &= ~APPLICATION_SMIME;
830  }
831 
832  rc = 0;
833 
834 bail:
835 
836  /* that's it. */
838  if (fp_body != fp)
839  mutt_file_fclose(&fp_body);
840  if (msg)
841  mx_msg_close(m, &msg);
842 
843  if (rc == -1)
844  {
845  mutt_env_free(&e_new->env);
846  mutt_body_free(&e_new->content);
847  }
848 
849  return rc;
850 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
The "current" mailbox.
Definition: context.h:36
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1790
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1418
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Manage keymappings.
#define NONULL(x)
Definition: string2.h:37
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:400
int msg_count
Total number of messages.
Definition: mailbox.h:102
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1742
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:69
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present.
Definition: send.h:96
The envelope/body of an email.
Definition: email.h:39
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1309
static struct Email * select_msg(struct Context *ctx)
Create a Menu to select a postponed message.
Definition: postpone.c:215
GUI selectable list of items.
Definition: mutt_menu.h:82
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2425
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:107
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:558
Structs that make up an email.
String processing routines to generate the mail index.
The "currently-open" mailbox.
#define mutt_message(...)
Definition: logging.h:83
int oldcurrent
For driver use only.
Definition: mutt_menu.h:109
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:95
NeoMutt Logging.
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
struct Body * content
List of MIME parts.
Definition: email.h:92
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:379
WHERE unsigned char C_Delete
Config: Really delete messages, when the mailbox is closed.
Definition: globals.h:187
String manipulation buffer.
Definition: buffer.h:33
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:254
FILE * fp_out
File to write to.
Definition: state.h:47
Messages to be purged (bypass trash)
Definition: mutt.h:106
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
Match case when comparing strings.
Definition: string2.h:67
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
Flags to control mutt_expando_format()
All user-callable functions.
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:91
FILE * fp_in
File to read from.
Definition: state.h:46
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
The body of an email.
Definition: body.h:34
Convenience wrapper for the config headers.
static void post_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the email list - Implements Menu::menu_make_entry()
Definition: postpone.c:203
Prepare and send an email.
Hundreds of global variables to back the user variables.
Assorted sorting methods.
Some miscellaneous functions.
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:284
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1087
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:147
char * message_id
Message ID.
Definition: envelope.h:69
struct Mailbox * mailbox
Definition: context.h:50
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
API for mailboxes.
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:55
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
IMAP network mailbox.
struct Envelope * env
Envelope information.
Definition: email.h:91
Convenience wrapper for the core headers.
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Mailbox *m, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1497
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:392
struct Menu * menu
Needed for pattern compilation.
Definition: context.h:46
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:412
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:109
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:360
char * subtype
content-type subtype
Definition: body.h:37
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
#define mutt_b2s(buf)
Definition: buffer.h:41
Prototypes for many functions.
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:560
const char * line
Definition: common.c:36
void mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:280
#define REDRAW_STATUS
Redraw the status bar.
Definition: mutt_menu.h:46
A local copy of an email.
Definition: mx.h:81
Create/manipulate threading in emails.
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
WHERE char * C_IndexFormat
Config: printf-like format string for the index menu (emails)
Definition: globals.h:117
Messages to be deleted.
Definition: mutt.h:104
A mailbox.
Definition: mailbox.h:92
#define PATH_MAX
Definition: mutt.h:52
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mx.h:51
int top
Entry that is the top of the current page.
Definition: mutt_menu.h:108
Type: &#39;text/*&#39;.
Definition: mime.h:38
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:253
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:173
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
static short PostCount
Definition: postpone.c:74
GUI present the user with a selectable list.
Ignore case when comparing strings.
Definition: string2.h:68
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:776
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:619
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:54
API for encryption/signing of emails.
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:612
void mutt_update_num_postponed(void)
Force the update of the number of postponed messages.
Definition: postpone.c:195
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:281
#define SEND_REPLY
Reply to sender.
Definition: send.h:87
struct Hash * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1437
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
unsigned int type
content-type primary type
Definition: body.h:65
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:85
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
char * title
Title of this menu.
Definition: mutt_menu.h:84
Keep track when processing files.
int mutt_num_postponed(struct Mailbox *m, bool force)
Return the number of postponed messages.
Definition: postpone.c:85
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1398
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition: postpone.c:449
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1030
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:199
char * data
String.
Definition: list.h:35
char * subject
Email&#39;s subject.
Definition: envelope.h:66
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
FILE * fp
pointer to the message data
Definition: mx.h:83
void mutt_adv_mktemp(struct Buffer *buf)
Create a temporary file.
Definition: muttlib.c:90
#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)
XXX.
Definition: mx.c:1539
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
static bool UpdateNumPostponed
Definition: postpone.c:75
Mapping between user-readable string and a constant.
Definition: mapping.h:29
Keep track when processing files.
Definition: state.h:44
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1545
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:48
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Miscellaneous functions for sending an email.
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
int current
Current entry.
Definition: mutt_menu.h:87
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:139
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:168
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:172
A List node for strings.
Definition: list.h:33
Decide how to display email content.
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1128
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
#define N_(a)
Definition: message.h:32
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
Sort by the order the messages appear in the mailbox.
Definition: sort.h:55
Convenience wrapper for the library headers.
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
Select a postponed email.
Definition: keymap.h:70
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1039
Log at debug level 3.
Definition: logging.h:58
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:596
struct Hash * id_hash
Hash table by msg id.
Definition: mailbox.h:138
#define REDRAW_CURRENT
Redraw the current line of the menu.
Definition: mutt_menu.h:45
int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, char *fcc, size_t fcclen)
Recall a postponed message.
Definition: postpone.c:290
The header of an Email.
Definition: envelope.h:54
int msgno
Number displayed to the user.
Definition: email.h:88
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135