Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 921 lines (758 sloc) 19.852 kB
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
1 /*
82cb256 @bcully Update copyrights. Closes #3016.
bcully authored
2 * Copyright (C) 1999-2004 Thomas Roessler <roessler@does-not-exist.org>
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
3 *
4 * This program is free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later
8 * version.
9 *
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
4ebd1cc @bcully Update FSF address (via sed, I hope nothing got mangled). Closes: #2071.
bcully authored
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
62255b8 @bcully Gah, forgot the zip code when updating the FSF address...
bcully authored
19 * Boston, MA 02110-1301, USA.
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
20 */
21
bd77e36 @bcully Add config.h to the top of every C file that could possibly want it.
bcully authored
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
26 #include "mutt.h"
27 #include "mutt_curses.h"
28 #include "mutt_menu.h"
29 #include "attach.h"
30 #include "mapping.h"
31 #include "copy.h"
17c0940 IDN support for e-mail messages. Things should work automagically
Thomas Roessler authored
32 #include "mutt_idna.h"
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
33
34 /* some helper functions to verify that we are exclusively operating
35 * on message/rfc822 attachments
36 */
37
38 static short check_msg (BODY * b, short err)
39 {
40 if (!mutt_is_message_type (b->type, b->subtype))
41 {
42 if (err)
43 mutt_error _("You may only bounce message/rfc822 parts.");
44 return -1;
45 }
46 return 0;
47 }
48
49 static short check_all_msg (ATTACHPTR ** idx, short idxlen,
50 BODY * cur, short err)
51 {
52 short i;
53
54 if (cur && check_msg (cur, err) == -1)
55 return -1;
56 else if (!cur)
57 {
58 for (i = 0; i < idxlen; i++)
59 {
60 if (idx[i]->content->tagged)
61 {
62 if (check_msg (idx[i]->content, err) == -1)
63 return -1;
64 }
65 }
66 }
67 return 0;
68 }
69
70
71 /* can we decode all tagged attachments? */
72
73 static short check_can_decode (ATTACHPTR ** idx, short idxlen,
74 BODY * cur)
75 {
76 short i;
77
78 if (cur)
79 return mutt_can_decode (cur);
80
81 for (i = 0; i < idxlen; i++)
82 if (idx[i]->content->tagged && !mutt_can_decode (idx[i]->content))
83 return 0;
84
85 return 1;
86 }
87
88 static short count_tagged (ATTACHPTR **idx, short idxlen)
89 {
90 short count = 0;
91 short i;
92
93 for (i = 0; i < idxlen; i++)
94 if (idx[i]->content->tagged)
95 count++;
96
97 return count;
98 }
99
100 /* count the number of tagged children below a multipart or message
101 * attachment.
102 */
103
104 static short count_tagged_children (ATTACHPTR ** idx,
105 short idxlen, short i)
106 {
107 short level = idx[i]->level;
108 short count = 0;
109
110 while ((++i < idxlen) && (level < idx[i]->level))
111 if (idx[i]->content->tagged)
112 count++;
113
114 return count;
115 }
116
117
118
119 /**
120 **
121 ** The bounce function, from the attachment menu
122 **
123 **/
124
125 void mutt_attach_bounce (FILE * fp, HEADER * hdr,
126 ATTACHPTR ** idx, short idxlen, BODY * cur)
127 {
128 short i;
129 char prompt[STRING];
130 char buf[HUGE_STRING];
17c0940 IDN support for e-mail messages. Things should work automagically
Thomas Roessler authored
131 char *err = NULL;
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
132 ADDRESS *adr = NULL;
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
133 int ret = 0;
134 int p = 0;
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
135
136 if (check_all_msg (idx, idxlen, cur, 1) == -1)
137 return;
138
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
139 /* one or more messages? */
140 p = (cur || count_tagged (idx, idxlen) == 1);
141
142 if (p)
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
143 strfcpy (prompt, _("Bounce message to: "), sizeof (prompt));
144 else
145 strfcpy (prompt, _("Bounce tagged messages to: "), sizeof (prompt));
146
147 buf[0] = '\0';
148 if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS)
149 || buf[0] == '\0')
150 return;
151
3d0554c Fix some (too lazy and tired to do all) of the inconsistencies
Thomas Roessler authored
152 if (!(adr = rfc822_parse_adrlist (adr, buf)))
153 {
154 mutt_error _("Error parsing address!");
155 return;
156 }
157
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
158 adr = mutt_expand_aliases (adr);
17c0940 IDN support for e-mail messages. Things should work automagically
Thomas Roessler authored
159
160 if (mutt_addrlist_to_idna (adr, &err) < 0)
161 {
162 mutt_error (_("Bad IDN: '%s'"), err);
163 FREE (&err);
164 rfc822_free_address (&adr);
165 return;
166 }
167
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
168 buf[0] = 0;
17c0940 IDN support for e-mail messages. Things should work automagically
Thomas Roessler authored
169 rfc822_write_address (buf, sizeof (buf), adr, 1);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
170
3d0554c Fix some (too lazy and tired to do all) of the inconsistencies
Thomas Roessler authored
171 #define extra_space (15+7+2)
172 /*
173 * See commands.c.
174 */
175 snprintf (prompt, sizeof (prompt) - 4,
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
176 (p ? _("Bounce message to %s") : _("Bounce messages to %s")), buf);
177
178 if (mutt_strwidth (prompt) > COLS - extra_space)
179 {
180 mutt_format_string (prompt, sizeof (prompt) - 4,
2adb5af @xdgc This patch implements the "%* " notation, which is analogous to "%> "
xdgc authored
181 0, COLS-extra_space, FMT_LEFT, 0,
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
182 prompt, sizeof (prompt), 0);
1886722 safe_strcat, safe_strncat. Thanks to Ulf H. for noting the wrong
Thomas Roessler authored
183 safe_strcat (prompt, sizeof (prompt), "...?");
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
184 }
185 else
1886722 safe_strcat, safe_strncat. Thanks to Ulf H. for noting the wrong
Thomas Roessler authored
186 safe_strcat (prompt, sizeof (prompt), "?");
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
187
5885405 Fix #1531. (recvcmd.c duplicate of #1528)
Zardoz@users.sourceforge.net authored
188 if (query_quadoption (OPT_BOUNCE, prompt) != M_YES)
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
189 {
190 rfc822_free_address (&adr);
191 CLEARLINE (LINES - 1);
192 mutt_message (p ? _("Message not bounced.") : _("Messages not bounced."));
193 return;
194 }
195
196 CLEARLINE (LINES - 1);
197
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
198 if (cur)
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
199 ret = mutt_bounce_message (fp, cur->hdr, adr);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
200 else
201 {
202 for (i = 0; i < idxlen; i++)
203 {
204 if (idx[i]->content->tagged)
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
205 if (mutt_bounce_message (fp, idx[i]->content->hdr, adr))
206 ret = 1;
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
207 }
208 }
209
4e135aa Introduce a new option named $bounce, and fix some inconsistencies
Thomas Roessler authored
210 if (!ret)
211 mutt_message (p ? _("Message bounced.") : _("Messages bounced."));
212 else
213 mutt_error (p ? _("Error bouncing message!") : _("Error bouncing messages!"));
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
214 }
215
216
217
218 /**
219 **
220 ** resend-message, from the attachment menu
221 **
222 **
223 **/
224
225 void mutt_attach_resend (FILE * fp, HEADER * hdr, ATTACHPTR ** idx,
226 short idxlen, BODY * cur)
227 {
228 short i;
229
230 if (check_all_msg (idx, idxlen, cur, 1) == -1)
231 return;
232
233 if (cur)
234 mutt_resend_message (fp, Context, cur->hdr);
235 else
236 {
237 for (i = 0; i < idxlen; i++)
238 if (idx[i]->content->tagged)
239 mutt_resend_message (fp, Context, idx[i]->content->hdr);
240 }
241 }
242
243
244 /**
245 **
246 ** forward-message, from the attachment menu
247 **
248 **/
249
250 /* try to find a common parent message for the tagged attachments. */
251
252 static HEADER *find_common_parent (ATTACHPTR ** idx, short idxlen,
253 short nattach)
254 {
255 short i;
256 short nchildren;
257
258 for (i = 0; i < idxlen; i++)
259 if (idx[i]->content->tagged)
260 break;
261
262 while (--i >= 0)
263 {
264 if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype))
265 {
266 nchildren = count_tagged_children (idx, idxlen, i);
267 if (nchildren == nattach)
268 return idx[i]->content->hdr;
269 }
270 }
271
272 return NULL;
273 }
274
275 /*
276 * check whether attachment #i is a parent of the attachment
277 * pointed to by cur
278 *
279 * Note: This and the calling procedure could be optimized quite a
280 * bit. For now, it's not worth the effort.
281 */
282
283 static int is_parent (short i, ATTACHPTR **idx, short idxlen, BODY *cur)
284 {
285 short level = idx[i]->level;
286
287 while ((++i < idxlen) && idx[i]->level > level)
288 {
289 if (idx[i]->content == cur)
290 return 1;
291 }
292
293 return 0;
294 }
295
296 static HEADER *find_parent (ATTACHPTR **idx, short idxlen, BODY *cur, short nattach)
297 {
298 short i;
299 HEADER *parent = NULL;
300
301 if (cur)
302 {
303 for (i = 0; i < idxlen; i++)
304 {
305 if (mutt_is_message_type (idx[i]->content->type, idx[i]->content->subtype)
306 && is_parent (i, idx, idxlen, cur))
307 parent = idx[i]->content->hdr;
308 if (idx[i]->content == cur)
309 break;
310 }
311 }
312 else if (nattach)
313 parent = find_common_parent (idx, idxlen, nattach);
314
315 return parent;
316 }
317
318 static void include_header (int quote, FILE * ifp,
319 HEADER * hdr, FILE * ofp,
320 char *_prefix)
321 {
322 int chflags = CH_DECODE;
323 char prefix[SHORT_STRING];
324
325 if (option (OPTWEED))
326 chflags |= CH_WEED | CH_REORDER;
327
328 if (quote)
329 {
330 if (_prefix)
331 strfcpy (prefix, _prefix, sizeof (prefix));
bff8671 Fix some nits with respect to text/plain; format=flowed.
Thomas Roessler authored
332 else if (!option (OPTTEXTFLOWED))
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
333 _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix),
334 Context, hdr, 0);
bff8671 Fix some nits with respect to text/plain; format=flowed.
Thomas Roessler authored
335 else
336 strfcpy (prefix, ">", sizeof (prefix));
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
337
338 chflags |= CH_PREFIX;
339 }
340
341 mutt_copy_header (ifp, hdr, ofp, chflags, quote ? prefix : NULL);
342 }
343
344 /* Attach all the body parts which can't be decoded.
345 * This code is shared by forwarding and replying. */
346
347 static BODY ** copy_problematic_attachments (FILE *fp,
348 BODY **last,
349 ATTACHPTR **idx,
350 short idxlen,
351 short force)
352 {
353 short i;
354
355 for (i = 0; i < idxlen; i++)
356 {
357 if (idx[i]->content->tagged &&
358 (force || !mutt_can_decode (idx[i]->content)))
359 {
360 if (mutt_copy_body (fp, last, idx[i]->content) == -1)
361 return NULL; /* XXXXX - may lead to crashes */
362 last = &((*last)->next);
363 }
364 }
365 return last;
366 }
367
368 /*
369 * forward one or several MIME bodies
370 * (non-message types)
371 */
372
373 static void attach_forward_bodies (FILE * fp, HEADER * hdr,
374 ATTACHPTR ** idx, short idxlen,
375 BODY * cur,
376 short nattach)
377 {
378 short i;
379 short mime_fwd_all = 0;
380 short mime_fwd_any = 1;
381 HEADER *parent = NULL;
382 HEADER *tmphdr = NULL;
383 BODY **last;
384 char tmpbody[_POSIX_PATH_MAX];
385 FILE *tmpfp = NULL;
386
387 char prefix[STRING];
388
389 int rc = 0;
390
391 STATE st;
392
393 /*
394 * First, find the parent message.
395 * Note: This could be made an option by just
396 * putting the following lines into an if block.
397 */
398
399
400 parent = find_parent (idx, idxlen, cur, nattach);
401
402 if (parent == NULL)
403 parent = hdr;
404
405
406 tmphdr = mutt_new_header ();
407 tmphdr->env = mutt_new_envelope ();
408 mutt_make_forward_subject (tmphdr->env, Context, parent);
409
410 mutt_mktemp (tmpbody);
411 if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
412 {
413 mutt_error (_("Can't open temporary file %s."), tmpbody);
414 return;
415 }
416
417 mutt_forward_intro (tmpfp, parent);
418
419 /* prepare the prefix here since we'll need it later. */
420
421 if (option (OPTFORWQUOTE))
bff8671 Fix some nits with respect to text/plain; format=flowed.
Thomas Roessler authored
422 {
423 if (!option (OPTTEXTFLOWED))
424 _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context,
425 parent, 0);
426 else
427 strfcpy (prefix, ">", sizeof (prefix));
428 }
429
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
430 include_header (option (OPTFORWQUOTE), fp, parent,
431 tmpfp, prefix);
432
433
434 /*
435 * Now, we have prepared the first part of the message body: The
436 * original message's header.
437 *
438 * The next part is more interesting: either include the message bodies,
439 * or attach them.
440 */
441
442 if ((!cur || mutt_can_decode (cur)) &&
443 (rc = query_quadoption (OPT_MIMEFWD,
9e7b527 Make some messages about mime-forwarding more comprehensible to
Thomas Roessler authored
444 _("Forward as attachments?"))) == M_YES)
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
445 mime_fwd_all = 1;
446 else if (rc == -1)
447 goto bail;
448
449 /*
450 * shortcut MIMEFWDREST when there is only one attachment. Is
451 * this intuitive?
452 */
453
454 if (!mime_fwd_all && !cur && (nattach > 1)
455 && !check_can_decode (idx, idxlen, cur))
456 {
457 if ((rc = query_quadoption (OPT_MIMEFWDREST,
458 _("Can't decode all tagged attachments. MIME-forward the others?"))) == -1)
459 goto bail;
460 else if (rc == M_NO)
461 mime_fwd_any = 0;
462 }
463
464 /* initialize a state structure */
465
466 memset (&st, 0, sizeof (st));
467
468 if (option (OPTFORWQUOTE))
469 st.prefix = prefix;
470 st.flags = M_CHARCONV;
471 if (option (OPTWEED))
472 st.flags |= M_WEED;
473 st.fpin = fp;
474 st.fpout = tmpfp;
475
476 /* where do we append new MIME parts? */
477 last = &tmphdr->content;
478
479 if (cur)
480 {
481 /* single body case */
482
483 if (!mime_fwd_all && mutt_can_decode (cur))
484 {
485 mutt_body_handler (cur, &st);
486 state_putc ('\n', &st);
487 }
488 else
489 {
490 if (mutt_copy_body (fp, last, cur) == -1)
491 goto bail;
492 last = &((*last)->next);
493 }
494 }
495 else
496 {
497 /* multiple body case */
498
499 if (!mime_fwd_all)
500 {
501 for (i = 0; i < idxlen; i++)
502 {
503 if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
504 {
505 mutt_body_handler (idx[i]->content, &st);
506 state_putc ('\n', &st);
507 }
508 }
509 }
510
511 if (mime_fwd_any &&
9913e1a @microe 'last' is assigned but never used. Remove assignment.
microe authored
512 copy_problematic_attachments (fp, last, idx, idxlen, mime_fwd_all) == NULL)
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
513 goto bail;
514 }
515
516 mutt_forward_trailer (tmpfp);
517
87de576 Use safe_fclose() instead of fclose(), add fclose() to check_sec.sh
Rocco Rutte authored
518 safe_fclose (&tmpfp);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
519 tmpfp = NULL;
520
521 /* now that we have the template, send it. */
522 ci_send_message (0, tmphdr, tmpbody, NULL, parent);
523 return;
524
525 bail:
526
527 if (tmpfp)
528 {
87de576 Use safe_fclose() instead of fclose(), add fclose() to check_sec.sh
Rocco Rutte authored
529 safe_fclose (&tmpfp);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
530 mutt_unlink (tmpbody);
531 }
532
533 mutt_free_header (&tmphdr);
534 }
535
536
537 /*
538 * Forward one or several message-type attachments. This
539 * is different from the previous function
540 * since we want to mimic the index menu's behaviour.
541 *
542 * Code reuse from ci_send_message is not possible here -
543 * ci_send_message relies on a context structure to find messages,
544 * while, on the attachment menu, messages are referenced through
545 * the attachment index.
546 */
547
548 static void attach_forward_msgs (FILE * fp, HEADER * hdr,
549 ATTACHPTR ** idx, short idxlen, BODY * cur)
550 {
551 HEADER *curhdr = NULL;
552 HEADER *tmphdr;
553 short i;
554 int rc;
555
556 BODY **last;
557 char tmpbody[_POSIX_PATH_MAX];
558 FILE *tmpfp = NULL;
559
560 int cmflags = 0;
561 int chflags = CH_XMIT;
562
563 if (cur)
564 curhdr = cur->hdr;
565 else
566 {
567 for (i = 0; i < idxlen; i++)
568 if (idx[i]->content->tagged)
569 {
570 curhdr = idx[i]->content->hdr;
571 break;
572 }
573 }
574
575 tmphdr = mutt_new_header ();
576 tmphdr->env = mutt_new_envelope ();
577 mutt_make_forward_subject (tmphdr->env, Context, curhdr);
578
579
580 tmpbody[0] = '\0';
581
582 if ((rc = query_quadoption (OPT_MIMEFWD,
583 _("Forward MIME encapsulated?"))) == M_NO)
584 {
585
586 /* no MIME encapsulation */
587
588 mutt_mktemp (tmpbody);
589 if (!(tmpfp = safe_fopen (tmpbody, "w")))
590 {
591 mutt_error (_("Can't create %s."), tmpbody);
592 mutt_free_header (&tmphdr);
593 return;
594 }
595
596 if (option (OPTFORWQUOTE))
597 {
598 chflags |= CH_PREFIX;
599 cmflags |= M_CM_PREFIX;
600 }
601
602 if (option (OPTFORWDECODE))
603 {
604 cmflags |= M_CM_DECODE | M_CM_CHARCONV;
605 if (option (OPTWEED))
606 {
607 chflags |= CH_WEED | CH_REORDER;
608 cmflags |= M_CM_WEED;
609 }
610 }
611
612
613 if (cur)
614 {
ed3b7a3 Apply message-hook to more commands, and make it more useful by
Thomas Roessler authored
615 /* mutt_message_hook (cur->hdr, M_MESSAGEHOOK); */
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
616 mutt_forward_intro (tmpfp, cur->hdr);
617 _mutt_copy_message (tmpfp, fp, cur->hdr, cur->hdr->content, cmflags, chflags);
618 mutt_forward_trailer (tmpfp);
619 }
620 else
621 {
622 for (i = 0; i < idxlen; i++)
623 {
624 if (idx[i]->content->tagged)
625 {
ed3b7a3 Apply message-hook to more commands, and make it more useful by
Thomas Roessler authored
626 /* mutt_message_hook (idx[i]->content->hdr, M_MESSAGEHOOK); */
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
627 mutt_forward_intro (tmpfp, idx[i]->content->hdr);
628 _mutt_copy_message (tmpfp, fp, idx[i]->content->hdr,
629 idx[i]->content->hdr->content, cmflags, chflags);
630 mutt_forward_trailer (tmpfp);
631 }
632 }
633 }
87de576 Use safe_fclose() instead of fclose(), add fclose() to check_sec.sh
Rocco Rutte authored
634 safe_fclose (&tmpfp);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
635 }
636 else if (rc == M_YES) /* do MIME encapsulation - we don't need to do much here */
637 {
638 last = &tmphdr->content;
639 if (cur)
640 mutt_copy_body (fp, last, cur);
641 else
642 {
643 for (i = 0; i < idxlen; i++)
644 if (idx[i]->content->tagged)
645 {
646 mutt_copy_body (fp, last, idx[i]->content);
647 last = &((*last)->next);
648 }
649 }
650 }
651 else
652 mutt_free_header (&tmphdr);
653
654 ci_send_message (0, tmphdr, *tmpbody ? tmpbody : NULL,
655 NULL, curhdr);
656
657 }
658
659 void mutt_attach_forward (FILE * fp, HEADER * hdr,
660 ATTACHPTR ** idx, short idxlen, BODY * cur)
661 {
662 short nattach;
663
664
665 if (check_all_msg (idx, idxlen, cur, 0) == 0)
666 attach_forward_msgs (fp, hdr, idx, idxlen, cur);
667 else
668 {
669 nattach = count_tagged (idx, idxlen);
670 attach_forward_bodies (fp, hdr, idx, idxlen, cur, nattach);
671 }
672 }
673
674
675
676 /**
677 **
678 ** the various reply functions, from the attachment menu
679 **
680 **
681 **/
682
683 /* Create the envelope defaults for a reply.
684 *
685 * This function can be invoked in two ways.
686 *
687 * Either, parent is NULL. In this case, all tagged bodies are of a message type,
688 * and the header information is fetched from them.
689 *
690 * Or, parent is non-NULL. In this case, cur is the common parent of all the
691 * tagged attachments.
692 *
693 * Note that this code is horribly similar to envelope_defaults () from send.c.
694 */
695
696 static int
697 attach_reply_envelope_defaults (ENVELOPE *env, ATTACHPTR **idx, short idxlen,
698 HEADER *parent, int flags)
699 {
700 ENVELOPE *curenv = NULL;
701 HEADER *curhdr = NULL;
702 short i;
703
704 if (!parent)
705 {
706 for (i = 0; i < idxlen; i++)
707 {
708 if (idx[i]->content->tagged)
709 {
710 curhdr = idx[i]->content->hdr;
711 curenv = curhdr->env;
712 break;
713 }
714 }
715 }
716 else
717 {
718 curenv = parent->env;
719 curhdr = parent;
720 }
721
722 if (curenv == NULL || curhdr == NULL)
723 {
724 mutt_error _("Can't find any tagged messages.");
725 return -1;
726 }
727
728 if (parent)
729 {
730 if (mutt_fetch_recips (env, curenv, flags) == -1)
731 return -1;
732 }
733 else
734 {
735 for (i = 0; i < idxlen; i++)
736 {
737 if (idx[i]->content->tagged
738 && mutt_fetch_recips (env, idx[i]->content->hdr->env, flags) == -1)
739 return -1;
740 }
741 }
742
743 if ((flags & SENDLISTREPLY) && !env->to)
744 {
745 mutt_error _("No mailing lists found!");
746 return (-1);
747 }
748
749 mutt_fix_reply_recipients (env);
750 mutt_make_misc_reply_headers (env, Context, curhdr, curenv);
8be9d4b Make sure References and In-Reply-To headers are generated properly
Thomas Roessler authored
751
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
752 if (parent)
8be9d4b Make sure References and In-Reply-To headers are generated properly
Thomas Roessler authored
753 mutt_add_to_reference_headers (env, curenv, NULL, NULL);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
754 else
755 {
8be9d4b Make sure References and In-Reply-To headers are generated properly
Thomas Roessler authored
756 LIST **p = NULL, **q = NULL;
757
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
758 for (i = 0; i < idxlen; i++)
759 {
760 if (idx[i]->content->tagged)
ffd2aec Bug fix. Problem noted by Vincent Lefevre's compiler.
Thomas Roessler authored
761 mutt_add_to_reference_headers (env, idx[i]->content->hdr->env, &p, &q);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
762 }
763 }
764
765 return 0;
766 }
767
768
769 /* This is _very_ similar to send.c's include_reply(). */
770
771 static void attach_include_reply (FILE *fp, FILE *tmpfp, HEADER *cur, int flags)
772 {
773 int cmflags = M_CM_PREFIX | M_CM_DECODE | M_CM_CHARCONV;
774 int chflags = CH_DECODE;
775
ed3b7a3 Apply message-hook to more commands, and make it more useful by
Thomas Roessler authored
776 /* mutt_message_hook (cur, M_MESSAGEHOOK); */
f801012 patch-1.3.3.tlr.message_hook.1
Thomas Roessler authored
777
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
778 mutt_make_attribution (Context, cur, tmpfp);
779
780 if (!option (OPTHEADER))
781 cmflags |= M_CM_NOHEADER;
782 if (option (OPTWEED))
783 {
784 chflags |= CH_WEED;
785 cmflags |= M_CM_WEED;
786 }
787
788 _mutt_copy_message (tmpfp, fp, cur, cur->content, cmflags, chflags);
789 mutt_make_post_indent (Context, cur, tmpfp);
790 }
791
792 void mutt_attach_reply (FILE * fp, HEADER * hdr,
793 ATTACHPTR ** idx, short idxlen, BODY * cur,
794 int flags)
795 {
796 short mime_reply_any = 0;
797
798 short nattach = 0;
799 HEADER *parent = NULL;
800 HEADER *tmphdr = NULL;
801 short i;
802
803 STATE st;
804 char tmpbody[_POSIX_PATH_MAX];
805 FILE *tmpfp;
806
807 char prefix[SHORT_STRING];
808 int rc;
809
810 if (check_all_msg (idx, idxlen, cur, 0) == -1)
811 {
812 nattach = count_tagged (idx, idxlen);
813 if ((parent = find_parent (idx, idxlen, cur, nattach)) == NULL)
814 parent = hdr;
815 }
816
817 if (nattach > 1 && !check_can_decode (idx, idxlen, cur))
818 {
819 if ((rc = query_quadoption (OPT_MIMEFWDREST,
820 _("Can't decode all tagged attachments. MIME-encapsulate the others?"))) == -1)
821 return;
822 else if (rc == M_YES)
823 mime_reply_any = 1;
824 }
825 else if (nattach == 1)
826 mime_reply_any = 1;
827
828 tmphdr = mutt_new_header ();
829 tmphdr->env = mutt_new_envelope ();
830
831 if (attach_reply_envelope_defaults (tmphdr->env, idx, idxlen,
245dabc Fix a segmentation fault when replying to multiple
Thomas Roessler authored
832 parent ? parent : (cur ? cur->hdr : NULL), flags) == -1)
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
833 {
834 mutt_free_header (&tmphdr);
835 return;
836 }
837
838 mutt_mktemp (tmpbody);
839 if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
840 {
841 mutt_error (_("Can't create %s."), tmpbody);
842 mutt_free_header (&tmphdr);
843 return;
844 }
845
846 if (!parent)
847 {
848 if (cur)
849 attach_include_reply (fp, tmpfp, cur->hdr, flags);
850 else
851 {
852 for (i = 0; i < idxlen; i++)
853 {
854 if (idx[i]->content->tagged)
855 attach_include_reply (fp, tmpfp, idx[i]->content->hdr, flags);
856 }
857 }
858 }
859 else
860 {
861 mutt_make_attribution (Context, parent, tmpfp);
862
863 memset (&st, 0, sizeof (STATE));
864 st.fpin = fp;
865 st.fpout = tmpfp;
866
bff8671 Fix some nits with respect to text/plain; format=flowed.
Thomas Roessler authored
867 if (!option (OPTTEXTFLOWED))
868 _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix),
869 Context, parent, 0);
870 else
871 strfcpy (prefix, ">", sizeof (prefix));
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
872
873 st.prefix = prefix;
874 st.flags = M_CHARCONV;
875
876 if (option (OPTWEED))
877 st.flags |= M_WEED;
878
879 if (option (OPTHEADER))
880 include_header (1, fp, parent, tmpfp, prefix);
881
882 if (cur)
883 {
884 if (mutt_can_decode (cur))
885 {
886 mutt_body_handler (cur, &st);
887 state_putc ('\n', &st);
888 }
889 else
890 mutt_copy_body (fp, &tmphdr->content, cur);
891 }
892 else
893 {
894 for (i = 0; i < idxlen; i++)
895 {
896 if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
897 {
898 mutt_body_handler (idx[i]->content, &st);
899 state_putc ('\n', &st);
900 }
901 }
902 }
903
904 mutt_make_post_indent (Context, parent, tmpfp);
905
906 if (mime_reply_any && !cur &&
907 copy_problematic_attachments (fp, &tmphdr->content, idx, idxlen, 0) == NULL)
908 {
909 mutt_free_header (&tmphdr);
87de576 Use safe_fclose() instead of fclose(), add fclose() to check_sec.sh
Rocco Rutte authored
910 safe_fclose (&tmpfp);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
911 return;
912 }
913 }
914
87de576 Use safe_fclose() instead of fclose(), add fclose() to check_sec.sh
Rocco Rutte authored
915 safe_fclose (&tmpfp);
d94a925 Rewriting lots of the recvattach code.
Thomas Roessler authored
916
917 if (ci_send_message (flags, tmphdr, tmpbody, NULL, parent) == 0)
918 mutt_set_flag (Context, hdr, M_REPLIED, 1);
919 }
920
Something went wrong with that request. Please try again.