NeoMutt  2018-07-16 +2388-bcedc8
Teaching an old dog new tricks
DOXYGEN
recvcmd.c File Reference

Send/reply with an attachment. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "mutt.h"
#include "alias.h"
#include "context.h"
#include "copy.h"
#include "curs_lib.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "mutt_body.h"
#include "mutt_logging.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "options.h"
#include "protos.h"
#include "send.h"
#include "sendlib.h"
#include "state.h"
#include <libintl.h>
+ Include dependency graph for recvcmd.c:

Go to the source code of this file.

Macros

#define EXTRA_SPACE   (15 + 7 + 2)
 

Functions

static bool check_msg (struct Body *b, bool err)
 Are we working with an RFC822 message. More...
 
static bool check_all_msg (struct AttachCtx *actx, struct Body *cur, bool err)
 Are all the Attachments RFC822 messages? More...
 
static bool check_can_decode (struct AttachCtx *actx, struct Body *cur)
 Can we decode all tagged attachments? More...
 
static short count_tagged (struct AttachCtx *actx)
 Count the number of tagged attachments. More...
 
static short count_tagged_children (struct AttachCtx *actx, short i)
 tagged children below a multipart/message attachment More...
 
void mutt_attach_bounce (struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
 Bounce function, from the attachment menu. More...
 
void mutt_attach_resend (FILE *fp, struct AttachCtx *actx, struct Body *cur)
 resend-message, from the attachment menu More...
 
static struct AttachPtrfind_common_parent (struct AttachCtx *actx, short nattach)
 find a common parent message for the tagged attachments More...
 
static int is_parent (short i, struct AttachCtx *actx, struct Body *cur)
 Check whether one attachment is the parent of another. More...
 
static struct AttachPtrfind_parent (struct AttachCtx *actx, struct Body *cur, short nattach)
 Find the parent of an Attachment. More...
 
static void include_header (bool quote, FILE *fp_in, struct Email *e, FILE *fp_out, char *prefix)
 Write an email header to a file, optionally quoting it. More...
 
static struct Body ** copy_problematic_attachments (struct Body **last, struct AttachCtx *actx, bool force)
 Attach the body parts which can't be decoded. More...
 
static void attach_forward_bodies (FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, short nattach)
 forward one or several MIME bodies More...
 
static void attach_forward_msgs (FILE *fp, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
 Forward one or several message-type attachments. More...
 
void mutt_attach_forward (FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
 Forward an Attachment. More...
 
static int attach_reply_envelope_defaults (struct Envelope *env, struct AttachCtx *actx, struct Email *parent, SendFlags flags)
 Create the envelope defaults for a reply. More...
 
static void attach_include_reply (FILE *fp, FILE *fp_tmp, struct Email *e)
 This is very similar to send.c's include_reply() More...
 
void mutt_attach_reply (FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
 Attach a reply. More...
 
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. More...
 

Variables

unsigned char C_MimeForwardRest
 Config: Forward all attachments, even if they can't be decoded. More...
 

Detailed Description

Send/reply with an attachment.

Authors
  • Thomas Roessler
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file recvcmd.c.

Macro Definition Documentation

#define EXTRA_SPACE   (15 + 7 + 2)

Function Documentation

static bool check_msg ( struct Body b,
bool  err 
)
static

Are we working with an RFC822 message.

Parameters
bBody of email
errIf true, display a message if this isn't an RFC822 message
Return values
trueThis is an RFC822 message

some helper functions to verify that we are exclusively operating on message/rfc822 attachments

Definition at line 74 of file recvcmd.c.

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 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
#define _(a)
Definition: message.h:28
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
#define mutt_error(...)
Definition: logging.h:84

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool check_all_msg ( struct AttachCtx actx,
struct Body cur,
bool  err 
)
static

Are all the Attachments RFC822 messages?

Parameters
actxAttachment context
curCurrent message
errIf true, report errors
Return values
trueIf all parts are RFC822 messages

Definition at line 92 of file recvcmd.c.

93 {
94  if (cur && !check_msg(cur, err))
95  return false;
96  else if (!cur)
97  {
98  for (short i = 0; i < actx->idxlen; i++)
99  {
100  if (actx->idx[i]->content->tagged)
101  {
102  if (!check_msg(actx->idx[i]->content, err))
103  return false;
104  }
105  }
106  }
107  return true;
108 }
static bool check_msg(struct Body *b, bool err)
Are we working with an RFC822 message.
Definition: recvcmd.c:74
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool check_can_decode ( struct AttachCtx actx,
struct Body cur 
)
static

Can we decode all tagged attachments?

Parameters
actxAttachment context
curBody of email
Return values
trueAll tagged attachments are decodable

Definition at line 116 of file recvcmd.c.

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]->content->tagged && !mutt_can_decode(actx->idx[i]->content))
123  return false;
124 
125  return true;
126 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1749
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static short count_tagged ( struct AttachCtx actx)
static

Count the number of tagged attachments.

Parameters
actxAttachment context
Return values
numNumber of tagged attachments

Definition at line 133 of file recvcmd.c.

134 {
135  short count = 0;
136  for (short i = 0; i < actx->idxlen; i++)
137  if (actx->idx[i]->content->tagged)
138  count++;
139 
140  return count;
141 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the caller graph for this function:

static short count_tagged_children ( struct AttachCtx actx,
short  i 
)
static

tagged children below a multipart/message attachment

Parameters
actxAttachment context
iIndex of first attachment
Return values
numNumber of tagged attachments

Definition at line 149 of file recvcmd.c.

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]->content->tagged)
156  count++;
157 
158  return count;
159 }
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * content
Attachment.
Definition: attach.h:36
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the caller graph for this function:

void mutt_attach_bounce ( struct Mailbox m,
FILE *  fp,
struct AttachCtx actx,
struct Body cur 
)

Bounce function, from the attachment menu.

Parameters
mMailbox
fpHandle of message
actxAttachment context
curBody of email

Definition at line 168 of file recvcmd.c.

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]->content->tagged)
200  {
201  if (TAILQ_EMPTY(&actx->idx[i]->content->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_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
213  else
214  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
215 
216  buf[0] = '\0';
217  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS) || (buf[0] == '\0'))
218  return;
219 
220  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
221  mutt_addrlist_parse(&al, buf);
222  if (TAILQ_EMPTY(&al))
223  {
224  mutt_error(_("Error parsing address"));
225  return;
226  }
227 
228  mutt_expand_aliases(&al);
229 
230  if (mutt_addrlist_to_intl(&al, &err) < 0)
231  {
232  mutt_error(_("Bad IDN: '%s'"), err);
233  FREE(&err);
234  goto end;
235  }
236 
237  buf[0] = '\0';
238  mutt_addrlist_write(buf, sizeof(buf), &al, true);
239 
240 #define EXTRA_SPACE (15 + 7 + 2)
241  /* See commands.c. */
242  snprintf(prompt, sizeof(prompt) - 4,
243  ngettext("Bounce message to %s?", "Bounce messages to %s?", p), buf);
244 
246  {
247  mutt_simple_format(prompt, sizeof(prompt) - 4, 0, MuttMessageWindow->cols - EXTRA_SPACE,
248  JUSTIFY_LEFT, 0, prompt, sizeof(prompt), false);
249  mutt_str_strcat(prompt, sizeof(prompt), "...?");
250  }
251  else
252  mutt_str_strcat(prompt, sizeof(prompt), "?");
253 
254  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
255  {
257  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
258  goto end;
259  }
260 
262 
263  if (cur)
264  ret = mutt_bounce_message(fp, cur->email, &al);
265  else
266  {
267  for (short i = 0; i < actx->idxlen; i++)
268  {
269  if (actx->idx[i]->content->tagged)
270  if (mutt_bounce_message(actx->idx[i]->fp, actx->idx[i]->content->email, &al))
271  ret = 1;
272  }
273  }
274 
275  if (ret == 0)
276  mutt_message(ngettext("Message bounced", "Messages bounced", p));
277  else
278  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
279 
280 end:
281  mutt_addrlist_clear(&al);
282 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:189
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:289
Left justify the text.
Definition: curs_lib.h:46
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:64
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:454
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3322
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1378
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
struct Envelope * env
Envelope information.
Definition: email.h:91
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:143
int mutt_bounce_message(FILE *fp, struct Email *e, struct AddressList *to)
Bounce an email message.
Definition: sendlib.c:3057
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1262
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
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:133
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1213
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define EXTRA_SPACE
#define FREE(x)
Definition: memory.h:40
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
#define TAILQ_EMPTY(head)
Definition: queue.h:715
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:631
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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:996

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_attach_resend ( FILE *  fp,
struct AttachCtx actx,
struct Body cur 
)

resend-message, from the attachment menu

Parameters
fpFile containing email
actxAttachment context
curAttachment

Definition at line 290 of file recvcmd.c.

291 {
292  if (!check_all_msg(actx, cur, true))
293  return;
294 
295  if (cur)
296  mutt_resend_message(fp, Context, cur->email);
297  else
298  {
299  for (short i = 0; i < actx->idxlen; i++)
300  if (actx->idx[i]->content->tagged)
301  mutt_resend_message(actx->idx[i]->fp, Context, actx->idx[i]->content->email);
302  }
303 }
The "current" mailbox.
Definition: context.h:36
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Attachment.
Definition: attach.h:36
int mutt_resend_message(FILE *fp, struct Context *ctx, struct Email *e_cur)
Resend an email.
Definition: send.c:1467
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct AttachPtr* find_common_parent ( struct AttachCtx actx,
short  nattach 
)
static

find a common parent message for the tagged attachments

Parameters
actxAttachment context
nattachNumber of tagged attachments
Return values
ptrParent attachment
NULLFailure, no common parent

Definition at line 312 of file recvcmd.c.

313 {
314  short i;
315  short nchildren;
316 
317  for (i = 0; i < actx->idxlen; i++)
318  if (actx->idx[i]->content->tagged)
319  break;
320 
321  while (--i >= 0)
322  {
323  if (mutt_is_message_type(actx->idx[i]->content->type, actx->idx[i]->content->subtype))
324  {
325  nchildren = count_tagged_children(actx, i);
326  if (nchildren == nattach)
327  return actx->idx[i];
328  }
329  }
330 
331  return NULL;
332 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
struct Body * content
Attachment.
Definition: attach.h:36
static short count_tagged_children(struct AttachCtx *actx, short i)
tagged children below a multipart/message attachment
Definition: recvcmd.c:149
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int is_parent ( short  i,
struct AttachCtx actx,
struct Body cur 
)
static

Check whether one attachment is the parent of another.

Parameters
iIndex of parent Attachment
actxAttachment context
curPotential child Attachemnt
Return values
trueAttachment

check whether attachment i is a parent of the attachment pointed to by cur

Note: This and the calling procedure could be optimized quite a bit. For now, it's not worth the effort.

Definition at line 346 of file recvcmd.c.

347 {
348  short level = actx->idx[i]->level;
349 
350  while ((++i < actx->idxlen) && (actx->idx[i]->level > level))
351  {
352  if (actx->idx[i]->content == cur)
353  return true;
354  }
355 
356  return false;
357 }
struct Body * content
Attachment.
Definition: attach.h:36
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the caller graph for this function:

static struct AttachPtr* find_parent ( struct AttachCtx actx,
struct Body cur,
short  nattach 
)
static

Find the parent of an Attachment.

Parameters
actxAttachment context
curAttachment (OPTIONAL)
nattachUse the nth attachment
Return values
ptrParent attachment
NULLNo parent exists

Definition at line 367 of file recvcmd.c.

368 {
369  struct AttachPtr *parent = NULL;
370 
371  if (cur)
372  {
373  for (short i = 0; i < actx->idxlen; i++)
374  {
375  if (mutt_is_message_type(actx->idx[i]->content->type,
376  actx->idx[i]->content->subtype) &&
377  is_parent(i, actx, cur))
378  {
379  parent = actx->idx[i];
380  }
381  if (actx->idx[i]->content == cur)
382  break;
383  }
384  }
385  else if (nattach)
386  parent = find_common_parent(actx, nattach);
387 
388  return parent;
389 }
An email to which things will be attached.
Definition: attach.h:34
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
short idxlen
Number of attachmentes.
Definition: attach.h:55
char * subtype
content-type subtype
Definition: body.h:37
static int is_parent(short i, struct AttachCtx *actx, struct Body *cur)
Check whether one attachment is the parent of another.
Definition: recvcmd.c:346
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
find a common parent message for the tagged attachments
Definition: recvcmd.c:312
unsigned int type
content-type primary type
Definition: body.h:65
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void include_header ( bool  quote,
FILE *  fp_in,
struct Email e,
FILE *  fp_out,
char *  prefix 
)
static

Write an email header to a file, optionally quoting it.

Parameters
quoteIf true, prefix the lines
fp_inFile to read from
eEmail
fp_outFile to write to
prefixPrefix for each line (OPTIONAL)

Definition at line 399 of file recvcmd.c.

400 {
401  CopyHeaderFlags chflags = CH_DECODE;
402  char prefix2[128];
403 
404  if (C_Weed)
405  chflags |= CH_WEED | CH_REORDER;
406 
407  if (quote)
408  {
409  if (prefix)
410  mutt_str_strfcpy(prefix2, prefix, sizeof(prefix2));
411  else if (!C_TextFlowed)
412  {
413  mutt_make_string(prefix2, sizeof(prefix2), NONULL(C_IndentString),
414  Context, Context->mailbox, e);
415  }
416  else
417  mutt_str_strfcpy(prefix2, ">", sizeof(prefix2));
418 
419  chflags |= CH_PREFIX;
420  }
421 
422  mutt_copy_header(fp_in, e, fp_out, chflags, quote ? prefix2 : NULL);
423 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:142
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix)
Copy Email header.
Definition: copy.c:391
struct Mailbox * mailbox
Definition: context.h:50
#define CH_WEED
Weed the headers?
Definition: copy.h:52
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
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
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:272
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:61
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct Body** copy_problematic_attachments ( struct Body **  last,
struct AttachCtx actx,
bool  force 
)
static

Attach the body parts which can't be decoded.

Parameters
[out]lastBody pointer to update
[in]actxAttachment context
[in]forceIf true, attach parts that can't be decoded
Return values
ptrPointer to last Body part

This code is shared by forwarding and replying.

Definition at line 434 of file recvcmd.c.

436 {
437  for (short i = 0; i < actx->idxlen; i++)
438  {
439  if (actx->idx[i]->content->tagged && (force || !mutt_can_decode(actx->idx[i]->content)))
440  {
441  if (mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content) == -1)
442  return NULL; /* XXXXX - may lead to crashes */
443  last = &((*last)->next);
444  }
445  }
446  return last;
447 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
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:47
bool tagged
This attachment is tagged.
Definition: body.h:70
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1749
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void attach_forward_bodies ( FILE *  fp,
struct Email e,
struct AttachCtx actx,
struct Body cur,
short  nattach 
)
static

forward one or several MIME bodies

Parameters
fpFile to read from
eEmail
actxAttachment Context
curBody of email
nattachNumber of tagged attachments

(non-message types)

Definition at line 459 of file recvcmd.c.

461 {
462  bool mime_fwd_all = false;
463  bool mime_fwd_any = true;
464  struct Email *e_parent = NULL;
465  FILE *fp_parent = NULL;
466  char tmpbody[PATH_MAX];
467  char prefix[256];
468  enum QuadOption ans = MUTT_ABORT;
469 
470  /* First, find the parent message.
471  * Note: This could be made an option by just
472  * putting the following lines into an if block. */
473  struct AttachPtr *parent = find_parent(actx, cur, nattach);
474  if (parent)
475  {
476  e_parent = parent->content->email;
477  fp_parent = parent->fp;
478  }
479  else
480  {
481  e_parent = e;
482  fp_parent = actx->fp_root;
483  }
484 
485  struct Email *e_tmp = email_new();
486  e_tmp->env = mutt_env_new();
487  mutt_make_forward_subject(e_tmp->env, Context->mailbox, e_parent);
488 
489  mutt_mktemp(tmpbody, sizeof(tmpbody));
490  FILE *fp_tmp = mutt_file_fopen(tmpbody, "w");
491  if (!fp_tmp)
492  {
493  mutt_error(_("Can't open temporary file %s"), tmpbody);
494  email_free(&e_tmp);
495  return;
496  }
497 
498  mutt_forward_intro(Context->mailbox, e_parent, fp_tmp);
499 
500  /* prepare the prefix here since we'll need it later. */
501 
502  if (C_ForwardQuote)
503  {
504  if (C_TextFlowed)
505  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
506  else
507  {
508  mutt_make_string(prefix, sizeof(prefix), NONULL(C_IndentString), Context,
509  Context->mailbox, e_parent);
510  }
511  }
512 
513  include_header(C_ForwardQuote, fp_parent, e_parent, fp_tmp, prefix);
514 
515  /* Now, we have prepared the first part of the message body: The
516  * original message's header.
517  *
518  * The next part is more interesting: either include the message bodies,
519  * or attach them. */
520  if ((!cur || mutt_can_decode(cur)) &&
521  ((ans = query_quadoption(C_MimeForward, _("Forward as attachments?"))) == MUTT_YES))
522  {
523  mime_fwd_all = true;
524  }
525  else if (ans == MUTT_ABORT)
526  {
527  goto bail;
528  }
529 
530  /* shortcut MIMEFWDREST when there is only one attachment.
531  * Is this intuitive? */
532  if (!mime_fwd_all && !cur && (nattach > 1) && !check_can_decode(actx, cur))
533  {
534  ans = query_quadoption(
536  _("Can't decode all tagged attachments. MIME-forward the others?"));
537  if (ans == MUTT_ABORT)
538  goto bail;
539  else if (ans == MUTT_NO)
540  mime_fwd_any = false;
541  }
542 
543  /* initialize a state structure */
544 
545  struct State st = { 0 };
546  if (C_ForwardQuote)
547  st.prefix = prefix;
548  st.flags = MUTT_CHARCONV;
549  if (C_Weed)
550  st.flags |= MUTT_WEED;
551  st.fp_out = fp_tmp;
552 
553  /* where do we append new MIME parts? */
554  struct Body **last = &e_tmp->content;
555 
556  if (cur)
557  {
558  /* single body case */
559 
560  if (!mime_fwd_all && mutt_can_decode(cur))
561  {
562  st.fp_in = fp;
563  mutt_body_handler(cur, &st);
564  state_putc('\n', &st);
565  }
566  else
567  {
568  if (mutt_body_copy(fp, last, cur) == -1)
569  goto bail;
570  }
571  }
572  else
573  {
574  /* multiple body case */
575 
576  if (!mime_fwd_all)
577  {
578  for (int i = 0; i < actx->idxlen; i++)
579  {
580  if (actx->idx[i]->content->tagged && mutt_can_decode(actx->idx[i]->content))
581  {
582  st.fp_in = actx->idx[i]->fp;
583  mutt_body_handler(actx->idx[i]->content, &st);
584  state_putc('\n', &st);
585  }
586  }
587  }
588 
589  if (mime_fwd_any && !copy_problematic_attachments(last, actx, mime_fwd_all))
590  goto bail;
591  }
592 
593  mutt_forward_trailer(Context->mailbox, e_parent, fp_tmp);
594 
595  mutt_file_fclose(&fp_tmp);
596  fp_tmp = NULL;
597 
598  /* now that we have the template, send it. */
599  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
600  el_add_email(&el, e_parent);
601  ci_send_message(SEND_NO_FLAGS, e_tmp, tmpbody, NULL, &el);
602  emaillist_clear(&el);
603  return;
604 
605 bail:
606 
607  if (fp_tmp)
608  {
609  mutt_file_fclose(&fp_tmp);
610  mutt_file_unlink(tmpbody);
611  }
612 
613  email_free(&e_tmp);
614 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
An email to which things will be attached.
Definition: attach.h:34
The envelope/body of an email.
Definition: email.h:39
static void include_header(bool quote, FILE *fp_in, struct Email *e, FILE *fp_out, char *prefix)
Write an email header to a file, optionally quoting it.
Definition: recvcmd.c:399
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:116
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:142
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3322
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
List of MIME parts.
Definition: email.h:92
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:191
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:432
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:86
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Mailbox * mailbox
Definition: context.h:50
WHERE unsigned char C_MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:193
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:127
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
Envelope information.
Definition: email.h:91
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:47
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:398
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:41
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:367
#define PATH_MAX
Definition: mutt.h:51
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1749
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
#define MUTT_WEED
Weed headers even when not in display mode.
Definition: state.h:35
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1837
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:451
static struct Body ** copy_problematic_attachments(struct Body **last, struct AttachCtx *actx, bool force)
Attach the body parts which can&#39;t be decoded.
Definition: recvcmd.c:434
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:272
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define state_putc(str, state)
Definition: state.h:55
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:61
WHERE bool C_ForwardQuote
Config: Automatically quote a forwarded message using C_IndentString.
Definition: globals.h:224
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *e)
Create a subject for a forwarded email.
Definition: send.c:912
Keep track when processing files.
Definition: state.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1545
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
unsigned char C_MimeForwardRest
Config: Forward all attachments, even if they can&#39;t be decoded.
Definition: recvcmd.c:60
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:584
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void attach_forward_msgs ( FILE *  fp,
struct AttachCtx actx,
struct Body cur,
SendFlags  flags 
)
static

Forward one or several message-type attachments.

Parameters
fpFile handle to attachment
actxAttachment Context
curAttachment to forward (OPTIONAL)
flagsSend mode, see SendFlags

This is different from the previous function since we want to mimic the index menu's behavior.

Code reuse from ci_send_message() is not possible here - it relies on a context structure to find messages, while, on the attachment menu, messages are referenced through the attachment index.

Definition at line 630 of file recvcmd.c.

632 {
633  struct Email *e_cur = NULL;
634  struct Email *e_tmp = NULL;
635  enum QuadOption ans;
636 
637  struct Body **last = NULL;
638  char tmpbody[PATH_MAX];
639  FILE *fp_tmp = NULL;
640 
641  CopyHeaderFlags chflags = CH_XMIT;
642 
643  if (cur)
644  e_cur = cur->email;
645  else
646  {
647  for (short i = 0; i < actx->idxlen; i++)
648  {
649  if (actx->idx[i]->content->tagged)
650  {
651  e_cur = actx->idx[i]->content->email;
652  break;
653  }
654  }
655  }
656 
657  e_tmp = email_new();
658  e_tmp->env = mutt_env_new();
659  mutt_make_forward_subject(e_tmp->env, Context->mailbox, e_cur);
660 
661  tmpbody[0] = '\0';
662 
663  ans = query_quadoption(C_MimeForward, _("Forward MIME encapsulated?"));
664  if (ans == MUTT_NO)
665  {
666  /* no MIME encapsulation */
667 
668  mutt_mktemp(tmpbody, sizeof(tmpbody));
669  fp_tmp = mutt_file_fopen(tmpbody, "w");
670  if (!fp_tmp)
671  {
672  mutt_error(_("Can't create %s"), tmpbody);
673  email_free(&e_tmp);
674  return;
675  }
676 
678  if (C_ForwardQuote)
679  {
680  chflags |= CH_PREFIX;
681  cmflags |= MUTT_CM_PREFIX;
682  }
683 
684  if (C_ForwardDecode)
685  {
686  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
687  if (C_Weed)
688  {
689  chflags |= CH_WEED | CH_REORDER;
690  cmflags |= MUTT_CM_WEED;
691  }
692  }
693 
694  if (cur)
695  {
696  mutt_forward_intro(Context->mailbox, cur->email, fp_tmp);
697  mutt_copy_message_fp(fp_tmp, fp, cur->email, cmflags, chflags);
698  mutt_forward_trailer(Context->mailbox, cur->email, fp_tmp);
699  }
700  else
701  {
702  for (short i = 0; i < actx->idxlen; i++)
703  {
704  if (actx->idx[i]->content->tagged)
705  {
706  mutt_forward_intro(Context->mailbox, actx->idx[i]->content->email, fp_tmp);
707  mutt_copy_message_fp(fp_tmp, actx->idx[i]->fp,
708  actx->idx[i]->content->email, cmflags, chflags);
709  mutt_forward_trailer(Context->mailbox, actx->idx[i]->content->email, fp_tmp);
710  }
711  }
712  }
713  mutt_file_fclose(&fp_tmp);
714  }
715  else if (ans == MUTT_YES) /* do MIME encapsulation - we don't need to do much here */
716  {
717  last = &e_tmp->content;
718  if (cur)
719  mutt_body_copy(fp, last, cur);
720  else
721  {
722  for (short i = 0; i < actx->idxlen; i++)
723  {
724  if (actx->idx[i]->content->tagged)
725  {
726  mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content);
727  last = &((*last)->next);
728  }
729  }
730  }
731  }
732  else
733  email_free(&e_tmp);
734 
735  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
736  el_add_email(&el, e_cur);
737  ci_send_message(flags, e_tmp, (tmpbody[0] != '\0') ? tmpbody : NULL, NULL, &el);
738  emaillist_clear(&el);
739 }
The "current" mailbox.
Definition: context.h:36
The envelope/body of an email.
Definition: email.h:39
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:223
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3322
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
List of MIME parts.
Definition: email.h:92
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
make a copy of a message from a FILE pointer
Definition: copy.c:597
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:432
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
The body of an email.
Definition: body.h:34
struct Mailbox * mailbox
Definition: context.h:50
WHERE unsigned char C_MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:193
#define CH_WEED
Weed the headers?
Definition: copy.h:52
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:127
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
Envelope information.
Definition: email.h:91
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:47
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:398
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:41
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
#define PATH_MAX
Definition: mutt.h:51
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1837
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:451
struct Body * content
Attachment.
Definition: attach.h:36
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_error(...)
Definition: logging.h:84
WHERE bool C_ForwardQuote
Config: Automatically quote a forwarded message using C_IndentString.
Definition: globals.h:224
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *e)
Create a subject for a forwarded email.
Definition: send.c:912
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:584
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_attach_forward ( FILE *  fp,
struct Email e,
struct AttachCtx actx,
struct Body cur,
SendFlags  flags 
)

Forward an Attachment.

Parameters
fpHandle to the attachment
eEmail
actxAttachment Context
curCurrent message
flagsSend mode, see SendFlags

Definition at line 749 of file recvcmd.c.

751 {
752  if (check_all_msg(actx, cur, false))
753  attach_forward_msgs(fp, actx, cur, flags);
754  else
755  {
756  const short nattach = count_tagged(actx);
757  attach_forward_bodies(fp, e, actx, cur, nattach);
758  }
759 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
static void attach_forward_msgs(FILE *fp, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward one or several message-type attachments.
Definition: recvcmd.c:630
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:133
static void attach_forward_bodies(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, short nattach)
forward one or several MIME bodies
Definition: recvcmd.c:459

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int attach_reply_envelope_defaults ( struct Envelope env,
struct AttachCtx actx,
struct Email parent,
SendFlags  flags 
)
static

Create the envelope defaults for a reply.

Parameters
envEnvelope to fill in
actxAttachment Context
parentParent Email
flagsFlags, see SendFlags
Return values
0Success
-1Error

This function can be invoked in two ways.

Either, parent is NULL. In this case, all tagged bodies are of a message type, and the header information is fetched from them.

Or, parent is non-NULL. In this case, cur is the common parent of all the tagged attachments.

Note that this code is horribly similar to envelope_defaults() from send.c.

Definition at line 780 of file recvcmd.c.

782 {
783  struct Envelope *curenv = NULL;
784  struct Email *e = NULL;
785 
786  if (!parent)
787  {
788  for (short i = 0; i < actx->idxlen; i++)
789  {
790  if (actx->idx[i]->content->tagged)
791  {
792  e = actx->idx[i]->content->email;
793  curenv = e->env;
794  break;
795  }
796  }
797  }
798  else
799  {
800  curenv = parent->env;
801  e = parent;
802  }
803 
804  if (!curenv || !e)
805  {
806  mutt_error(_("Can't find any tagged messages"));
807  return -1;
808  }
809 
810 #ifdef USE_NNTP
811  if ((flags & SEND_NEWS))
812  {
813  /* in case followup set Newsgroups: with Followup-To: if it present */
814  if (!env->newsgroups && curenv &&
815  (mutt_str_strcasecmp(curenv->followup_to, "poster") != 0))
816  {
817  env->newsgroups = mutt_str_strdup(curenv->followup_to);
818  }
819  }
820  else
821 #endif
822  {
823  if (parent)
824  {
825  if (mutt_fetch_recips(env, curenv, flags) == -1)
826  return -1;
827  }
828  else
829  {
830  for (short i = 0; i < actx->idxlen; i++)
831  {
832  if (actx->idx[i]->content->tagged &&
833  (mutt_fetch_recips(env, actx->idx[i]->content->email->env, flags) == -1))
834  {
835  return -1;
836  }
837  }
838  }
839 
840  if ((flags & SEND_LIST_REPLY) && TAILQ_EMPTY(&env->to))
841  {
842  mutt_error(_("No mailing lists found"));
843  return -1;
844  }
845 
847  }
848  mutt_make_misc_reply_headers(env, curenv);
849 
850  if (parent)
851  mutt_add_to_reference_headers(env, curenv);
852  else
853  {
854  for (short i = 0; i < actx->idxlen; i++)
855  {
856  if (actx->idx[i]->content->tagged)
858  }
859  }
860 
861  return 0;
862 }
void mutt_fix_reply_recipients(struct Envelope *env)
Remove duplicate recipients.
Definition: send.c:885
The envelope/body of an email.
Definition: email.h:39
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:802
#define _(a)
Definition: message.h:28
void mutt_make_misc_reply_headers(struct Envelope *env, struct Envelope *curenv)
Set subject for a reply.
Definition: send.c:929
short idxlen
Number of attachmentes.
Definition: attach.h:55
struct Envelope * env
Envelope information.
Definition: email.h:91
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:89
bool tagged
This attachment is tagged.
Definition: body.h:70
#define SEND_NEWS
Reply to a news article.
Definition: send.h:101
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:715
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
The header of an Email.
Definition: envelope.h:54
void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv)
Generate references for a reply email.
Definition: send.c:951

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void attach_include_reply ( FILE *  fp,
FILE *  fp_tmp,
struct Email e 
)
static

This is very similar to send.c's include_reply()

Parameters
fpFile handle to attachment
fp_tmpFile handle to temporary file
eEmail

Definition at line 870 of file recvcmd.c.

871 {
873  CopyHeaderFlags chflags = CH_DECODE;
874 
876 
877  if (!C_Header)
878  cmflags |= MUTT_CM_NOHEADER;
879  if (C_Weed)
880  {
881  chflags |= CH_WEED;
882  cmflags |= MUTT_CM_WEED;
883  }
884 
885  mutt_copy_message_fp(fp_tmp, fp, e, cmflags, chflags);
887 }
The "current" mailbox.
Definition: context.h:36
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
make a copy of a message from a FILE pointer
Definition: copy.c:597
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
void mutt_make_post_indent(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add suffix to replied email text.
Definition: send.c:660
struct Mailbox * mailbox
Definition: context.h:50
#define CH_WEED
Weed the headers?
Definition: copy.h:52
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:230
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:641

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_attach_reply ( FILE *  fp,
struct Email e,
struct AttachCtx actx,
struct Body e_cur,
SendFlags  flags 
)

Attach a reply.

Parameters
fpFile handle to reply
eEmail
actxAttachment Context
e_curCurrent message
flagsSend mode, see SendFlags

Definition at line 897 of file recvcmd.c.

899 {
900  bool mime_reply_any = false;
901 
902  short nattach = 0;
903  struct AttachPtr *parent = NULL;
904  struct Email *e_parent = NULL;
905  FILE *fp_parent = NULL;
906  struct Email *e_tmp = NULL;
907 
908  struct State st;
909  char tmpbody[PATH_MAX];
910  FILE *fp_tmp = NULL;
911 
912  char prefix[128];
913 
914 #ifdef USE_NNTP
915  if (flags & SEND_NEWS)
916  OptNewsSend = true;
917  else
918  OptNewsSend = false;
919 #endif
920 
921  if (!check_all_msg(actx, e_cur, false))
922  {
923  nattach = count_tagged(actx);
924  parent = find_parent(actx, e_cur, nattach);
925  if (parent)
926  {
927  e_parent = parent->content->email;
928  fp_parent = parent->fp;
929  }
930  else
931  {
932  e_parent = e;
933  fp_parent = actx->fp_root;
934  }
935  }
936 
937  if ((nattach > 1) && !check_can_decode(actx, e_cur))
938  {
939  const enum QuadOption ans = query_quadoption(
940  C_MimeForwardRest, _("Can't decode all tagged attachments. "
941  "MIME-encapsulate the others?"));
942  if (ans == MUTT_ABORT)
943  return;
944  else if (ans == MUTT_YES)
945  mime_reply_any = true;
946  }
947  else if (nattach == 1)
948  mime_reply_any = true;
949 
950  e_tmp = email_new();
951  e_tmp->env = mutt_env_new();
952 
954  e_tmp->env, actx, e_parent ? e_parent : (e_cur ? e_cur->email : NULL), flags) == -1)
955  {
956  email_free(&e_tmp);
957  return;
958  }
959 
960  mutt_mktemp(tmpbody, sizeof(tmpbody));
961  fp_tmp = mutt_file_fopen(tmpbody, "w");
962  if (!fp_tmp)
963  {
964  mutt_error(_("Can't create %s"), tmpbody);
965  email_free(&e_tmp);
966  return;
967  }
968 
969  if (!e_parent)
970  {
971  if (e_cur)
972  attach_include_reply(fp, fp_tmp, e_cur->email);
973  else
974  {
975  for (short i = 0; i < actx->idxlen; i++)
976  {
977  if (actx->idx[i]->content->tagged)
978  attach_include_reply(actx->idx[i]->fp, fp_tmp, actx->idx[i]->content->email);
979  }
980  }
981  }
982  else
983  {
984  mutt_make_attribution(Context->mailbox, e_parent, fp_tmp);
985 
986  memset(&st, 0, sizeof(struct State));
987  st.fp_out = fp_tmp;
988 
989  if (!C_TextFlowed)
990  {
991  mutt_make_string(prefix, sizeof(prefix), NONULL(C_IndentString), Context,
992  Context->mailbox, e_parent);
993  }
994  else
995  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
996 
997  st.prefix = prefix;
998  st.flags = MUTT_CHARCONV;
999 
1000  if (C_Weed)
1001  st.flags |= MUTT_WEED;
1002 
1003  if (C_Header)
1004  include_header(true, fp_parent, e_parent, fp_tmp, prefix);
1005 
1006  if (e_cur)
1007  {
1008  if (mutt_can_decode(e_cur))
1009  {
1010  st.fp_in = fp;
1011  mutt_body_handler(e_cur, &st);
1012  state_putc('\n', &st);
1013  }
1014  else
1015  mutt_body_copy(fp, &e_tmp->content, e_cur);
1016  }
1017  else
1018  {
1019  for (short i = 0; i < actx->idxlen; i++)
1020  {
1021  if (actx->idx[i]->content->tagged && mutt_can_decode(actx->idx[i]->content))
1022  {
1023  st.fp_in = actx->idx[i]->fp;
1024  mutt_body_handler(actx->idx[i]->content, &st);
1025  state_putc('\n', &st);
1026  }
1027  }
1028  }
1029 
1030  mutt_make_post_indent(Context->mailbox, e_parent, fp_tmp);
1031 
1032  if (mime_reply_any && !e_cur &&
1033  !copy_problematic_attachments(&e_tmp->content, actx, false))
1034  {
1035  email_free(&e_tmp);
1036  mutt_file_fclose(&fp_tmp);
1037  return;
1038  }
1039  }
1040 
1041  mutt_file_fclose(&fp_tmp);
1042 
1043  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1044  el_add_email(&el, e_parent ? e_parent : (e_cur ? e_cur->email : NULL));
1045  if (ci_send_message(flags, e_tmp, tmpbody, NULL, &el) == 0)
1046  {
1048  }
1049  emaillist_clear(&el);
1050 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:37
An email to which things will be attached.
Definition: attach.h:34
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:68
The envelope/body of an email.
Definition: email.h:39
static void include_header(bool quote, FILE *fp_in, struct Email *e, FILE *fp_out, char *prefix)
Write an email header to a file, optionally quoting it.
Definition: recvcmd.c:399
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:116
static void attach_include_reply(FILE *fp, FILE *fp_tmp, struct Email *e)
This is very similar to send.c&#39;s include_reply()
Definition: recvcmd.c:870
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:142
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3322
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
List of MIME parts.
Definition: email.h:92
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
void mutt_make_post_indent(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add suffix to replied email text.
Definition: send.c:660
Messages that have been replied to.
Definition: mutt.h:100
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Mailbox * mailbox
Definition: context.h:50
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:127
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
Envelope information.
Definition: email.h:91
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:47
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:398
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:41
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:230
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:367
#define PATH_MAX
Definition: mutt.h:51
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1749
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
#define MUTT_WEED
Weed headers even when not in display mode.
Definition: state.h:35
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:133
#define SEND_NEWS
Reply to a news article.
Definition: send.h:101
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1837
static struct Body ** copy_problematic_attachments(struct Body **last, struct AttachCtx *actx, bool force)
Attach the body parts which can&#39;t be decoded.
Definition: recvcmd.c:434
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:272
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define state_putc(str, state)
Definition: state.h:55
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:61
Keep track when processing files.
Definition: state.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1545
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
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:780
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:44
unsigned char C_MimeForwardRest
Config: Forward all attachments, even if they can&#39;t be decoded.
Definition: recvcmd.c:60
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:584
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:641

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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.

Parameters
fpFile containing attachment (UNUSED)
eEmail (UNUSED)
actxAttachment Context
curCurrent attachment

Definition at line 1059 of file recvcmd.c.

1061 {
1062  if (!check_all_msg(actx, cur, 0))
1063  {
1064  /* L10N: You will see this error message if you invoke <compose-to-sender>
1065  when you are on a normal attachment. */
1066  mutt_error(_("You may only compose to sender with message/rfc822 parts"));
1067  return;
1068  }
1069 
1070  struct Email *e_tmp = email_new();
1071  e_tmp->env = mutt_env_new();
1072 
1073  if (cur)
1074  {
1075  if (mutt_fetch_recips(e_tmp->env, cur->email->env, SEND_TO_SENDER) == -1)
1076  return;
1077  }
1078  else
1079  {
1080  for (int i = 0; i < actx->idxlen; i++)
1081  {
1082  if (actx->idx[i]->content->tagged &&
1083  (mutt_fetch_recips(e_tmp->env, actx->idx[i]->content->email->env,
1084  SEND_TO_SENDER) == -1))
1085  return;
1086  }
1087  }
1088  ci_send_message(SEND_NO_FLAGS, e_tmp, NULL, NULL, NULL);
1089 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:92
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:99
The envelope/body of an email.
Definition: email.h:39
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:802
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:86
struct Envelope * env
Envelope information.
Definition: email.h:91
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:41
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1837
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

unsigned char C_MimeForwardRest

Config: Forward all attachments, even if they can't be decoded.

Definition at line 60 of file recvcmd.c.