NeoMutt  2018-07-16 +952-a2da0a
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 "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 (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)
 forward-message, from the attachment menu 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 *ifp, struct Email *e, FILE *ofp, 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, int flags)
 Forward one or several message-type attachments. More...
 
void mutt_attach_forward (FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, int flags)
 Forward an Attachment. More...
 
static int attach_reply_envelope_defaults (struct Envelope *env, struct AttachCtx *actx, struct Email *parent, int flags)
 the various reply functions, from the attachment menu More...
 
static void attach_include_reply (FILE *fp, FILE *tmpfp, struct Email *cur)
 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 *cur, int 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 MimeForwardRest
 Config: Forward all attachments, even if they can't be decoded. More...
 

Detailed Description

Send/reply with an attachment.

Authors
  • Thomas Roessler

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

71 {
72  if (!mutt_is_message_type(b->type, b->subtype))
73  {
74  if (err)
75  mutt_error(_("You may only bounce message/rfc822 parts"));
76  return false;
77  }
78  return true;
79 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1214
#define _(a)
Definition: message.h:28
char * subtype
content-type subtype
Definition: body.h:36
unsigned int type
content-type primary type
Definition: body.h:67
#define mutt_error(...)
Definition: logging.h:88

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

89 {
90  if (cur && !check_msg(cur, err))
91  return false;
92  else if (!cur)
93  {
94  for (short i = 0; i < actx->idxlen; i++)
95  {
96  if (actx->idx[i]->content->tagged)
97  {
98  if (!check_msg(actx->idx[i]->content, err))
99  return false;
100  }
101  }
102  }
103  return true;
104 }
static bool check_msg(struct Body *b, bool err)
Are we working with an RFC822 message.
Definition: recvcmd.c:70
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
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 112 of file recvcmd.c.

113 {
114  if (cur)
115  return mutt_can_decode(cur);
116 
117  for (short i = 0; i < actx->idxlen; i++)
118  if (actx->idx[i]->content->tagged && !mutt_can_decode(actx->idx[i]->content))
119  return false;
120 
121  return true;
122 }
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
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 129 of file recvcmd.c.

130 {
131  short count = 0;
132  for (short i = 0; i < actx->idxlen; i++)
133  if (actx->idx[i]->content->tagged)
134  count++;
135 
136  return count;
137 }
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
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 145 of file recvcmd.c.

146 {
147  short level = actx->idx[i]->level;
148  short count = 0;
149 
150  while ((++i < actx->idxlen) && (level < actx->idx[i]->level))
151  if (actx->idx[i]->content->tagged)
152  count++;
153 
154  return count;
155 }
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
struct Body * content
Definition: attach.h:36
int level
Definition: attach.h:40
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the caller graph for this function:

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

Bounce function, from the attachment menu.

Parameters
fpHandle of message
actxAttachment context
curBody of email

Definition at line 163 of file recvcmd.c.

164 {
165  char prompt[STRING];
166  char buf[HUGE_STRING];
167  char *err = NULL;
168  struct Address *addr = NULL;
169  int ret = 0;
170  int p = 0;
171 
172  if (!check_all_msg(actx, cur, true))
173  return;
174 
175  /* one or more messages? */
176  p = cur ? 1 : count_tagged(actx);
177 
178  /* RFC5322 mandates a From: header, so warn before bouncing
179  * messages without one */
180  if (cur)
181  {
182  if (!cur->email->env->from)
183  {
184  mutt_error(_("Warning: message contains no From: header"));
186  }
187  }
188  else
189  {
190  for (short i = 0; i < actx->idxlen; i++)
191  {
192  if (actx->idx[i]->content->tagged)
193  {
194  if (!actx->idx[i]->content->email->env->from)
195  {
196  mutt_error(_("Warning: message contains no From: header"));
198  break;
199  }
200  }
201  }
202  }
203 
204  if (p)
205  mutt_str_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
206  else
207  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
208 
209  buf[0] = '\0';
210  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS) || buf[0] == '\0')
211  return;
212 
213  addr = mutt_addr_parse_list(addr, buf);
214  if (!addr)
215  {
216  mutt_error(_("Error parsing address"));
217  return;
218  }
219 
220  addr = mutt_expand_aliases(addr);
221 
222  if (mutt_addrlist_to_intl(addr, &err) < 0)
223  {
224  mutt_error(_("Bad IDN: '%s'"), err);
225  FREE(&err);
226  mutt_addr_free(&addr);
227  return;
228  }
229 
230  buf[0] = 0;
231  mutt_addr_write(buf, sizeof(buf), addr, true);
232 
233 #define EXTRA_SPACE (15 + 7 + 2)
234  /* See commands.c. */
235  snprintf(prompt, sizeof(prompt) - 4,
236  ngettext("Bounce message to %s", "Bounce messages to %s", p), buf);
237 
239  {
240  mutt_simple_format(prompt, sizeof(prompt) - 4, 0, MuttMessageWindow->cols - EXTRA_SPACE,
241  FMT_LEFT, 0, prompt, sizeof(prompt), 0);
242  mutt_str_strcat(prompt, sizeof(prompt), "...?");
243  }
244  else
245  mutt_str_strcat(prompt, sizeof(prompt), "?");
246 
247  if (query_quadoption(Bounce, prompt) != MUTT_YES)
248  {
249  mutt_addr_free(&addr);
251  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
252  return;
253  }
254 
256 
257  if (cur)
258  ret = mutt_bounce_message(fp, cur->email, addr);
259  else
260  {
261  for (short i = 0; i < actx->idxlen; i++)
262  {
263  if (actx->idx[i]->content->tagged)
264  if (mutt_bounce_message(actx->idx[i]->fp, actx->idx[i]->content->email, addr))
265  ret = 1;
266  }
267  }
268 
269  if (!ret)
270  mutt_message(ngettext("Message bounced", "Messages bounced", p));
271  else
272  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
273 
274  mutt_addr_free(&addr);
275 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:88
int mutt_bounce_message(FILE *fp, struct Email *e, struct Address *to)
Bounce an email message.
Definition: sendlib.c:3039
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, int justify, char pad_char, const char *s, size_t n, int arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:911
#define MUTT_ALIAS
do alias "completion" by calling up the alias-menu
Definition: mutt.h:58
#define mutt_message(...)
Definition: logging.h:87
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define FMT_LEFT
Definition: curs_lib.h:41
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
An email address.
Definition: address.h:32
int mutt_addrlist_to_intl(struct Address *a, char **err)
Convert an Address list to Punycode.
Definition: address.c:1208
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1146
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
struct Envelope * env
envelope information
Definition: email.h:91
bool tagged
Definition: body.h:74
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
struct Address * from
Definition: envelope.h:35
#define HUGE_STRING
Definition: string2.h:37
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1176
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
struct Address * mutt_addr_parse_list(struct Address *top, const char *s)
Parse a list of email addresses.
Definition: address.c:465
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:742
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:129
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:402
#define STRING
Definition: string2.h:35
struct Address * mutt_expand_aliases(struct Address *a)
Expand aliases in a List of Addresses.
Definition: alias.c:296
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
WHERE unsigned char Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:185
#define EXTRA_SPACE
#define FREE(x)
Definition: memory.h:46
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:446
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
Definition: attach.h:54

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

284 {
285  if (!check_all_msg(actx, cur, true))
286  return;
287 
288  if (cur)
289  mutt_resend_message(fp, Context, cur->email);
290  else
291  {
292  for (short i = 0; i < actx->idxlen; i++)
293  if (actx->idx[i]->content->tagged)
294  mutt_resend_message(actx->idx[i]->fp, Context, actx->idx[i]->content->email);
295  }
296 }
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:88
short idxlen
Definition: attach.h:55
int mutt_resend_message(FILE *fp, struct Context *ctx, struct Email *cur)
Resend an email.
Definition: send.c:1430
bool tagged
Definition: body.h:74
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Definition: attach.h:36
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
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

forward-message, from the attachment menu

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

310 {
311  short i;
312  short nchildren;
313 
314  for (i = 0; i < actx->idxlen; i++)
315  if (actx->idx[i]->content->tagged)
316  break;
317 
318  while (--i >= 0)
319  {
320  if (mutt_is_message_type(actx->idx[i]->content->type, actx->idx[i]->content->subtype))
321  {
322  nchildren = count_tagged_children(actx, i);
323  if (nchildren == nattach)
324  return actx->idx[i];
325  }
326  }
327 
328  return NULL;
329 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1214
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
char * subtype
content-type subtype
Definition: body.h:36
unsigned int type
content-type primary type
Definition: body.h:67
struct Body * content
Definition: attach.h:36
static short count_tagged_children(struct AttachCtx *actx, short i)
tagged children below a multipart/message attachment
Definition: recvcmd.c:145
struct AttachPtr ** idx
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 343 of file recvcmd.c.

344 {
345  short level = actx->idx[i]->level;
346 
347  while ((++i < actx->idxlen) && actx->idx[i]->level > level)
348  {
349  if (actx->idx[i]->content == cur)
350  return true;
351  }
352 
353  return false;
354 }
struct Body * content
Definition: attach.h:36
int level
Definition: attach.h:40
struct AttachPtr ** idx
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 364 of file recvcmd.c.

365 {
366  struct AttachPtr *parent = NULL;
367 
368  if (cur)
369  {
370  for (short i = 0; i < actx->idxlen; i++)
371  {
372  if (mutt_is_message_type(actx->idx[i]->content->type,
373  actx->idx[i]->content->subtype) &&
374  is_parent(i, actx, cur))
375  {
376  parent = actx->idx[i];
377  }
378  if (actx->idx[i]->content == cur)
379  break;
380  }
381  }
382  else if (nattach)
383  parent = find_common_parent(actx, nattach);
384 
385  return parent;
386 }
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:1214
short idxlen
Definition: attach.h:55
char * subtype
content-type subtype
Definition: body.h:36
static int is_parent(short i, struct AttachCtx *actx, struct Body *cur)
Check whether one attachment is the parent of another.
Definition: recvcmd.c:343
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
forward-message, from the attachment menu
Definition: recvcmd.c:309
unsigned int type
content-type primary type
Definition: body.h:67
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
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 *  ifp,
struct Email e,
FILE *  ofp,
char *  prefix 
)
static

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

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

Definition at line 396 of file recvcmd.c.

397 {
398  int chflags = CH_DECODE;
399  char prefix2[SHORT_STRING];
400 
401  if (Weed)
402  chflags |= CH_WEED | CH_REORDER;
403 
404  if (quote)
405  {
406  if (prefix)
407  mutt_str_strfcpy(prefix2, prefix, sizeof(prefix2));
408  else if (!TextFlowed)
409  {
410  mutt_make_string_flags(prefix2, sizeof(prefix2), NONULL(IndentString),
411  Context, e, 0);
412  }
413  else
414  mutt_str_strfcpy(prefix2, ">", sizeof(prefix2));
415 
416  chflags |= CH_PREFIX;
417  }
418 
419  mutt_copy_header(ifp, e, ofp, chflags, quote ? prefix2 : NULL);
420 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:39
#define SHORT_STRING
Definition: string2.h:34
int mutt_copy_header(FILE *in, struct Email *e, FILE *out, int flags, const char *prefix)
Copy Email header.
Definition: copy.c:406
WHERE bool TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:259
#define CH_WEED
weed the headers?
Definition: copy.h:48
bool Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:38
#define CH_REORDER
Re-order output of headers.
Definition: copy.h:54
#define CH_DECODE
do RFC1522 decoding?
Definition: copy.h:49
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:742
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Email *e, enum FormatFlag flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1454
#define CH_PREFIX
use IndentString string?
Definition: copy.h:52
WHERE char * IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:138

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

433 {
434  for (short i = 0; i < actx->idxlen; i++)
435  {
436  if (actx->idx[i]->content->tagged && (force || !mutt_can_decode(actx->idx[i]->content)))
437  {
438  if (mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content) == -1)
439  return NULL; /* XXXXX - may lead to crashes */
440  last = &((*last)->next);
441  }
442  }
443  return last;
444 }
short idxlen
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
Definition: body.h:74
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
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 456 of file recvcmd.c.

458 {
459  bool mime_fwd_all = false;
460  bool mime_fwd_any = true;
461  struct Email *parent_hdr = NULL;
462  FILE *parent_fp = NULL;
463  char tmpbody[PATH_MAX];
464  char prefix[STRING];
465  int rc = 0;
466 
467  /* First, find the parent message.
468  * Note: This could be made an option by just
469  * putting the following lines into an if block.
470  */
471  struct AttachPtr *parent = find_parent(actx, cur, nattach);
472  if (parent)
473  {
474  parent_hdr = parent->content->email;
475  parent_fp = parent->fp;
476  }
477  else
478  {
479  parent_hdr = e;
480  parent_fp = actx->root_fp;
481  }
482 
483  struct Email *tmphdr = mutt_email_new();
484  tmphdr->env = mutt_env_new();
485  mutt_make_forward_subject(tmphdr->env, Context, parent_hdr);
486 
487  mutt_mktemp(tmpbody, sizeof(tmpbody));
488  FILE *tmpfp = mutt_file_fopen(tmpbody, "w");
489  if (!tmpfp)
490  {
491  mutt_error(_("Can't open temporary file %s"), tmpbody);
492  mutt_email_free(&tmphdr);
493  return;
494  }
495 
496  mutt_forward_intro(Context, parent_hdr, tmpfp);
497 
498  /* prepare the prefix here since we'll need it later. */
499 
500  if (ForwardQuote)
501  {
502  if (!TextFlowed)
503  {
504  mutt_make_string_flags(prefix, sizeof(prefix), NONULL(IndentString),
505  Context, parent_hdr, 0);
506  }
507  else
508  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
509  }
510 
511  include_header(ForwardQuote, parent_fp, parent_hdr, tmpfp, prefix);
512 
513  /* Now, we have prepared the first part of the message body: The
514  * original message's header.
515  *
516  * The next part is more interesting: either include the message bodies,
517  * or attach them.
518  */
519  if ((!cur || mutt_can_decode(cur)) &&
520  (rc = query_quadoption(MimeForward, _("Forward as attachments?"))) == MUTT_YES)
521  {
522  mime_fwd_all = true;
523  }
524  else if (rc == -1)
525  {
526  goto bail;
527  }
528 
529  /* shortcut MIMEFWDREST when there is only one attachment.
530  * Is this intuitive?
531  */
532  if (!mime_fwd_all && !cur && (nattach > 1) && !check_can_decode(actx, cur))
533  {
534  rc = query_quadoption(
536  _("Can't decode all tagged attachments. MIME-forward the others?"));
537  if (rc == MUTT_ABORT)
538  goto bail;
539  else if (rc == MUTT_NO)
540  mime_fwd_any = false;
541  }
542 
543  /* initialize a state structure */
544 
545  struct State st = { 0 };
546  if (ForwardQuote)
547  st.prefix = prefix;
548  st.flags = MUTT_CHARCONV;
549  if (Weed)
550  st.flags |= MUTT_WEED;
551  st.fpout = tmpfp;
552 
553  /* where do we append new MIME parts? */
554  struct Body **last = &tmphdr->content;
555 
556  if (cur)
557  {
558  /* single body case */
559 
560  if (!mime_fwd_all && mutt_can_decode(cur))
561  {
562  st.fpin = 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.fpin = 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, parent_hdr, tmpfp);
594 
595  mutt_file_fclose(&tmpfp);
596  tmpfp = NULL;
597 
598  /* now that we have the template, send it. */
599  ci_send_message(0, tmphdr, tmpbody, NULL, parent_hdr);
600  return;
601 
602 bail:
603 
604  if (tmpfp)
605  {
606  mutt_file_fclose(&tmpfp);
607  mutt_file_unlink(tmpbody);
608  }
609 
610  mutt_email_free(&tmphdr);
611 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:39
An email to which things will be attached.
Definition: attach.h:34
The envelope/body of an email.
Definition: email.h:35
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:112
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:44
User aborted the question (with Ctrl-G)
Definition: quad.h:37
unsigned char MimeForwardRest
Config: Forward all attachments, even if they can&#39;t be decoded.
Definition: recvcmd.c:59
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void mutt_forward_trailer(struct Context *ctx, struct Email *cur, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:520
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:192
char * prefix
Definition: state.h:35
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
void mutt_make_forward_subject(struct Envelope *env, struct Context *ctx, struct Email *cur)
Create a subject for a forwarded email.
Definition: send.c:854
void mutt_forward_intro(struct Context *ctx, struct Email *cur, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:501
The body of an email.
Definition: body.h:33
WHERE bool TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:259
FILE * fpout
Definition: state.h:34
#define state_putc(x, y)
Definition: state.h:52
int flags
Definition: state.h:36
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:48
bool Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:38
bool tagged
Definition: body.h:74
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
static void include_header(bool quote, FILE *ifp, struct Email *e, FILE *ofp, char *prefix)
Write an email header to a file, optionally quoting it.
Definition: recvcmd.c:396
#define mutt_mktemp(a, b)
Definition: muttlib.h:71
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:364
#define PATH_MAX
Definition: mutt.h:46
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
FILE * root_fp
used by recvattach for updating
Definition: attach.h:52
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:742
#define MUTT_WEED
weed headers even when not in display mode
Definition: state.h:43
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
FILE * fpin
Definition: state.h:33
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:548
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:431
WHERE unsigned char MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:188
#define STRING
Definition: string2.h:35
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_error(...)
Definition: logging.h:88
int ci_send_message(int flags, struct Email *msg, char *tempfile, struct Context *ctx, struct Email *cur)
Send an email.
Definition: send.c:1530
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Email *e, enum FormatFlag flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1454
Keep track when processing files.
Definition: state.h:31
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1502
WHERE bool ForwardQuote
Config: Automatically quote a forwarded message using IndentString.
Definition: globals.h:215
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
Definition: attach.h:54
WHERE char * IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:138

+ 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,
int  flags 
)
static

Forward one or several message-type attachments.

Parameters
fpFile handle to attachment
actxAttachment Context
curAttachment to forward (OPTIONAL)
flagsSend mode, e.g. SEND_RESEND

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 - ci_send_message relies on a context structure to find messages, while, on the attachment menu, messages are referenced through the attachment index.

Definition at line 627 of file recvcmd.c.

628 {
629  struct Email *curhdr = NULL;
630  struct Email *tmphdr = NULL;
631  int rc;
632 
633  struct Body **last = NULL;
634  char tmpbody[PATH_MAX];
635  FILE *tmpfp = NULL;
636 
637  int chflags = CH_XMIT;
638 
639  if (cur)
640  curhdr = cur->email;
641  else
642  {
643  for (short i = 0; i < actx->idxlen; i++)
644  {
645  if (actx->idx[i]->content->tagged)
646  {
647  curhdr = actx->idx[i]->content->email;
648  break;
649  }
650  }
651  }
652 
653  tmphdr = mutt_email_new();
654  tmphdr->env = mutt_env_new();
655  mutt_make_forward_subject(tmphdr->env, Context, curhdr);
656 
657  tmpbody[0] = '\0';
658 
659  rc = query_quadoption(MimeForward, _("Forward MIME encapsulated?"));
660  if (rc == MUTT_NO)
661  {
662  /* no MIME encapsulation */
663 
664  mutt_mktemp(tmpbody, sizeof(tmpbody));
665  tmpfp = mutt_file_fopen(tmpbody, "w");
666  if (!tmpfp)
667  {
668  mutt_error(_("Can't create %s"), tmpbody);
669  mutt_email_free(&tmphdr);
670  return;
671  }
672 
673  int cmflags = 0;
674  if (ForwardQuote)
675  {
676  chflags |= CH_PREFIX;
677  cmflags |= MUTT_CM_PREFIX;
678  }
679 
680  if (ForwardDecode)
681  {
682  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
683  if (Weed)
684  {
685  chflags |= CH_WEED | CH_REORDER;
686  cmflags |= MUTT_CM_WEED;
687  }
688  }
689 
690  if (cur)
691  {
692  mutt_forward_intro(Context, cur->email, tmpfp);
693  mutt_copy_message_fp(tmpfp, fp, cur->email, cmflags, chflags);
694  mutt_forward_trailer(Context, cur->email, tmpfp);
695  }
696  else
697  {
698  for (short i = 0; i < actx->idxlen; i++)
699  {
700  if (actx->idx[i]->content->tagged)
701  {
702  mutt_forward_intro(Context, actx->idx[i]->content->email, tmpfp);
703  mutt_copy_message_fp(tmpfp, actx->idx[i]->fp,
704  actx->idx[i]->content->email, cmflags, chflags);
705  mutt_forward_trailer(Context, actx->idx[i]->content->email, tmpfp);
706  }
707  }
708  }
709  mutt_file_fclose(&tmpfp);
710  }
711  else if (rc == MUTT_YES) /* do MIME encapsulation - we don't need to do much here */
712  {
713  last = &tmphdr->content;
714  if (cur)
715  mutt_body_copy(fp, last, cur);
716  else
717  {
718  for (short i = 0; i < actx->idxlen; i++)
719  {
720  if (actx->idx[i]->content->tagged)
721  {
722  mutt_body_copy(actx->idx[i]->fp, last, actx->idx[i]->content);
723  last = &((*last)->next);
724  }
725  }
726  }
727  }
728  else
729  mutt_email_free(&tmphdr);
730 
731  ci_send_message(flags, tmphdr, *tmpbody ? tmpbody : NULL, NULL, curhdr);
732 }
The "current" mailbox.
Definition: context.h:36
The envelope/body of an email.
Definition: email.h:35
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
WHERE bool ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:214
void mutt_forward_trailer(struct Context *ctx, struct Email *cur, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:520
struct Body * content
list of MIME parts
Definition: email.h:92
#define MUTT_CM_WEED
weed message/rfc822 attachment headers
Definition: copy.h:37
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
void mutt_make_forward_subject(struct Envelope *env, struct Context *ctx, struct Email *cur)
Create a subject for a forwarded email.
Definition: send.c:854
void mutt_forward_intro(struct Context *ctx, struct Email *cur, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:501
The body of an email.
Definition: body.h:33
#define CH_WEED
weed the headers?
Definition: copy.h:48
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:48
bool Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:38
bool tagged
Definition: body.h:74
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
int mutt_copy_message_fp(FILE *fpout, FILE *fpin, struct Email *e, int flags, int chflags)
make a copy of a message from a FILE pointer
Definition: copy.c:584
#define MUTT_CM_PREFIX
quote the message
Definition: copy.h:33
#define mutt_mktemp(a, b)
Definition: muttlib.h:71
#define PATH_MAX
Definition: mutt.h:46
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
#define MUTT_CM_DECODE
decode the message body into text/plain
Definition: copy.h:34
#define CH_REORDER
Re-order output of headers.
Definition: copy.h:54
#define MUTT_CM_CHARCONV
perform character set conversions
Definition: copy.h:38
#define CH_XMIT
transmitting this message?
Definition: copy.h:50
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:548
WHERE unsigned char MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:188
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_error(...)
Definition: logging.h:88
int ci_send_message(int flags, struct Email *msg, char *tempfile, struct Context *ctx, struct Email *cur)
Send an email.
Definition: send.c:1530
WHERE bool ForwardQuote
Config: Automatically quote a forwarded message using IndentString.
Definition: globals.h:215
struct Email * email
header information for message/rfc822
Definition: body.h:59
#define CH_PREFIX
use IndentString string?
Definition: copy.h:52
struct AttachPtr ** idx
Definition: attach.h:54

+ 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,
int  flags 
)

Forward an Attachment.

Parameters
fpHandle to the attachment
eEmail
actxAttachment Context
curCurrent message
flagsSend mode, e.g. SEND_RESEND

Definition at line 742 of file recvcmd.c.

744 {
745  if (check_all_msg(actx, cur, false))
746  attach_forward_msgs(fp, actx, cur, flags);
747  else
748  {
749  const short nattach = count_tagged(actx);
750  attach_forward_bodies(fp, e, actx, cur, nattach);
751  }
752 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:88
static void attach_forward_msgs(FILE *fp, struct AttachCtx *actx, struct Body *cur, int flags)
Forward one or several message-type attachments.
Definition: recvcmd.c:627
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:129
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:456

+ 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,
int  flags 
)
static

the various reply functions, from the attachment menu

Create the envelope defaults for a reply

Parameters
envEnvelope to fill in
actxAttachment Context
parentParent Email
flagsFlags, e.g. SEND_LIST_REPLY
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 777 of file recvcmd.c.

779 {
780  struct Envelope *curenv = NULL;
781  struct Email *curhdr = NULL;
782 
783  if (!parent)
784  {
785  for (short i = 0; i < actx->idxlen; i++)
786  {
787  if (actx->idx[i]->content->tagged)
788  {
789  curhdr = actx->idx[i]->content->email;
790  curenv = curhdr->env;
791  break;
792  }
793  }
794  }
795  else
796  {
797  curenv = parent->env;
798  curhdr = parent;
799  }
800 
801  if (!curenv || !curhdr)
802  {
803  mutt_error(_("Can't find any tagged messages"));
804  return -1;
805  }
806 
807 #ifdef USE_NNTP
808  if ((flags & SEND_NEWS))
809  {
810  /* in case followup set Newsgroups: with Followup-To: if it present */
811  if (!env->newsgroups && curenv &&
812  (mutt_str_strcasecmp(curenv->followup_to, "poster") != 0))
813  {
814  env->newsgroups = mutt_str_strdup(curenv->followup_to);
815  }
816  }
817  else
818 #endif
819  {
820  if (parent)
821  {
822  if (mutt_fetch_recips(env, curenv, flags) == -1)
823  return -1;
824  }
825  else
826  {
827  for (short i = 0; i < actx->idxlen; i++)
828  {
829  if (actx->idx[i]->content->tagged &&
830  mutt_fetch_recips(env, actx->idx[i]->content->email->env, flags) == -1)
831  {
832  return -1;
833  }
834  }
835  }
836 
837  if ((flags & SEND_LIST_REPLY) && !env->to)
838  {
839  mutt_error(_("No mailing lists found"));
840  return -1;
841  }
842 
844  }
845  mutt_make_misc_reply_headers(env, curenv);
846 
847  if (parent)
848  mutt_add_to_reference_headers(env, curenv);
849  else
850  {
851  for (short i = 0; i < actx->idxlen; i++)
852  {
853  if (actx->idx[i]->content->tagged)
855  }
856  }
857 
858  return 0;
859 }
void mutt_fix_reply_recipients(struct Envelope *env)
Remove duplicate recipients.
Definition: send.c:825
The envelope/body of an email.
Definition: email.h:35
struct Address * to
Definition: envelope.h:36
#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:871
short idxlen
Definition: attach.h:55
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, int flags)
Generate recpients for a reply email.
Definition: send.c:745
struct Envelope * env
envelope information
Definition: email.h:91
#define SEND_LIST_REPLY
Definition: send.h:84
bool tagged
Definition: body.h:74
#define SEND_NEWS
Definition: send.h:95
char * newsgroups
Definition: envelope.h:53
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
char * followup_to
Definition: envelope.h:55
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
Definition: attach.h:54
The header of an email.
Definition: envelope.h:32
void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv)
Generate references for a reply email.
Definition: send.c:894

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void attach_include_reply ( FILE *  fp,
FILE *  tmpfp,
struct Email cur 
)
static

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

Parameters
fpFile handle to attachment
tmpfpFile handle to temporary file
curEmail

Definition at line 867 of file recvcmd.c.

868 {
870  int chflags = CH_DECODE;
871 
872  mutt_make_attribution(Context, cur, tmpfp);
873 
874  if (!Header)
875  cmflags |= MUTT_CM_NOHEADER;
876  if (Weed)
877  {
878  chflags |= CH_WEED;
879  cmflags |= MUTT_CM_WEED;
880  }
881 
882  mutt_copy_message_fp(tmpfp, fp, cur, cmflags, chflags);
883  mutt_make_post_indent(Context, cur, tmpfp);
884 }
The "current" mailbox.
Definition: context.h:36
#define MUTT_CM_WEED
weed message/rfc822 attachment headers
Definition: copy.h:37
void mutt_make_post_indent(struct Context *ctx, struct Email *cur, FILE *out)
Add suffix to replied email text.
Definition: send.c:604
#define CH_WEED
weed the headers?
Definition: copy.h:48
bool Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:38
void mutt_make_attribution(struct Context *ctx, struct Email *cur, FILE *out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:585
int mutt_copy_message_fp(FILE *fpout, FILE *fpin, struct Email *e, int flags, int chflags)
make a copy of a message from a FILE pointer
Definition: copy.c:584
#define MUTT_CM_PREFIX
quote the message
Definition: copy.h:33
#define MUTT_CM_DECODE
decode the message body into text/plain
Definition: copy.h:34
#define MUTT_CM_CHARCONV
perform character set conversions
Definition: copy.h:38
WHERE bool Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:221
#define CH_DECODE
do RFC1522 decoding?
Definition: copy.h:49
#define MUTT_CM_NOHEADER
flags to mutt_copy_message
Definition: copy.h:32

+ 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 cur,
int  flags 
)

Attach a reply.

Parameters
fpFile handle to reply
eEmail
actxAttachment Context
curCurrent message
flagsSend mode, e.g. SEND_RESEND

Definition at line 894 of file recvcmd.c.

896 {
897  bool mime_reply_any = false;
898 
899  short nattach = 0;
900  struct AttachPtr *parent = NULL;
901  struct Email *parent_hdr = NULL;
902  FILE *parent_fp = NULL;
903  struct Email *tmphdr = NULL;
904 
905  struct State st;
906  char tmpbody[PATH_MAX];
907  FILE *tmpfp = NULL;
908 
909  char prefix[SHORT_STRING];
910 
911 #ifdef USE_NNTP
912  if (flags & SEND_NEWS)
913  OptNewsSend = true;
914  else
915  OptNewsSend = false;
916 #endif
917 
918  if (!check_all_msg(actx, cur, false))
919  {
920  nattach = count_tagged(actx);
921  parent = find_parent(actx, cur, nattach);
922  if (parent)
923  {
924  parent_hdr = parent->content->email;
925  parent_fp = parent->fp;
926  }
927  else
928  {
929  parent_hdr = e;
930  parent_fp = actx->root_fp;
931  }
932  }
933 
934  if (nattach > 1 && !check_can_decode(actx, cur))
935  {
936  const int rc = query_quadoption(MimeForwardRest,
937  _("Can't decode all tagged attachments. "
938  "MIME-encapsulate the others?"));
939  if (rc == MUTT_ABORT)
940  return;
941  else if (rc == MUTT_YES)
942  mime_reply_any = true;
943  }
944  else if (nattach == 1)
945  mime_reply_any = true;
946 
947  tmphdr = mutt_email_new();
948  tmphdr->env = mutt_env_new();
949 
951  tmphdr->env, actx, parent_hdr ? parent_hdr : (cur ? cur->email : NULL), flags) == -1)
952  {
953  mutt_email_free(&tmphdr);
954  return;
955  }
956 
957  mutt_mktemp(tmpbody, sizeof(tmpbody));
958  tmpfp = mutt_file_fopen(tmpbody, "w");
959  if (!tmpfp)
960  {
961  mutt_error(_("Can't create %s"), tmpbody);
962  mutt_email_free(&tmphdr);
963  return;
964  }
965 
966  if (!parent_hdr)
967  {
968  if (cur)
969  attach_include_reply(fp, tmpfp, cur->email);
970  else
971  {
972  for (short i = 0; i < actx->idxlen; i++)
973  {
974  if (actx->idx[i]->content->tagged)
975  attach_include_reply(actx->idx[i]->fp, tmpfp, actx->idx[i]->content->email);
976  }
977  }
978  }
979  else
980  {
981  mutt_make_attribution(Context, parent_hdr, tmpfp);
982 
983  memset(&st, 0, sizeof(struct State));
984  st.fpout = tmpfp;
985 
986  if (!TextFlowed)
987  {
988  mutt_make_string_flags(prefix, sizeof(prefix), NONULL(IndentString),
989  Context, parent_hdr, 0);
990  }
991  else
992  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
993 
994  st.prefix = prefix;
995  st.flags = MUTT_CHARCONV;
996 
997  if (Weed)
998  st.flags |= MUTT_WEED;
999 
1000  if (Header)
1001  include_header(true, parent_fp, parent_hdr, tmpfp, prefix);
1002 
1003  if (cur)
1004  {
1005  if (mutt_can_decode(cur))
1006  {
1007  st.fpin = fp;
1008  mutt_body_handler(cur, &st);
1009  state_putc('\n', &st);
1010  }
1011  else
1012  mutt_body_copy(fp, &tmphdr->content, cur);
1013  }
1014  else
1015  {
1016  for (short i = 0; i < actx->idxlen; i++)
1017  {
1018  if (actx->idx[i]->content->tagged && mutt_can_decode(actx->idx[i]->content))
1019  {
1020  st.fpin = actx->idx[i]->fp;
1021  mutt_body_handler(actx->idx[i]->content, &st);
1022  state_putc('\n', &st);
1023  }
1024  }
1025  }
1026 
1027  mutt_make_post_indent(Context, parent_hdr, tmpfp);
1028 
1029  if (mime_reply_any && !cur && !copy_problematic_attachments(&tmphdr->content, actx, false))
1030  {
1031  mutt_email_free(&tmphdr);
1032  mutt_file_fclose(&tmpfp);
1033  return;
1034  }
1035  }
1036 
1037  mutt_file_fclose(&tmpfp);
1038 
1039  if (ci_send_message(flags, tmphdr, tmpbody, NULL,
1040  parent_hdr ? parent_hdr : (cur ? cur->email : NULL)) == 0)
1041  {
1043  }
1044 }
The "current" mailbox.
Definition: context.h:36
#define NONULL(x)
Definition: string2.h:39
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:88
#define SHORT_STRING
Definition: string2.h:34
The envelope/body of an email.
Definition: email.h:35
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:112
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:44
User aborted the question (with Ctrl-G)
Definition: quad.h:37
unsigned char MimeForwardRest
Config: Forward all attachments, even if they can&#39;t be decoded.
Definition: recvcmd.c:59
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
char * prefix
Definition: state.h:35
void mutt_make_post_indent(struct Context *ctx, struct Email *cur, FILE *out)
Add suffix to replied email text.
Definition: send.c:604
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
WHERE bool TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:259
#define state_putc(x, y)
Definition: state.h:52
int flags
Definition: state.h:36
struct Mailbox * mailbox
Definition: context.h:50
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:48
bool Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:38
void mutt_make_attribution(struct Context *ctx, struct Email *cur, FILE *out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:585
bool tagged
Definition: body.h:74
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
Messages that have been replied to.
Definition: mutt.h:115
static void include_header(bool quote, FILE *ifp, struct Email *e, FILE *ofp, char *prefix)
Write an email header to a file, optionally quoting it.
Definition: recvcmd.c:396
#define mutt_mktemp(a, b)
Definition: muttlib.h:71
static struct AttachPtr * find_parent(struct AttachCtx *actx, struct Body *cur, short nattach)
Find the parent of an Attachment.
Definition: recvcmd.c:364
#define PATH_MAX
Definition: mutt.h:46
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
WHERE bool Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:221
FILE * root_fp
used by recvattach for updating
Definition: attach.h:52
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:742
#define MUTT_WEED
weed headers even when not in display mode
Definition: state.h:43
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:129
#define mutt_set_flag(a, b, c, d)
Definition: protos.h:54
#define SEND_NEWS
Definition: send.h:95
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:548
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:431
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_error(...)
Definition: logging.h:88
int ci_send_message(int flags, struct Email *msg, char *tempfile, struct Context *ctx, struct Email *cur)
Send an email.
Definition: send.c:1530
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Email *e, enum FormatFlag flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1454
static int attach_reply_envelope_defaults(struct Envelope *env, struct AttachCtx *actx, struct Email *parent, int flags)
the various reply functions, from the attachment menu
Definition: recvcmd.c:777
Keep track when processing files.
Definition: state.h:31
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1502
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
Definition: attach.h:54
static void attach_include_reply(FILE *fp, FILE *tmpfp, struct Email *cur)
This is very similar to send.c&#39;s include_reply()
Definition: recvcmd.c:867
WHERE char * IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:138

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

1055 {
1056  if (!check_all_msg(actx, cur, 0))
1057  {
1058  /* L10N: You will see this error message if you invoke <compose-to-sender>
1059  when you are on a normal attachment.
1060  */
1061  mutt_error(_("You may only compose to sender with message/rfc822 parts"));
1062  return;
1063  }
1064 
1065  struct Email *tmphdr = mutt_email_new();
1066  tmphdr->env = mutt_env_new();
1067 
1068  if (cur)
1069  {
1070  if (mutt_fetch_recips(tmphdr->env, cur->email->env, SEND_TO_SENDER) == -1)
1071  return;
1072  }
1073  else
1074  {
1075  for (int i = 0; i < actx->idxlen; i++)
1076  {
1077  if (actx->idx[i]->content->tagged &&
1078  mutt_fetch_recips(tmphdr->env, actx->idx[i]->content->email->env,
1079  SEND_TO_SENDER) == -1)
1080  return;
1081  }
1082  }
1083  ci_send_message(0, tmphdr, NULL, NULL, NULL);
1084 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:88
#define SEND_TO_SENDER
Definition: send.h:94
The envelope/body of an email.
Definition: email.h:35
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, int flags)
Generate recpients for a reply email.
Definition: send.c:745
struct Envelope * env
envelope information
Definition: email.h:91
bool tagged
Definition: body.h:74
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
int ci_send_message(int flags, struct Email *msg, char *tempfile, struct Context *ctx, struct Email *cur)
Send an email.
Definition: send.c:1530
struct Email * email
header information for message/rfc822
Definition: body.h:59
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

unsigned char MimeForwardRest

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

Definition at line 59 of file recvcmd.c.