NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
recvcmd.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stdbool.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include "mutt/lib.h"
35 #include "address/lib.h"
36 #include "config/lib.h"
37 #include "email/lib.h"
38 #include "core/lib.h"
39 #include "alias/lib.h"
40 #include "gui/lib.h"
41 #include "mutt.h"
42 #include "recvcmd.h"
43 #include "send/lib.h"
44 #include "context.h"
45 #include "copy.h"
46 #include "handler.h"
47 #include "hdrline.h"
48 #include "init.h"
49 #include "mutt_body.h"
50 #include "mutt_globals.h"
51 #include "mutt_logging.h"
52 #include "muttlib.h"
53 #include "options.h"
54 #include "protos.h"
55 #include "state.h"
56 #ifdef ENABLE_NLS
57 #include <libintl.h>
58 #endif
59 
60 struct Mailbox;
61 
62 /* These Config Variables are only used in recvcmd.c */
63 unsigned char C_MimeForwardRest;
64 
74 static bool check_msg(struct Body *b, bool err)
75 {
76  if (!mutt_is_message_type(b->type, b->subtype))
77  {
78  if (err)
79  mutt_error(_("You may only bounce message/rfc822 parts"));
80  return false;
81  }
82  return true;
83 }
84 
92 static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
93 {
94  if (cur && !check_msg(cur, err))
95  return false;
96  if (!cur)
97  {
98  for (short i = 0; i < actx->idxlen; i++)
99  {
100  if (actx->idx[i]->body->tagged)
101  {
102  if (!check_msg(actx->idx[i]->body, err))
103  return false;
104  }
105  }
106  }
107  return true;
108 }
109 
116 static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
117 {
118  if (cur)
119  return mutt_can_decode(cur);
120 
121  for (short i = 0; i < actx->idxlen; i++)
122  if (actx->idx[i]->body->tagged && !mutt_can_decode(actx->idx[i]->body))
123  return false;
124 
125  return true;
126 }
127 
133 static short count_tagged(struct AttachCtx *actx)
134 {
135  short count = 0;
136  for (short i = 0; i < actx->idxlen; i++)
137  if (actx->idx[i]->body->tagged)
138  count++;
139 
140  return count;
141 }
142 
149 static short count_tagged_children(struct AttachCtx *actx, short i)
150 {
151  short level = actx->idx[i]->level;
152  short count = 0;
153 
154  while ((++i < actx->idxlen) && (level < actx->idx[i]->level))
155  if (actx->idx[i]->body->tagged)
156  count++;
157 
158  return count;
159 }
160 
168 void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
169 {
170  if (!m || !fp || !actx)
171  return;
172 
173  char prompt[256];
174  char buf[8192];
175  char *err = NULL;
176  int ret = 0;
177  int p = 0;
178 
179  if (!check_all_msg(actx, cur, true))
180  return;
181 
182  /* one or more messages? */
183  p = cur ? 1 : count_tagged(actx);
184 
185  /* RFC5322 mandates a From: header, so warn before bouncing
186  * messages without one */
187  if (cur)
188  {
189  if (TAILQ_EMPTY(&cur->email->env->from))
190  {
191  mutt_error(_("Warning: message contains no From: header"));
193  }
194  }
195  else
196  {
197  for (short i = 0; i < actx->idxlen; i++)
198  {
199  if (actx->idx[i]->body->tagged)
200  {
201  if (TAILQ_EMPTY(&actx->idx[i]->body->email->env->from))
202  {
203  mutt_error(_("Warning: message contains no From: header"));
205  break;
206  }
207  }
208  }
209  }
210 
211  if (p)
212  mutt_str_copy(prompt, _("Bounce message to: "), sizeof(prompt));
213  else
214  mutt_str_copy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
215 
216  buf[0] = '\0';
217  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS, false, NULL, NULL) ||
218  (buf[0] == '\0'))
219  {
220  return;
221  }
222 
223  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
224  mutt_addrlist_parse(&al, buf);
225  if (TAILQ_EMPTY(&al))
226  {
227  mutt_error(_("Error parsing address"));
228  return;
229  }
230 
231  mutt_expand_aliases(&al);
232 
233  if (mutt_addrlist_to_intl(&al, &err) < 0)
234  {
235  mutt_error(_("Bad IDN: '%s'"), err);
236  FREE(&err);
237  goto end;
238  }
239 
240  buf[0] = '\0';
241  mutt_addrlist_write(&al, buf, sizeof(buf), true);
242 
243 #define EXTRA_SPACE (15 + 7 + 2)
244  /* See commands.c. */
245  snprintf(prompt, sizeof(prompt) - 4,
246  ngettext("Bounce message to %s?", "Bounce messages to %s?", p), buf);
247 
249  {
250  mutt_simple_format(prompt, sizeof(prompt) - 4, 0, MessageWindow->state.cols - EXTRA_SPACE,
251  JUSTIFY_LEFT, 0, prompt, sizeof(prompt), false);
252  mutt_str_cat(prompt, sizeof(prompt), "...?");
253  }
254  else
255  mutt_str_cat(prompt, sizeof(prompt), "?");
256 
257  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
258  {
260  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
261  goto end;
262  }
263 
265 
266  if (cur)
267  ret = mutt_bounce_message(fp, m, cur->email, &al, NeoMutt->sub);
268  else
269  {
270  for (short i = 0; i < actx->idxlen; i++)
271  {
272  if (actx->idx[i]->body->tagged)
273  {
274  if (mutt_bounce_message(actx->idx[i]->fp, m, actx->idx[i]->body->email,
275  &al, NeoMutt->sub))
276  {
277  ret = 1;
278  }
279  }
280  }
281  }
282 
283  if (ret == 0)
284  mutt_message(ngettext("Message bounced", "Messages bounced", p));
285  else
286  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
287 
288 end:
289  mutt_addrlist_clear(&al);
290 }
291 
299 void mutt_attach_resend(FILE *fp, struct Context *ctx, struct AttachCtx *actx,
300  struct Body *cur)
301 {
302  if (!check_all_msg(actx, cur, true))
303  return;
304 
305  if (cur)
306  mutt_resend_message(fp, ctx, cur->email, NeoMutt->sub);
307  else
308  {
309  for (short i = 0; i < actx->idxlen; i++)
310  {
311  if (actx->idx[i]->body->tagged)
312  {
313  mutt_resend_message(actx->idx[i]->fp, ctx, actx->idx[i]->body->email,
314  NeoMutt->sub);
315  }
316  }
317  }
318 }
319 
327 static struct AttachPtr *find_common_parent(struct AttachCtx *actx, short nattach)
328 {
329  short i;
330  short nchildren;
331 
332  for (i = 0; i < actx->idxlen; i++)
333  if (actx->idx[i]->body->tagged)
334  break;
335 
336  while (--i >= 0)
337  {
338  if (mutt_is_message_type(actx->idx[i]->body->type, actx->idx[i]->body->subtype))
339  {
340  nchildren = count_tagged_children(actx, i);
341  if (nchildren == nattach)
342  return actx->idx[i];
343  }
344  }
345 
346  return NULL;
347 }
348 
361 static int is_parent(short i, struct AttachCtx *actx, struct Body *cur)
362 {
363  short level = actx->idx[i]->level;
364 
365  while ((++i < actx->idxlen) && (actx->idx[i]->level > level))
366  {
367  if (actx->idx[i]->body == cur)
368  return true;
369  }
370 
371  return false;
372 }
373 
382 static struct AttachPtr *find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
383 {
384  struct AttachPtr *parent = NULL;
385 
386  if (cur)
387  {
388  for (short i = 0; i < actx->idxlen; i++)
389  {
390  if (mutt_is_message_type(actx->idx[i]->body->type, actx->idx[i]->body->subtype) &&
391  is_parent(i, actx, cur))
392  {
393  parent = actx->idx[i];
394  }
395  if (actx->idx[i]->body == cur)
396  break;
397  }
398  }
399  else if (nattach)
400  parent = find_common_parent(actx, nattach);
401 
402  return parent;
403 }
404 
414 static void include_header(bool quote, FILE *fp_in, struct Mailbox *m,
415  struct Email *e, FILE *fp_out, char *prefix)
416 {
417  CopyHeaderFlags chflags = CH_DECODE;
418  char prefix2[128];
419 
420  if (C_Weed)
421  chflags |= CH_WEED | CH_REORDER;
422 
423  if (quote)
424  {
425  if (prefix)
426  mutt_str_copy(prefix2, prefix, sizeof(prefix2));
427  else if (!C_TextFlowed)
428  {
429  mutt_make_string(prefix2, sizeof(prefix2), 0, NONULL(C_IndentString), m,
430  -1, e, MUTT_FORMAT_NO_FLAGS, NULL);
431  }
432  else
433  mutt_str_copy(prefix2, ">", sizeof(prefix2));
434 
435  chflags |= CH_PREFIX;
436  }
437 
438  mutt_copy_header(fp_in, e, fp_out, chflags, quote ? prefix2 : NULL, 0);
439 }
440 
450 static struct Body **copy_problematic_attachments(struct Body **last,
451  struct AttachCtx *actx, bool force)
452 {
453  for (short i = 0; i < actx->idxlen; i++)
454  {
455  if (actx->idx[i]->body->tagged && (force || !mutt_can_decode(actx->idx[i]->body)))
456  {
457  if (mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->body) == -1)
458  return NULL; /* XXXXX - may lead to crashes */
459  last = &((*last)->next);
460  }
461  }
462  return last;
463 }
464 
476 static void attach_forward_bodies(FILE *fp, struct Mailbox *m, struct Email *e,
477  struct AttachCtx *actx, struct Body *cur, short nattach)
478 {
479  bool mime_fwd_all = false;
480  bool mime_fwd_any = true;
481  struct Email *e_parent = NULL;
482  FILE *fp_parent = NULL;
483  char prefix[256];
484  enum QuadOption ans = MUTT_NO;
485  struct Buffer *tmpbody = NULL;
486 
487  /* First, find the parent message.
488  * Note: This could be made an option by just
489  * putting the following lines into an if block. */
490  struct AttachPtr *parent = find_parent(actx, cur, nattach);
491  if (parent)
492  {
493  e_parent = parent->body->email;
494  fp_parent = parent->fp;
495  }
496  else
497  {
498  e_parent = e;
499  fp_parent = actx->fp_root;
500  }
501 
502  struct Email *e_tmp = email_new();
503  e_tmp->env = mutt_env_new();
504  mutt_make_forward_subject(e_tmp->env, m, e_parent, NeoMutt->sub);
505 
506  tmpbody = mutt_buffer_pool_get();
507  mutt_buffer_mktemp(tmpbody);
508  FILE *fp_tmp = mutt_file_fopen(mutt_buffer_string(tmpbody), "w");
509  if (!fp_tmp)
510  {
511  mutt_error(_("Can't open temporary file %s"), mutt_buffer_string(tmpbody));
512  email_free(&e_tmp);
513  goto bail;
514  }
515 
516  mutt_forward_intro(m, e_parent, fp_tmp, NeoMutt->sub);
517 
518  /* prepare the prefix here since we'll need it later. */
519 
520  if (C_ForwardQuote)
521  {
522  if (C_TextFlowed)
523  mutt_str_copy(prefix, ">", sizeof(prefix));
524  else
525  {
526  mutt_make_string(prefix, sizeof(prefix), 0, NONULL(C_IndentString), m, -1,
527  e_parent, MUTT_FORMAT_NO_FLAGS, NULL);
528  }
529  }
530 
531  include_header(C_ForwardQuote, fp_parent, m, e_parent, fp_tmp, prefix);
532 
533  /* Now, we have prepared the first part of the message body: The
534  * original message's header.
535  *
536  * The next part is more interesting: either include the message bodies,
537  * or attach them. */
538  if ((!cur || mutt_can_decode(cur)) &&
539  ((ans = query_quadoption(C_MimeForward, _("Forward as attachments?"))) == MUTT_YES))
540  {
541  mime_fwd_all = true;
542  }
543  else if (ans == MUTT_ABORT)
544  {
545  goto bail;
546  }
547 
548  /* shortcut MIMEFWDREST when there is only one attachment.
549  * Is this intuitive? */
550  if (!mime_fwd_all && !cur && (nattach > 1) && !check_can_decode(actx, cur))
551  {
552  ans = query_quadoption(
554  _("Can't decode all tagged attachments. MIME-forward the others?"));
555  if (ans == MUTT_ABORT)
556  goto bail;
557  else if (ans == MUTT_NO)
558  mime_fwd_any = false;
559  }
560 
561  /* initialize a state structure */
562 
563  struct State st = { 0 };
564  if (C_ForwardQuote)
565  st.prefix = prefix;
566  st.flags = MUTT_CHARCONV;
567  if (C_Weed)
568  st.flags |= MUTT_WEED;
569  st.fp_out = fp_tmp;
570 
571  /* where do we append new MIME parts? */
572  struct Body **last = &e_tmp->body;
573 
574  if (cur)
575  {
576  /* single body case */
577 
578  if (!mime_fwd_all && mutt_can_decode(cur))
579  {
580  st.fp_in = fp;
581  mutt_body_handler(cur, &st);
582  state_putc(&st, '\n');
583  }
584  else
585  {
586  if (mutt_body_copy(fp, last, cur) == -1)
587  goto bail;
588  }
589  }
590  else
591  {
592  /* multiple body case */
593 
594  if (!mime_fwd_all)
595  {
596  for (int i = 0; i < actx->idxlen; i++)
597  {
598  if (actx->idx[i]->body->tagged && mutt_can_decode(actx->idx[i]->body))
599  {
600  st.fp_in = actx->idx[i]->fp;
601  mutt_body_handler(actx->idx[i]->body, &st);
602  state_putc(&st, '\n');
603  }
604  }
605  }
606 
607  if (mime_fwd_any && !copy_problematic_attachments(last, actx, mime_fwd_all))
608  goto bail;
609  }
610 
611  mutt_forward_trailer(m, e_parent, fp_tmp, NeoMutt->sub);
612 
613  mutt_file_fclose(&fp_tmp);
614  fp_tmp = NULL;
615 
616  /* now that we have the template, send it. */
617  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
618  emaillist_add_email(&el, e_parent);
619  mutt_send_message(SEND_NO_FLAGS, e_tmp, mutt_buffer_string(tmpbody), NULL,
620  &el, NeoMutt->sub);
621  emaillist_clear(&el);
622  mutt_buffer_pool_release(&tmpbody);
623  return;
624 
625 bail:
626  if (fp_tmp)
627  {
628  mutt_file_fclose(&fp_tmp);
630  }
631  mutt_buffer_pool_release(&tmpbody);
632 
633  email_free(&e_tmp);
634 }
635 
651 static void attach_forward_msgs(FILE *fp, struct Mailbox *m, struct AttachCtx *actx,
652  struct Body *cur, SendFlags flags)
653 {
654  struct Email *e_cur = NULL;
655  struct Email *e_tmp = NULL;
656  enum QuadOption ans;
657  struct Body **last = NULL;
658  struct Buffer *tmpbody = NULL;
659  FILE *fp_tmp = NULL;
660 
661  CopyHeaderFlags chflags = CH_XMIT;
662 
663  if (cur)
664  e_cur = cur->email;
665  else
666  {
667  for (short i = 0; i < actx->idxlen; i++)
668  {
669  if (actx->idx[i]->body->tagged)
670  {
671  e_cur = actx->idx[i]->body->email;
672  break;
673  }
674  }
675  }
676 
677  e_tmp = email_new();
678  e_tmp->env = mutt_env_new();
679  mutt_make_forward_subject(e_tmp->env, m, e_cur, NeoMutt->sub);
680 
681  tmpbody = mutt_buffer_pool_get();
682 
683  ans = query_quadoption(C_MimeForward, _("Forward MIME encapsulated?"));
684  if (ans == MUTT_NO)
685  {
686  /* no MIME encapsulation */
687 
688  mutt_buffer_mktemp(tmpbody);
689  fp_tmp = mutt_file_fopen(mutt_buffer_string(tmpbody), "w");
690  if (!fp_tmp)
691  {
692  mutt_error(_("Can't create %s"), mutt_buffer_string(tmpbody));
693  goto cleanup;
694  }
695 
697  if (C_ForwardQuote)
698  {
699  chflags |= CH_PREFIX;
700  cmflags |= MUTT_CM_PREFIX;
701  }
702 
703  if (C_ForwardDecode)
704  {
705  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
706  if (C_Weed)
707  {
708  chflags |= CH_WEED | CH_REORDER;
709  cmflags |= MUTT_CM_WEED;
710  }
711  }
712 
713  if (cur)
714  {
715  mutt_forward_intro(m, cur->email, fp_tmp, NeoMutt->sub);
716  mutt_copy_message_fp(fp_tmp, fp, cur->email, cmflags, chflags, 0);
717  mutt_forward_trailer(m, cur->email, fp_tmp, NeoMutt->sub);
718  }
719  else
720  {
721  for (short i = 0; i < actx->idxlen; i++)
722  {
723  if (actx->idx[i]->body->tagged)
724  {
725  mutt_forward_intro(m, actx->idx[i]->body->email, fp_tmp, NeoMutt->sub);
726  mutt_copy_message_fp(fp_tmp, actx->idx[i]->fp,
727  actx->idx[i]->body->email, cmflags, chflags, 0);
728  mutt_forward_trailer(m, actx->idx[i]->body->email, fp_tmp, NeoMutt->sub);
729  }
730  }
731  }
732  mutt_file_fclose(&fp_tmp);
733  }
734  else if (ans == MUTT_YES) /* do MIME encapsulation - we don't need to do much here */
735  {
736  last = &e_tmp->body;
737  if (cur)
738  mutt_body_copy(fp, last, cur);
739  else
740  {
741  for (short i = 0; i < actx->idxlen; i++)
742  {
743  if (actx->idx[i]->body->tagged)
744  {
745  mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->body);
746  last = &((*last)->next);
747  }
748  }
749  }
750  }
751  else
752  email_free(&e_tmp);
753 
754  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
755  emaillist_add_email(&el, e_cur);
756  mutt_send_message(flags, e_tmp,
757  mutt_buffer_is_empty(tmpbody) ? NULL : mutt_buffer_string(tmpbody),
758  NULL, &el, NeoMutt->sub);
759  emaillist_clear(&el);
760  e_tmp = NULL; /* mutt_send_message frees this */
761 
762 cleanup:
763  email_free(&e_tmp);
764  mutt_buffer_pool_release(&tmpbody);
765 }
766 
776 void mutt_attach_forward(FILE *fp, struct Mailbox *m, struct Email *e,
777  struct AttachCtx *actx, struct Body *cur, SendFlags flags)
778 {
779  if (check_all_msg(actx, cur, false))
780  attach_forward_msgs(fp, m, actx, cur, flags);
781  else
782  {
783  const short nattach = count_tagged(actx);
784  attach_forward_bodies(fp, m, e, actx, cur, nattach);
785  }
786 }
787 
807 static int attach_reply_envelope_defaults(struct Envelope *env, struct AttachCtx *actx,
808  struct Email *parent, SendFlags flags)
809 {
810  struct Envelope *curenv = NULL;
811  struct Email *e = NULL;
812 
813  if (!parent)
814  {
815  for (short i = 0; i < actx->idxlen; i++)
816  {
817  if (actx->idx[i]->body->tagged)
818  {
819  e = actx->idx[i]->body->email;
820  curenv = e->env;
821  break;
822  }
823  }
824  }
825  else
826  {
827  curenv = parent->env;
828  e = parent;
829  }
830 
831  if (!curenv || !e)
832  {
833  mutt_error(_("Can't find any tagged messages"));
834  return -1;
835  }
836 
837 #ifdef USE_NNTP
838  if ((flags & SEND_NEWS))
839  {
840  /* in case followup set Newsgroups: with Followup-To: if it present */
841  if (!env->newsgroups && curenv && !mutt_istr_equal(curenv->followup_to, "poster"))
842  {
844  }
845  }
846  else
847 #endif
848  {
849  if (parent)
850  {
851  if (mutt_fetch_recips(env, curenv, flags, NeoMutt->sub) == -1)
852  return -1;
853  }
854  else
855  {
856  for (short i = 0; i < actx->idxlen; i++)
857  {
858  if (actx->idx[i]->body->tagged &&
859  (mutt_fetch_recips(env, actx->idx[i]->body->email->env, flags,
860  NeoMutt->sub) == -1))
861  {
862  return -1;
863  }
864  }
865  }
866 
867  if ((flags & SEND_LIST_REPLY) && TAILQ_EMPTY(&env->to))
868  {
869  mutt_error(_("No mailing lists found"));
870  return -1;
871  }
872 
874  }
876 
877  if (parent)
879  else
880  {
881  for (short i = 0; i < actx->idxlen; i++)
882  {
883  if (actx->idx[i]->body->tagged)
884  {
886  NeoMutt->sub);
887  }
888  }
889  }
890 
891  return 0;
892 }
893 
901 static void attach_include_reply(FILE *fp, FILE *fp_tmp, struct Mailbox *m, struct Email *e)
902 {
904  CopyHeaderFlags chflags = CH_DECODE;
905 
906  mutt_make_attribution(m, e, fp_tmp, NeoMutt->sub);
907 
908  if (!C_Header)
909  cmflags |= MUTT_CM_NOHEADER;
910  if (C_Weed)
911  {
912  chflags |= CH_WEED;
913  cmflags |= MUTT_CM_WEED;
914  }
915 
916  mutt_copy_message_fp(fp_tmp, fp, e, cmflags, chflags, 0);
917  mutt_make_post_indent(m, e, fp_tmp, NeoMutt->sub);
918 }
919 
929 void mutt_attach_reply(FILE *fp, struct Mailbox *m, struct Email *e,
930  struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
931 {
932  bool mime_reply_any = false;
933 
934  short nattach = 0;
935  struct AttachPtr *parent = NULL;
936  struct Email *e_parent = NULL;
937  FILE *fp_parent = NULL;
938  struct Email *e_tmp = NULL;
939  FILE *fp_tmp = NULL;
940  struct Buffer *tmpbody = NULL;
941  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
942 
943  char prefix[128];
944 
945 #ifdef USE_NNTP
946  if (flags & SEND_NEWS)
947  OptNewsSend = true;
948  else
949  OptNewsSend = false;
950 #endif
951 
952  if (!check_all_msg(actx, e_cur, false))
953  {
954  nattach = count_tagged(actx);
955  parent = find_parent(actx, e_cur, nattach);
956  if (parent)
957  {
958  e_parent = parent->body->email;
959  fp_parent = parent->fp;
960  }
961  else
962  {
963  e_parent = e;
964  fp_parent = actx->fp_root;
965  }
966  }
967 
968  if ((nattach > 1) && !check_can_decode(actx, e_cur))
969  {
970  const enum QuadOption ans = query_quadoption(
971  C_MimeForwardRest, _("Can't decode all tagged attachments. "
972  "MIME-encapsulate the others?"));
973  if (ans == MUTT_ABORT)
974  return;
975  if (ans == MUTT_YES)
976  mime_reply_any = true;
977  }
978  else if (nattach == 1)
979  mime_reply_any = true;
980 
981  e_tmp = email_new();
982  e_tmp->env = mutt_env_new();
983 
985  e_tmp->env, actx, e_parent ? e_parent : (e_cur ? e_cur->email : NULL), flags) == -1)
986  {
987  goto cleanup;
988  }
989 
990  tmpbody = mutt_buffer_pool_get();
991  mutt_buffer_mktemp(tmpbody);
992  fp_tmp = mutt_file_fopen(mutt_buffer_string(tmpbody), "w");
993  if (!fp_tmp)
994  {
995  mutt_error(_("Can't create %s"), mutt_buffer_string(tmpbody));
996  goto cleanup;
997  }
998 
999  if (!e_parent)
1000  {
1001  if (e_cur)
1002  attach_include_reply(fp, fp_tmp, m, e_cur->email);
1003  else
1004  {
1005  for (short i = 0; i < actx->idxlen; i++)
1006  {
1007  if (actx->idx[i]->body->tagged)
1008  attach_include_reply(actx->idx[i]->fp, fp_tmp, m, actx->idx[i]->body->email);
1009  }
1010  }
1011  }
1012  else
1013  {
1014  mutt_make_attribution(m, e_parent, fp_tmp, NeoMutt->sub);
1015 
1016  struct State st;
1017  memset(&st, 0, sizeof(struct State));
1018  st.fp_out = fp_tmp;
1019 
1020  if (C_TextFlowed)
1021  {
1022  mutt_str_copy(prefix, ">", sizeof(prefix));
1023  }
1024  else
1025  {
1026  mutt_make_string(prefix, sizeof(prefix), 0, NONULL(C_IndentString), m, -1,
1027  e_parent, MUTT_FORMAT_NO_FLAGS, NULL);
1028  }
1029 
1030  st.prefix = prefix;
1031  st.flags = MUTT_CHARCONV;
1032 
1033  if (C_Weed)
1034  st.flags |= MUTT_WEED;
1035 
1036  if (C_Header)
1037  include_header(true, fp_parent, m, e_parent, fp_tmp, prefix);
1038 
1039  if (e_cur)
1040  {
1041  if (mutt_can_decode(e_cur))
1042  {
1043  st.fp_in = fp;
1044  mutt_body_handler(e_cur, &st);
1045  state_putc(&st, '\n');
1046  }
1047  else
1048  mutt_body_copy(fp, &e_tmp->body, e_cur);
1049  }
1050  else
1051  {
1052  for (short i = 0; i < actx->idxlen; i++)
1053  {
1054  if (actx->idx[i]->body->tagged && mutt_can_decode(actx->idx[i]->body))
1055  {
1056  st.fp_in = actx->idx[i]->fp;
1057  mutt_body_handler(actx->idx[i]->body, &st);
1058  state_putc(&st, '\n');
1059  }
1060  }
1061  }
1062 
1063  mutt_make_post_indent(m, e_parent, fp_tmp, NeoMutt->sub);
1064 
1065  if (mime_reply_any && !e_cur && !copy_problematic_attachments(&e_tmp->body, actx, false))
1066  {
1067  goto cleanup;
1068  }
1069  }
1070 
1071  mutt_file_fclose(&fp_tmp);
1072 
1073  emaillist_add_email(&el, e_parent ? e_parent : (e_cur ? e_cur->email : NULL));
1074  if (mutt_send_message(flags, e_tmp, mutt_buffer_string(tmpbody), NULL, &el,
1075  NeoMutt->sub) == 0)
1076  {
1077  mutt_set_flag(m, e, MUTT_REPLIED, true);
1078  }
1079  e_tmp = NULL; /* mutt_send_message frees this */
1080 
1081 cleanup:
1082  if (fp_tmp)
1083  {
1084  mutt_file_fclose(&fp_tmp);
1086  }
1087  mutt_buffer_pool_release(&tmpbody);
1088  email_free(&e_tmp);
1089  emaillist_clear(&el);
1090 }
1091 
1099 void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx,
1100  struct Body *cur)
1101 {
1102  if (!check_all_msg(actx, cur, 0))
1103  {
1104  /* L10N: You will see this error message if you invoke <compose-to-sender>
1105  when you are on a normal attachment. */
1106  mutt_error(_("You may only compose to sender with message/rfc822 parts"));
1107  return;
1108  }
1109 
1110  struct Email *e_tmp = email_new();
1111  e_tmp->env = mutt_env_new();
1112 
1113  if (cur)
1114  {
1115  if (mutt_fetch_recips(e_tmp->env, cur->email->env, SEND_TO_SENDER, NeoMutt->sub) == -1)
1116  {
1117  email_free(&e_tmp);
1118  return;
1119  }
1120  }
1121  else
1122  {
1123  for (int i = 0; i < actx->idxlen; i++)
1124  {
1125  if (actx->idx[i]->body->tagged &&
1126  (mutt_fetch_recips(e_tmp->env, actx->idx[i]->body->email->env,
1127  SEND_TO_SENDER, NeoMutt->sub) == -1))
1128  {
1129  email_free(&e_tmp);
1130  return;
1131  }
1132  }
1133  }
1134 
1135  // This call will free e_tmp for us
1136  mutt_send_message(SEND_NO_FLAGS, e_tmp, NULL, NULL, NULL, NeoMutt->sub);
1137 }
lib.h
Envelope
The header of an Email.
Definition: envelope.h:54
CopyHeaderFlags
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
SendFlags
uint16_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
Definition: send.h:37
AttachCtx
A set of attachments.
Definition: attach.h:49
C_Header
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: mutt_globals.h:149
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
AttachCtx::fp_root
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
C_MimeForward
WHERE unsigned char C_MimeForward
Config: Forward a message as a 'message/RFC822' MIME part.
Definition: mutt_globals.h:127
Envelope::followup_to
char * followup_to
List of 'followup-to' fields.
Definition: envelope.h:77
State::fp_in
FILE * fp_in
File to read from.
Definition: state.h:46
CH_REORDER
#define CH_REORDER
Re-order output of headers (specified by 'hdr_order')
Definition: copy.h:58
MessageWindow
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
MUTT_CM_CHARCONV
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
Mailbox
A mailbox.
Definition: mailbox.h:81
include_header
static void include_header(bool quote, FILE *fp_in, struct Mailbox *m, struct Email *e, FILE *fp_out, char *prefix)
Write an email header to a file, optionally quoting it.
Definition: recvcmd.c:414
mutt_make_string
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1427
C_TextFlowed
WHERE bool C_TextFlowed
Config: Generate 'format=flowed' messages.
Definition: mutt_globals.h:166
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_addrlist_to_intl
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
Body
The body of an email.
Definition: body.h:34
AttachPtr::fp
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
MUTT_CM_NOHEADER
#define MUTT_CM_NOHEADER
Don't copy the message header.
Definition: copy.h:35
mutt_add_to_reference_headers
void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv, struct ConfigSubset *sub)
Generate references for a reply email.
Definition: send.c:965
mutt_window_clearline
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
mutt_addrlist_write
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
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
handler.h
AttachPtr
An email to which things will be attached.
Definition: attach.h:34
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
CH_WEED
#define CH_WEED
Weed the headers?
Definition: copy.h:52
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
mutt_expand_aliases
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_globals.h
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
mutt_file_unlink
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
mutt_strwidth
int mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:1363
copy_problematic_attachments
static struct Body ** copy_problematic_attachments(struct Body **last, struct AttachCtx *actx, bool force)
Attach the body parts which can't be decoded.
Definition: recvcmd.c:450
FREE
#define FREE(x)
Definition: memory.h:40
options.h
mutt_make_attribution
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out, struct ConfigSubset *sub)
Add "on DATE, PERSON wrote" header.
Definition: send.c:593
state_putc
#define state_putc(STATE, STR)
Definition: state.h:56
mutt_addrlist_parse
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
MUTT_ABORT
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:38
copy.h
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
MUTT_FORMAT_NO_FLAGS
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
Body::tagged
bool tagged
This attachment is tagged.
Definition: body.h:70
mutt_make_post_indent
void mutt_make_post_indent(struct Mailbox *m, struct Email *e, FILE *fp_out, struct ConfigSubset *sub)
Add suffix to replied email text.
Definition: send.c:618
email_new
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
mutt_attach_mail_sender
void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur)
Compose an email to the sender in the email attachment.
Definition: recvcmd.c:1099
State::fp_out
FILE * fp_out
File to write to.
Definition: state.h:47
mutt_bounce_message
int mutt_bounce_message(FILE *fp, struct Mailbox *m, struct Email *e, struct AddressList *to, struct ConfigSubset *sub)
Bounce an email message.
Definition: sendlib.c:1374
C_ForwardQuote
WHERE bool C_ForwardQuote
Config: Automatically quote a forwarded message using $indent_string
Definition: mutt_globals.h:148
State::prefix
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_copy_message_fp
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
make a copy of a message from a FILE pointer
Definition: copy.c:616
mutt_attach_forward
void mutt_attach_forward(FILE *fp, struct Mailbox *m, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
Definition: recvcmd.c:776
EXTRA_SPACE
#define EXTRA_SPACE
MUTT_ALIAS
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
lib.h
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
SEND_NEWS
#define SEND_NEWS
Reply to a news article.
Definition: send.h:54
attach_forward_msgs
static void attach_forward_msgs(FILE *fp, struct Mailbox *m, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward one or several message-type attachments.
Definition: recvcmd.c:651
protos.h
MUTT_CM_WEED
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
mutt_resend_message
int mutt_resend_message(FILE *fp, struct Context *ctx, struct Email *e_cur, struct ConfigSubset *sub)
Resend an email.
Definition: send.c:1521
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
attach_include_reply
static void attach_include_reply(FILE *fp, FILE *fp_tmp, struct Mailbox *m, struct Email *e)
This is very similar to send.c's include_reply()
Definition: recvcmd.c:901
JUSTIFY_LEFT
@ JUSTIFY_LEFT
Left justify the text.
Definition: curs_lib.h:48
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_can_decode
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1805
CH_DECODE
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
init.h
SEND_TO_SENDER
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:52
C_MimeForwardRest
unsigned char C_MimeForwardRest
Config: Forward all attachments, even if they can't be decoded.
Definition: recvcmd.c:60
MUTT_CHARCONV
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
lib.h
muttlib.h
C_Bounce
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: mutt_globals.h:124
mutt_simple_format
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:1097
AttachPtr::level
int level
Nesting depth of attachment.
Definition: attach.h:40
MUTT_CM_NO_FLAGS
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
lib.h
lib.h
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
count_tagged
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:133
mutt_send_message
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el, struct ConfigSubset *sub)
Send an email.
Definition: send.c:2012
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
C_ForwardDecode
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: mutt_globals.h:147
mutt_is_message_type
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1368
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
AttachPtr::body
struct Body * body
Attachment.
Definition: attach.h:36
emaillist_add_email
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:151
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_body.h
mutt_copy_header
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy Email header.
Definition: copy.c:405
MUTT_REPLIED
@ MUTT_REPLIED
Messages that have been replied to.
Definition: mutt.h:95
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
mutt_make_forward_subject
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *e, struct ConfigSubset *sub)
Create a subject for a forwarded email.
Definition: send.c:917
attach_reply_envelope_defaults
static int attach_reply_envelope_defaults(struct Envelope *env, struct AttachCtx *actx, struct Email *parent, SendFlags flags)
Create the envelope defaults for a reply.
Definition: recvcmd.c:807
SEND_NO_FLAGS
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:40
check_msg
static bool check_msg(struct Body *b, bool err)
Are we working with an RFC822 message.
Definition: recvcmd.c:74
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
recvcmd.h
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
mutt_forward_trailer
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp, struct ConfigSubset *sub)
Add a "end of forwarded message" text.
Definition: send.c:437
mutt_logging.h
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
Envelope::newsgroups
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
lib.h
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
check_all_msg
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
CH_PREFIX
#define CH_PREFIX
Quote header using $indent_string string?
Definition: copy.h:56
C_Weed
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: globals.c:40
lib.h
mutt_str_cat
char * mutt_str_cat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:385
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
State
Keep track when processing files.
Definition: state.h:44
mutt_attach_resend
void mutt_attach_resend(FILE *fp, struct Context *ctx, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:299
mutt_make_misc_reply_headers
void mutt_make_misc_reply_headers(struct Envelope *env, struct Envelope *curenv, struct ConfigSubset *sub)
Set subject for a reply.
Definition: send.c:938
mutt_forward_intro
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp, struct ConfigSubset *sub)
Add the "start of forwarded message" text.
Definition: send.c:411
MUTT_WEED
#define MUTT_WEED
Weed headers even when not in display mode.
Definition: state.h:35
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
is_parent
static int is_parent(short i, struct AttachCtx *actx, struct Body *cur)
Check whether one attachment is the parent of another.
Definition: recvcmd.c:361
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
mutt_body_handler
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1595
check_can_decode
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:116
context.h
AttachCtx::idx
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
mutt_body_copy
int mutt_body_copy(FILE *fp, struct Body **tgt, struct Body *src)
Create a send-mode duplicate from a receive-mode body.
Definition: mutt_body.c:48
MUTT_CM_DECODE
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
email_free
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
C_IndentString
WHERE char * C_IndentString
Config: String used to indent 'reply' text.
Definition: mutt_globals.h:102
SEND_LIST_REPLY
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:43
OptNewsSend
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:46
mutt_get_field
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:311
Body::email
struct Email * email
header information for message/rfc822
Definition: body.h:55
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
mutt_attach_reply
void mutt_attach_reply(FILE *fp, struct Mailbox *m, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:929
state.h
State::flags
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
mutt_attach_bounce
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:168
Email
The envelope/body of an email.
Definition: email.h:37
MUTT_CM_PREFIX
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
lib.h
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_set_flag
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:67
emaillist_clear
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:130
count_tagged_children
static short count_tagged_children(struct AttachCtx *actx, short i)
tagged children below a multipart/message attachment
Definition: recvcmd.c:149
attach_forward_bodies
static void attach_forward_bodies(FILE *fp, struct Mailbox *m, struct Email *e, struct AttachCtx *actx, struct Body *cur, short nattach)
forward one or several MIME bodies
Definition: recvcmd.c:476
mutt_fetch_recips
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags, struct ConfigSubset *sub)
Generate recpients for a reply email.
Definition: send.c:799
mutt_fix_reply_recipients
void mutt_fix_reply_recipients(struct Envelope *env, struct ConfigSubset *sub)
Remove duplicate recipients.
Definition: send.c:886
hdrline.h
AttachCtx::idxlen
short idxlen
Number of attachmentes.
Definition: attach.h:55
find_parent
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:382
find_common_parent
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
find a common parent message for the tagged attachments
Definition: recvcmd.c:327
CH_XMIT
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
idx
size_t idx
Definition: mailbox.c:234
mutt_error
#define mutt_error(...)
Definition: logging.h:84
CopyMessageFlags
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
mutt_str_copy
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