NeoMutt  2018-07-16 +1360-3df4a2
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 (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 *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, 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

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:1255
#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:70
#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:77
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:77
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
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:77
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:77
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 ( 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 164 of file recvcmd.c.

165 {
166  if (!m || !fp || !actx)
167  return;
168 
169  char prompt[256];
170  char buf[8192];
171  char *err = NULL;
172  struct Address *addr = NULL;
173  int ret = 0;
174  int p = 0;
175 
176  if (!check_all_msg(actx, cur, true))
177  return;
178 
179  /* one or more messages? */
180  p = cur ? 1 : count_tagged(actx);
181 
182  /* RFC5322 mandates a From: header, so warn before bouncing
183  * messages without one */
184  if (cur)
185  {
186  if (!cur->email->env->from)
187  {
188  mutt_error(_("Warning: message contains no From: header"));
190  }
191  }
192  else
193  {
194  for (short i = 0; i < actx->idxlen; i++)
195  {
196  if (actx->idx[i]->content->tagged)
197  {
198  if (!actx->idx[i]->content->email->env->from)
199  {
200  mutt_error(_("Warning: message contains no From: header"));
202  break;
203  }
204  }
205  }
206  }
207 
208  if (p)
209  mutt_str_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
210  else
211  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
212 
213  buf[0] = '\0';
214  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS) || (buf[0] == '\0'))
215  return;
216 
217  addr = mutt_addr_parse_list(addr, buf);
218  if (!addr)
219  {
220  mutt_error(_("Error parsing address"));
221  return;
222  }
223 
224  addr = mutt_expand_aliases(addr);
225 
226  if (mutt_addrlist_to_intl(addr, &err) < 0)
227  {
228  mutt_error(_("Bad IDN: '%s'"), err);
229  FREE(&err);
230  mutt_addr_free(&addr);
231  return;
232  }
233 
234  buf[0] = '\0';
235  mutt_addr_write(buf, sizeof(buf), addr, true);
236 
237 #define EXTRA_SPACE (15 + 7 + 2)
238  /* See commands.c. */
239  snprintf(prompt, sizeof(prompt) - 4,
240  ngettext("Bounce message to %s", "Bounce messages to %s", p), buf);
241 
243  {
244  mutt_simple_format(prompt, sizeof(prompt) - 4, 0, MuttMessageWindow->cols - EXTRA_SPACE,
245  FMT_LEFT, 0, prompt, sizeof(prompt), 0);
246  mutt_str_strcat(prompt, sizeof(prompt), "...?");
247  }
248  else
249  mutt_str_strcat(prompt, sizeof(prompt), "?");
250 
251  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
252  {
253  mutt_addr_free(&addr);
255  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
256  return;
257  }
258 
260 
261  if (cur)
262  ret = mutt_bounce_message(fp, cur->email, addr);
263  else
264  {
265  for (short i = 0; i < actx->idxlen; i++)
266  {
267  if (actx->idx[i]->content->tagged)
268  if (mutt_bounce_message(actx->idx[i]->fp, actx->idx[i]->content->email, addr))
269  ret = 1;
270  }
271  }
272 
273  if (!ret)
274  mutt_message(ngettext("Message bounced", "Messages bounced", p));
275  else
276  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
277 
278  mutt_addr_free(&addr);
279 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:188
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:3002
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:61
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
#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:42
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
An email address.
Definition: address.h:32
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:77
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:92
bool tagged
Definition: body.h:77
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
struct Address * from
Definition: envelope.h:41
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1176
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:741
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
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:401
struct Address * mutt_expand_aliases(struct Address *a)
Expand aliases in a List of Addresses.
Definition: alias.c:297
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
#define EXTRA_SPACE
#define FREE(x)
Definition: memory.h:40
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:60
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 287 of file recvcmd.c.

288 {
289  if (!check_all_msg(actx, cur, true))
290  return;
291 
292  if (cur)
293  mutt_resend_message(fp, Context, cur->email);
294  else
295  {
296  for (short i = 0; i < actx->idxlen; i++)
297  if (actx->idx[i]->content->tagged)
298  mutt_resend_message(actx->idx[i]->fp, Context, actx->idx[i]->content->email);
299  }
300 }
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: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:1367
bool tagged
Definition: body.h:77
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:60
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

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:1255
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:77
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:70
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:1255
short idxlen
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:343
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
find a common parent message for the tagged attachments
Definition: recvcmd.c:309
unsigned int type
content-type primary type
Definition: body.h:70
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 *  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 396 of file recvcmd.c.

397 {
398  CopyHeaderFlags chflags = CH_DECODE;
399  char prefix2[128];
400 
401  if (C_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 (!C_TextFlowed)
409  {
410  mutt_make_string(prefix2, sizeof(prefix2), NONULL(C_IndentString),
411  Context, Context->mailbox, e);
412  }
413  else
414  mutt_str_strfcpy(prefix2, ">", sizeof(prefix2));
415 
416  chflags |= CH_PREFIX;
417  }
418 
419  mutt_copy_header(fp_in, e, fp_out, chflags, quote ? prefix2 : NULL);
420 }
The "current" mailbox.
Definition: context.h:37
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:141
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix)
Copy Email header.
Definition: copy.c:386
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:741
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:263
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59
#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:39

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Forward one or several message-type attachments.

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

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

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

Definition at line 627 of file recvcmd.c.

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

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Forward an Attachment.

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

Definition at line 746 of file recvcmd.c.

748 {
749  if (check_all_msg(actx, cur, false))
750  attach_forward_msgs(fp, actx, cur, flags);
751  else
752  {
753  const short nattach = count_tagged(actx);
754  attach_forward_bodies(fp, e, actx, cur, nattach);
755  }
756 }
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, SendFlags 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,
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 777 of file recvcmd.c.

779 {
780  struct Envelope *curenv = NULL;
781  struct Email *e = 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  e = actx->idx[i]->content->email;
790  curenv = e->env;
791  break;
792  }
793  }
794  }
795  else
796  {
797  curenv = parent->env;
798  e = parent;
799  }
800 
801  if (!curenv || !e)
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:784
The envelope/body of an email.
Definition: email.h:37
struct Address * to
Definition: envelope.h:42
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:699
#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:829
short idxlen
Definition: attach.h:55
struct Envelope * env
envelope information
Definition: email.h:92
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
bool tagged
Definition: body.h:77
#define SEND_NEWS
Reply to a news article.
Definition: send.h:100
char * newsgroups
Definition: envelope.h:59
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
char * followup_to
Definition: envelope.h:61
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
struct Email * email
header information for message/rfc822
Definition: body.h:60
struct AttachPtr ** idx
Definition: attach.h:54
The header of an email.
Definition: envelope.h:38
void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv)
Generate references for a reply email.
Definition: send.c:851

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

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

Parameters
fpFile handle to attachment
fp_tmpFile handle to temporary file
curEmail

Definition at line 867 of file recvcmd.c.

868 {
870  CopyHeaderFlags chflags = CH_DECODE;
871 
872  mutt_make_attribution(Context->mailbox, cur, fp_tmp);
873 
874  if (!C_Header)
875  cmflags |= MUTT_CM_NOHEADER;
876  if (C_Weed)
877  {
878  chflags |= CH_WEED;
879  cmflags |= MUTT_CM_WEED;
880  }
881 
882  mutt_copy_message_fp(fp_tmp, fp, cur, cmflags, chflags);
883  mutt_make_post_indent(Context->mailbox, cur, fp_tmp);
884 }
The "current" mailbox.
Definition: context.h:37
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
make a copy of a message from a FILE pointer
Definition: copy.c:590
#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:560
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:225
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:541

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

Attach a reply.

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

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 *e_parent = NULL;
902  FILE *fp_parent = NULL;
903  struct Email *e_tmp = NULL;
904 
905  struct State st;
906  char tmpbody[PATH_MAX];
907  FILE *fp_tmp = NULL;
908 
909  char prefix[128];
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  e_parent = parent->content->email;
925  fp_parent = parent->fp;
926  }
927  else
928  {
929  e_parent = e;
930  fp_parent = actx->fp_root;
931  }
932  }
933 
934  if ((nattach > 1) && !check_can_decode(actx, cur))
935  {
936  const enum QuadOption ans = query_quadoption(
937  C_MimeForwardRest, _("Can't decode all tagged attachments. "
938  "MIME-encapsulate the others?"));
939  if (ans == MUTT_ABORT)
940  return;
941  else if (ans == MUTT_YES)
942  mime_reply_any = true;
943  }
944  else if (nattach == 1)
945  mime_reply_any = true;
946 
947  e_tmp = mutt_email_new();
948  e_tmp->env = mutt_env_new();
949 
951  e_tmp->env, actx, e_parent ? e_parent : (cur ? cur->email : NULL), flags) == -1)
952  {
953  mutt_email_free(&e_tmp);
954  return;
955  }
956 
957  mutt_mktemp(tmpbody, sizeof(tmpbody));
958  fp_tmp = mutt_file_fopen(tmpbody, "w");
959  if (!fp_tmp)
960  {
961  mutt_error(_("Can't create %s"), tmpbody);
962  mutt_email_free(&e_tmp);
963  return;
964  }
965 
966  if (!e_parent)
967  {
968  if (cur)
969  attach_include_reply(fp, fp_tmp, 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, fp_tmp, actx->idx[i]->content->email);
976  }
977  }
978  }
979  else
980  {
981  mutt_make_attribution(Context->mailbox, e_parent, fp_tmp);
982 
983  memset(&st, 0, sizeof(struct State));
984  st.fp_out = fp_tmp;
985 
986  if (!C_TextFlowed)
987  {
988  mutt_make_string(prefix, sizeof(prefix), NONULL(C_IndentString), Context,
989  Context->mailbox, e_parent);
990  }
991  else
992  mutt_str_strfcpy(prefix, ">", sizeof(prefix));
993 
994  st.prefix = prefix;
995  st.flags = MUTT_CHARCONV;
996 
997  if (C_Weed)
998  st.flags |= MUTT_WEED;
999 
1000  if (C_Header)
1001  include_header(true, fp_parent, e_parent, fp_tmp, prefix);
1002 
1003  if (cur)
1004  {
1005  if (mutt_can_decode(cur))
1006  {
1007  st.fp_in = fp;
1008  mutt_body_handler(cur, &st);
1009  state_putc('\n', &st);
1010  }
1011  else
1012  mutt_body_copy(fp, &e_tmp->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.fp_in = 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->mailbox, e_parent, fp_tmp);
1028 
1029  if (mime_reply_any && !cur && !copy_problematic_attachments(&e_tmp->content, actx, false))
1030  {
1031  mutt_email_free(&e_tmp);
1032  mutt_file_fclose(&fp_tmp);
1033  return;
1034  }
1035  }
1036 
1037  mutt_file_fclose(&fp_tmp);
1038 
1039  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1040  el_add_email(&el, e_parent ? e_parent : (cur ? cur->email : NULL));
1041  if (ci_send_message(flags, e_tmp, tmpbody, NULL, &el) == 0)
1042  {
1044  }
1045  el_free(&el);
1046 }
The "current" mailbox.
Definition: context.h:37
#define NONULL(x)
Definition: string2.h:36
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 mutt_set_flag(m, e, flag, bf)
Definition: protos.h:68
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:396
static bool check_can_decode(struct AttachCtx *actx, struct Body *cur)
Can we decode all tagged attachments?
Definition: recvcmd.c:112
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:141
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
list of MIME parts
Definition: email.h:93
FILE * fp_root
used by recvattach for updating
Definition: attach.h:52
void el_free(struct EmailList *el)
Drop a private list of Emails.
Definition: context.c:322
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
#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_post_indent(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add suffix to replied email text.
Definition: send.c:560
Messages that have been replied to.
Definition: mutt.h:97
int ci_send_message(SendFlags flags, struct Email *msg, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1726
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Mailbox * mailbox
Definition: context.h:51
struct Envelope * env
envelope information
Definition: email.h:92
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
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:386
bool tagged
Definition: body.h:77
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:225
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:72
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:48
static void attach_include_reply(FILE *fp, FILE *fp_tmp, struct Email *cur)
This is very similar to send.c&#39;s include_reply()
Definition: recvcmd.c:867
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
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:741
#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:129
#define SEND_NEWS
Reply to a news article.
Definition: send.h:100
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:546
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 bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:263
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
#define state_putc(str, state)
Definition: state.h:55
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59
Keep track when processing files.
Definition: state.h:44
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1524
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:777
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
unsigned char C_MimeForwardRest
Config: Forward all attachments, even if they can&#39;t be decoded.
Definition: recvcmd.c:59
struct Email * email
header information for message/rfc822
Definition: body.h:60
struct AttachPtr ** idx
Definition: attach.h:54
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:541

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

1057 {
1058  if (!check_all_msg(actx, cur, 0))
1059  {
1060  /* L10N: You will see this error message if you invoke <compose-to-sender>
1061  when you are on a normal attachment. */
1062  mutt_error(_("You may only compose to sender with message/rfc822 parts"));
1063  return;
1064  }
1065 
1066  struct Email *e_tmp = mutt_email_new();
1067  e_tmp->env = mutt_env_new();
1068 
1069  if (cur)
1070  {
1071  if (mutt_fetch_recips(e_tmp->env, cur->email->env, SEND_TO_SENDER) == -1)
1072  return;
1073  }
1074  else
1075  {
1076  for (int i = 0; i < actx->idxlen; i++)
1077  {
1078  if (actx->idx[i]->content->tagged &&
1079  (mutt_fetch_recips(e_tmp->env, actx->idx[i]->content->email->env,
1080  SEND_TO_SENDER) == -1))
1081  return;
1082  }
1083  }
1084  ci_send_message(0, e_tmp, NULL, NULL, NULL);
1085 }
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
Compose new email to sender.
Definition: send.h:98
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:699
#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 ci_send_message(SendFlags flags, struct Email *msg, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1726
struct Envelope * env
envelope information
Definition: email.h:92
bool tagged
Definition: body.h:77
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
struct Email * email
header information for message/rfc822
Definition: body.h:60
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 C_MimeForwardRest

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

Definition at line 59 of file recvcmd.c.