NeoMutt  2020-03-20-65-g141838
Teaching an old dog new tricks
DOXYGEN
recvcmd.c File Reference

Send/reply with an attachment. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "recvcmd.h"
#include "alias.h"
#include "context.h"
#include "copy.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "init.h"
#include "mutt_body.h"
#include "mutt_logging.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

◆ EXTRA_SPACE

#define EXTRA_SPACE   (15 + 7 + 2)

Function Documentation

◆ check_msg()

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:1391
#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:

◆ check_all_msg()

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  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:

◆ check_can_decode()

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:1753
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:

◆ count_tagged()

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:

◆ count_tagged_children()

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:

◆ mutt_attach_bounce()

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(&al, buf, sizeof(buf), 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,
249  JUSTIFY_LEFT, 0, prompt, sizeof(prompt), false);
250  mutt_str_strcat(prompt, sizeof(prompt), "...?");
251  }
252  else
253  mutt_str_strcat(prompt, sizeof(prompt), "?");
254 
255  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
256  {
258  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
259  goto end;
260  }
261 
263 
264  if (cur)
265  ret = mutt_bounce_message(fp, cur->email, &al);
266  else
267  {
268  for (short i = 0; i < actx->idxlen; i++)
269  {
270  if (actx->idx[i]->content->tagged)
271  if (mutt_bounce_message(actx->idx[i]->fp, actx->idx[i]->content->email, &al))
272  ret = 1;
273  }
274  }
275 
276  if (ret == 0)
277  mutt_message(ngettext("Message bounced", "Messages bounced", p));
278  else
279  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
280 
281 end:
282  mutt_addrlist_clear(&al);
283 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:179
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:303
Left justify the text.
Definition: curs_lib.h:47
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
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:112
struct Envelope * env
Envelope information.
Definition: email.h:89
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:113
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
int mutt_bounce_message(FILE *fp, struct Email *e, struct AddressList *to)
Bounce an email message.
Definition: sendlib.c:3123
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1337
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:773
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:1217
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:46
#define TAILQ_EMPTY(head)
Definition: queue.h:714
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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:1138
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:1071
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_attach_resend()

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 291 of file recvcmd.c.

292 {
293  if (!check_all_msg(actx, cur, true))
294  return;
295 
296  if (cur)
297  mutt_resend_message(fp, Context, cur->email);
298  else
299  {
300  for (short i = 0; i < actx->idxlen; i++)
301  if (actx->idx[i]->content->tagged)
302  mutt_resend_message(actx->idx[i]->fp, Context, actx->idx[i]->content->email);
303  }
304 }
The "current" mailbox.
Definition: context.h:37
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:1504
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:

◆ find_common_parent()

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 313 of file recvcmd.c.

314 {
315  short i;
316  short nchildren;
317 
318  for (i = 0; i < actx->idxlen; i++)
319  if (actx->idx[i]->content->tagged)
320  break;
321 
322  while (--i >= 0)
323  {
324  if (mutt_is_message_type(actx->idx[i]->content->type, actx->idx[i]->content->subtype))
325  {
326  nchildren = count_tagged_children(actx, i);
327  if (nchildren == nattach)
328  return actx->idx[i];
329  }
330  }
331 
332  return NULL;
333 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1391
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:

◆ is_parent()

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 347 of file recvcmd.c.

348 {
349  short level = actx->idx[i]->level;
350 
351  while ((++i < actx->idxlen) && (actx->idx[i]->level > level))
352  {
353  if (actx->idx[i]->content == cur)
354  return true;
355  }
356 
357  return false;
358 }
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:

◆ find_parent()

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 368 of file recvcmd.c.

369 {
370  struct AttachPtr *parent = NULL;
371 
372  if (cur)
373  {
374  for (short i = 0; i < actx->idxlen; i++)
375  {
376  if (mutt_is_message_type(actx->idx[i]->content->type,
377  actx->idx[i]->content->subtype) &&
378  is_parent(i, actx, cur))
379  {
380  parent = actx->idx[i];
381  }
382  if (actx->idx[i]->content == cur)
383  break;
384  }
385  }
386  else if (nattach)
387  parent = find_common_parent(actx, nattach);
388 
389  return parent;
390 }
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:1391
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:347
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
find a common parent message for the tagged attachments
Definition: recvcmd.c:313
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:

◆ include_header()

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 400 of file recvcmd.c.

401 {
402  CopyHeaderFlags chflags = CH_DECODE;
403  char prefix2[128];
404 
405  if (C_Weed)
406  chflags |= CH_WEED | CH_REORDER;
407 
408  if (quote)
409  {
410  if (prefix)
411  mutt_str_strfcpy(prefix2, prefix, sizeof(prefix2));
412  else if (!C_TextFlowed)
413  {
414  mutt_make_string(prefix2, sizeof(prefix2), 0, NONULL(C_IndentString),
415  Context, Context->mailbox, e);
416  }
417  else
418  mutt_str_strfcpy(prefix2, ">", sizeof(prefix2));
419 
420  chflags |= CH_PREFIX;
421  }
422 
423  mutt_copy_header(fp_in, e, fp_out, chflags, quote ? prefix2 : NULL, 0);
424 }
The "current" mailbox.
Definition: context.h:37
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:136
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
struct Mailbox * mailbox
Definition: context.h:51
#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:773
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:254
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
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:392
#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:

◆ copy_problematic_attachments()

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 435 of file recvcmd.c.

437 {
438  for (short i = 0; i < actx->idxlen; i++)
439  {
440  if (actx->idx[i]->content->tagged && (force || !mutt_can_decode(actx->idx[i]->content)))
441  {
442  if (mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content) == -1)
443  return NULL; /* XXXXX - may lead to crashes */
444  last = &((*last)->next);
445  }
446  }
447  return last;
448 }
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:48
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:1753
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:

◆ attach_forward_bodies()

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 460 of file recvcmd.c.

462 {
463  bool mime_fwd_all = false;
464  bool mime_fwd_any = true;
465  struct Email *e_parent = NULL;
466  FILE *fp_parent = NULL;
467  char prefix[256];
468  enum QuadOption ans = MUTT_NO;
469  struct Buffer *tmpbody = NULL;
470 
471  /* First, find the parent message.
472  * Note: This could be made an option by just
473  * putting the following lines into an if block. */
474  struct AttachPtr *parent = find_parent(actx, cur, nattach);
475  if (parent)
476  {
477  e_parent = parent->content->email;
478  fp_parent = parent->fp;
479  }
480  else
481  {
482  e_parent = e;
483  fp_parent = actx->fp_root;
484  }
485 
486  struct Email *e_tmp = email_new();
487  e_tmp->env = mutt_env_new();
488  mutt_make_forward_subject(e_tmp->env, Context->mailbox, e_parent);
489 
490  tmpbody = mutt_buffer_pool_get();
491  mutt_buffer_mktemp(tmpbody);
492  FILE *fp_tmp = mutt_file_fopen(mutt_b2s(tmpbody), "w");
493  if (!fp_tmp)
494  {
495  mutt_error(_("Can't open temporary file %s"), mutt_b2s(tmpbody));
496  email_free(&e_tmp);
497  goto bail;
498  }
499 
500  mutt_forward_intro(Context->mailbox, e_parent, fp_tmp);
501 
502  /* prepare the prefix here since we'll need it later. */
503 
504  if (C_ForwardQuote)
505  {
506  if (C_TextFlowed)
507  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
508  else
509  {
510  mutt_make_string(prefix, sizeof(prefix), 0, NONULL(C_IndentString),
511  Context, Context->mailbox, e_parent);
512  }
513  }
514 
515  include_header(C_ForwardQuote, fp_parent, e_parent, fp_tmp, prefix);
516 
517  /* Now, we have prepared the first part of the message body: The
518  * original message's header.
519  *
520  * The next part is more interesting: either include the message bodies,
521  * or attach them. */
522  if ((!cur || mutt_can_decode(cur)) &&
523  ((ans = query_quadoption(C_MimeForward, _("Forward as attachments?"))) == MUTT_YES))
524  {
525  mime_fwd_all = true;
526  }
527  else if (ans == MUTT_ABORT)
528  {
529  goto bail;
530  }
531 
532  /* shortcut MIMEFWDREST when there is only one attachment.
533  * Is this intuitive? */
534  if (!mime_fwd_all && !cur && (nattach > 1) && !check_can_decode(actx, cur))
535  {
536  ans = query_quadoption(
538  _("Can't decode all tagged attachments. MIME-forward the others?"));
539  if (ans == MUTT_ABORT)
540  goto bail;
541  else if (ans == MUTT_NO)
542  mime_fwd_any = false;
543  }
544 
545  /* initialize a state structure */
546 
547  struct State st = { 0 };
548  if (C_ForwardQuote)
549  st.prefix = prefix;
550  st.flags = MUTT_CHARCONV;
551  if (C_Weed)
552  st.flags |= MUTT_WEED;
553  st.fp_out = fp_tmp;
554 
555  /* where do we append new MIME parts? */
556  struct Body **last = &e_tmp->content;
557 
558  if (cur)
559  {
560  /* single body case */
561 
562  if (!mime_fwd_all && mutt_can_decode(cur))
563  {
564  st.fp_in = fp;
565  mutt_body_handler(cur, &st);
566  state_putc(&st, '\n');
567  }
568  else
569  {
570  if (mutt_body_copy(fp, last, cur) == -1)
571  goto bail;
572  }
573  }
574  else
575  {
576  /* multiple body case */
577 
578  if (!mime_fwd_all)
579  {
580  for (int i = 0; i < actx->idxlen; i++)
581  {
582  if (actx->idx[i]->content->tagged && mutt_can_decode(actx->idx[i]->content))
583  {
584  st.fp_in = actx->idx[i]->fp;
585  mutt_body_handler(actx->idx[i]->content, &st);
586  state_putc(&st, '\n');
587  }
588  }
589  }
590 
591  if (mime_fwd_any && !copy_problematic_attachments(last, actx, mime_fwd_all))
592  goto bail;
593  }
594 
595  mutt_forward_trailer(Context->mailbox, e_parent, fp_tmp);
596 
597  mutt_file_fclose(&fp_tmp);
598  fp_tmp = NULL;
599 
600  /* now that we have the template, send it. */
601  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
602  emaillist_add_email(&el, e_parent);
603  ci_send_message(SEND_NO_FLAGS, e_tmp, mutt_b2s(tmpbody), NULL, &el);
604  emaillist_clear(&el);
605  mutt_buffer_pool_release(&tmpbody);
606  return;
607 
608 bail:
609  if (fp_tmp)
610  {
611  mutt_file_fclose(&fp_tmp);
612  mutt_file_unlink(mutt_b2s(tmpbody));
613  }
614  mutt_buffer_pool_release(&tmpbody);
615 
616  email_free(&e_tmp);
617 }
The "current" mailbox.
Definition: context.h:37
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
#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:37
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:400
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:116
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:136
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:144
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
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:430
String manipulation buffer.
Definition: buffer.h:33
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:87
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Mailbox * mailbox
Definition: context.h:51
WHERE unsigned char C_MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:183
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
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
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
#define mutt_b2s(buf)
Definition: buffer.h:41
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:368
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1753
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:773
#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:1893
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:449
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:435
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:254
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:123
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
WHERE bool C_ForwardQuote
Config: Automatically quote a forwarded message using C_IndentString.
Definition: globals.h:215
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *e)
Create a subject for a forwarded email.
Definition: send.c:938
Keep track when processing files.
Definition: state.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1550
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
#define state_putc(STATE, STR)
Definition: state.h:56
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:588
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:36
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:

◆ attach_forward_msgs()

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 633 of file recvcmd.c.

635 {
636  struct Email *e_cur = NULL;
637  struct Email *e_tmp = NULL;
638  enum QuadOption ans;
639  struct Body **last = NULL;
640  struct Buffer *tmpbody = NULL;
641  FILE *fp_tmp = NULL;
642 
643  CopyHeaderFlags chflags = CH_XMIT;
644 
645  if (cur)
646  e_cur = cur->email;
647  else
648  {
649  for (short i = 0; i < actx->idxlen; i++)
650  {
651  if (actx->idx[i]->content->tagged)
652  {
653  e_cur = actx->idx[i]->content->email;
654  break;
655  }
656  }
657  }
658 
659  e_tmp = email_new();
660  e_tmp->env = mutt_env_new();
661  mutt_make_forward_subject(e_tmp->env, Context->mailbox, e_cur);
662 
663  tmpbody = mutt_buffer_pool_get();
664 
665  ans = query_quadoption(C_MimeForward, _("Forward MIME encapsulated?"));
666  if (ans == MUTT_NO)
667  {
668  /* no MIME encapsulation */
669 
670  mutt_buffer_mktemp(tmpbody);
671  fp_tmp = mutt_file_fopen(mutt_b2s(tmpbody), "w");
672  if (!fp_tmp)
673  {
674  mutt_error(_("Can't create %s"), mutt_b2s(tmpbody));
675  goto cleanup;
676  }
677 
679  if (C_ForwardQuote)
680  {
681  chflags |= CH_PREFIX;
682  cmflags |= MUTT_CM_PREFIX;
683  }
684 
685  if (C_ForwardDecode)
686  {
687  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
688  if (C_Weed)
689  {
690  chflags |= CH_WEED | CH_REORDER;
691  cmflags |= MUTT_CM_WEED;
692  }
693  }
694 
695  if (cur)
696  {
697  mutt_forward_intro(Context->mailbox, cur->email, fp_tmp);
698  mutt_copy_message_fp(fp_tmp, fp, cur->email, cmflags, chflags, 0);
699  mutt_forward_trailer(Context->mailbox, cur->email, fp_tmp);
700  }
701  else
702  {
703  for (short i = 0; i < actx->idxlen; i++)
704  {
705  if (actx->idx[i]->content->tagged)
706  {
707  mutt_forward_intro(Context->mailbox, actx->idx[i]->content->email, fp_tmp);
708  mutt_copy_message_fp(fp_tmp, actx->idx[i]->fp,
709  actx->idx[i]->content->email, cmflags, chflags, 0);
710  mutt_forward_trailer(Context->mailbox, actx->idx[i]->content->email, fp_tmp);
711  }
712  }
713  }
714  mutt_file_fclose(&fp_tmp);
715  }
716  else if (ans == MUTT_YES) /* do MIME encapsulation - we don't need to do much here */
717  {
718  last = &e_tmp->content;
719  if (cur)
720  mutt_body_copy(fp, last, cur);
721  else
722  {
723  for (short i = 0; i < actx->idxlen; i++)
724  {
725  if (actx->idx[i]->content->tagged)
726  {
727  mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content);
728  last = &((*last)->next);
729  }
730  }
731  }
732  }
733  else
734  email_free(&e_tmp);
735 
736  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
737  emaillist_add_email(&el, e_cur);
738  ci_send_message(flags, e_tmp,
739  mutt_buffer_is_empty(tmpbody) ? NULL : mutt_b2s(tmpbody), NULL, &el);
740  emaillist_clear(&el);
741  e_tmp = NULL; /* ci_send_message frees this */
742 
743 cleanup:
744  email_free(&e_tmp);
745  mutt_buffer_pool_release(&tmpbody);
746 }
The "current" mailbox.
Definition: context.h:37
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:214
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:144
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:430
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
String manipulation buffer.
Definition: buffer.h:33
#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:51
WHERE unsigned char C_MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:183
#define CH_WEED
Weed the headers?
Definition: copy.h:52
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
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
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
#define mutt_b2s(buf)
Definition: buffer.h:41
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#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:1893
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:449
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:123
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:215
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *e)
Create a subject for a forwarded email.
Definition: send.c:938
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
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:598
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
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:36
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:

◆ mutt_attach_forward()

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 756 of file recvcmd.c.

758 {
759  if (check_all_msg(actx, cur, false))
760  attach_forward_msgs(fp, actx, cur, flags);
761  else
762  {
763  const short nattach = count_tagged(actx);
764  attach_forward_bodies(fp, e, actx, cur, nattach);
765  }
766 }
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:633
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:460
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_reply_envelope_defaults()

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 787 of file recvcmd.c.

789 {
790  struct Envelope *curenv = NULL;
791  struct Email *e = NULL;
792 
793  if (!parent)
794  {
795  for (short i = 0; i < actx->idxlen; i++)
796  {
797  if (actx->idx[i]->content->tagged)
798  {
799  e = actx->idx[i]->content->email;
800  curenv = e->env;
801  break;
802  }
803  }
804  }
805  else
806  {
807  curenv = parent->env;
808  e = parent;
809  }
810 
811  if (!curenv || !e)
812  {
813  mutt_error(_("Can't find any tagged messages"));
814  return -1;
815  }
816 
817 #ifdef USE_NNTP
818  if ((flags & SEND_NEWS))
819  {
820  /* in case followup set Newsgroups: with Followup-To: if it present */
821  if (!env->newsgroups && curenv &&
822  (mutt_str_strcasecmp(curenv->followup_to, "poster") != 0))
823  {
824  env->newsgroups = mutt_str_strdup(curenv->followup_to);
825  }
826  }
827  else
828 #endif
829  {
830  if (parent)
831  {
832  if (mutt_fetch_recips(env, curenv, flags) == -1)
833  return -1;
834  }
835  else
836  {
837  for (short i = 0; i < actx->idxlen; i++)
838  {
839  if (actx->idx[i]->content->tagged &&
840  (mutt_fetch_recips(env, actx->idx[i]->content->email->env, flags) == -1))
841  {
842  return -1;
843  }
844  }
845  }
846 
847  if ((flags & SEND_LIST_REPLY) && TAILQ_EMPTY(&env->to))
848  {
849  mutt_error(_("No mailing lists found"));
850  return -1;
851  }
852 
854  }
855  mutt_make_misc_reply_headers(env, curenv);
856 
857  if (parent)
858  mutt_add_to_reference_headers(env, curenv);
859  else
860  {
861  for (short i = 0; i < actx->idxlen; i++)
862  {
863  if (actx->idx[i]->content->tagged)
865  }
866  }
867 
868  return 0;
869 }
void mutt_fix_reply_recipients(struct Envelope *env)
Remove duplicate recipients.
Definition: send.c:911
The envelope/body of an email.
Definition: email.h:37
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:828
#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:955
short idxlen
Number of attachmentes.
Definition: attach.h:55
struct Envelope * env
Envelope information.
Definition: email.h:89
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
bool tagged
This attachment is tagged.
Definition: body.h:70
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
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:651
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
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:977
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_include_reply()

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 877 of file recvcmd.c.

878 {
880  CopyHeaderFlags chflags = CH_DECODE;
881 
883 
884  if (!C_Header)
885  cmflags |= MUTT_CM_NOHEADER;
886  if (C_Weed)
887  {
888  chflags |= CH_WEED;
889  cmflags |= MUTT_CM_WEED;
890  }
891 
892  mutt_copy_message_fp(fp_tmp, fp, e, cmflags, chflags, 0);
894 }
The "current" mailbox.
Definition: context.h:37
#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:666
struct Mailbox * mailbox
Definition: context.h:51
#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:216
#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
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:598
#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:647
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_attach_reply()

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 904 of file recvcmd.c.

906 {
907  bool mime_reply_any = false;
908 
909  short nattach = 0;
910  struct AttachPtr *parent = NULL;
911  struct Email *e_parent = NULL;
912  FILE *fp_parent = NULL;
913  struct Email *e_tmp = NULL;
914  FILE *fp_tmp = NULL;
915  struct Buffer *tmpbody = NULL;
916 
917  char prefix[128];
918 
919 #ifdef USE_NNTP
920  if (flags & SEND_NEWS)
921  OptNewsSend = true;
922  else
923  OptNewsSend = false;
924 #endif
925 
926  if (!check_all_msg(actx, e_cur, false))
927  {
928  nattach = count_tagged(actx);
929  parent = find_parent(actx, e_cur, nattach);
930  if (parent)
931  {
932  e_parent = parent->content->email;
933  fp_parent = parent->fp;
934  }
935  else
936  {
937  e_parent = e;
938  fp_parent = actx->fp_root;
939  }
940  }
941 
942  if ((nattach > 1) && !check_can_decode(actx, e_cur))
943  {
944  const enum QuadOption ans = query_quadoption(
945  C_MimeForwardRest, _("Can't decode all tagged attachments. "
946  "MIME-encapsulate the others?"));
947  if (ans == MUTT_ABORT)
948  return;
949  if (ans == MUTT_YES)
950  mime_reply_any = true;
951  }
952  else if (nattach == 1)
953  mime_reply_any = true;
954 
955  e_tmp = email_new();
956  e_tmp->env = mutt_env_new();
957 
959  e_tmp->env, actx, e_parent ? e_parent : (e_cur ? e_cur->email : NULL), flags) == -1)
960  {
961  goto cleanup;
962  }
963 
964  tmpbody = mutt_buffer_pool_get();
965  mutt_buffer_mktemp(tmpbody);
966  fp_tmp = mutt_file_fopen(mutt_b2s(tmpbody), "w");
967  if (!fp_tmp)
968  {
969  mutt_error(_("Can't create %s"), mutt_b2s(tmpbody));
970  goto cleanup;
971  }
972 
973  if (!e_parent)
974  {
975  if (e_cur)
976  attach_include_reply(fp, fp_tmp, e_cur->email);
977  else
978  {
979  for (short i = 0; i < actx->idxlen; i++)
980  {
981  if (actx->idx[i]->content->tagged)
982  attach_include_reply(actx->idx[i]->fp, fp_tmp, actx->idx[i]->content->email);
983  }
984  }
985  }
986  else
987  {
988  mutt_make_attribution(Context->mailbox, e_parent, fp_tmp);
989 
990  struct State st;
991  memset(&st, 0, sizeof(struct State));
992  st.fp_out = fp_tmp;
993 
994  if (C_TextFlowed)
995  {
996  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
997  }
998  else
999  {
1000  mutt_make_string(prefix, sizeof(prefix), 0, NONULL(C_IndentString),
1001  Context, Context->mailbox, e_parent);
1002  }
1003 
1004  st.prefix = prefix;
1005  st.flags = MUTT_CHARCONV;
1006 
1007  if (C_Weed)
1008  st.flags |= MUTT_WEED;
1009 
1010  if (C_Header)
1011  include_header(true, fp_parent, e_parent, fp_tmp, prefix);
1012 
1013  if (e_cur)
1014  {
1015  if (mutt_can_decode(e_cur))
1016  {
1017  st.fp_in = fp;
1018  mutt_body_handler(e_cur, &st);
1019  state_putc(&st, '\n');
1020  }
1021  else
1022  mutt_body_copy(fp, &e_tmp->content, e_cur);
1023  }
1024  else
1025  {
1026  for (short i = 0; i < actx->idxlen; i++)
1027  {
1028  if (actx->idx[i]->content->tagged && mutt_can_decode(actx->idx[i]->content))
1029  {
1030  st.fp_in = actx->idx[i]->fp;
1031  mutt_body_handler(actx->idx[i]->content, &st);
1032  state_putc(&st, '\n');
1033  }
1034  }
1035  }
1036 
1037  mutt_make_post_indent(Context->mailbox, e_parent, fp_tmp);
1038 
1039  if (mime_reply_any && !e_cur &&
1040  !copy_problematic_attachments(&e_tmp->content, actx, false))
1041  {
1042  goto cleanup;
1043  }
1044  }
1045 
1046  mutt_file_fclose(&fp_tmp);
1047 
1048  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1049  emaillist_add_email(&el, e_parent ? e_parent : (e_cur ? e_cur->email : NULL));
1050  if (ci_send_message(flags, e_tmp, mutt_b2s(tmpbody), NULL, &el) == 0)
1051  {
1053  }
1054  e_tmp = NULL; /* ci_send_message frees this */
1055 
1056 cleanup:
1057  if (fp_tmp)
1058  {
1059  mutt_file_fclose(&fp_tmp);
1060  mutt_file_unlink(mutt_b2s(tmpbody));
1061  }
1062  mutt_buffer_pool_release(&tmpbody);
1063  email_free(&e_tmp);
1064  emaillist_clear(&el);
1065 }
The "current" mailbox.
Definition: context.h:37
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
#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:70
The envelope/body of an email.
Definition: email.h:37
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:400
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:116
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
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:877
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:136
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:144
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
String manipulation buffer.
Definition: buffer.h:33
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:666
Messages that have been replied to.
Definition: mutt.h:93
struct Mailbox * mailbox
Definition: context.h:51
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
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
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:216
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:368
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1753
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:773
#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:102
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:1893
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:435
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:254
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:123
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
Keep track when processing files.
Definition: state.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1550
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
#define state_putc(STATE, STR)
Definition: state.h:56
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:787
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
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:588
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:36
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:647
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

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

Definition at line 1074 of file recvcmd.c.

1076 {
1077  if (!check_all_msg(actx, cur, 0))
1078  {
1079  /* L10N: You will see this error message if you invoke <compose-to-sender>
1080  when you are on a normal attachment. */
1081  mutt_error(_("You may only compose to sender with message/rfc822 parts"));
1082  return;
1083  }
1084 
1085  struct Email *e_tmp = email_new();
1086  e_tmp->env = mutt_env_new();
1087 
1088  if (cur)
1089  {
1090  if (mutt_fetch_recips(e_tmp->env, cur->email->env, SEND_TO_SENDER) == -1)
1091  {
1092  email_free(&e_tmp);
1093  return;
1094  }
1095  }
1096  else
1097  {
1098  for (int i = 0; i < actx->idxlen; i++)
1099  {
1100  if (actx->idx[i]->content->tagged &&
1101  (mutt_fetch_recips(e_tmp->env, actx->idx[i]->content->email->env,
1102  SEND_TO_SENDER) == -1))
1103  {
1104  email_free(&e_tmp);
1105  return;
1106  }
1107  }
1108  }
1109 
1110  // This call will free e_tmp for us
1111  ci_send_message(SEND_NO_FLAGS, e_tmp, NULL, NULL, NULL);
1112 }
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:100
The envelope/body of an email.
Definition: email.h:37
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:828
#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:87
struct Envelope * env
Envelope information.
Definition: email.h:89
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
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:1893
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
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_MimeForwardRest

unsigned char C_MimeForwardRest

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

Definition at line 60 of file recvcmd.c.