NeoMutt  2018-07-16 +2225-8687db
Teaching an old dog new tricks
DOXYGEN
recvcmd.c File Reference

Send/reply with an attachment. More...

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

Go to the source code of this file.

Macros

#define EXTRA_SPACE   (15 + 7 + 2)
 

Functions

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

Variables

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

Detailed Description

Send/reply with an attachment.

Authors
  • Thomas Roessler
  • Pietro Cerutti

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

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

Definition in file recvcmd.c.

Macro Definition Documentation

#define EXTRA_SPACE   (15 + 7 + 2)

Function Documentation

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

Are we working with an RFC822 message.

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

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

Definition at line 72 of file recvcmd.c.

73 {
74  if (!mutt_is_message_type(b->type, b->subtype))
75  {
76  if (err)
77  mutt_error(_("You may only bounce message/rfc822 parts"));
78  return false;
79  }
80  return true;
81 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1270
#define _(a)
Definition: message.h:28
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
#define mutt_error(...)
Definition: logging.h:84
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 90 of file recvcmd.c.

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

115 {
116  if (cur)
117  return mutt_can_decode(cur);
118 
119  for (short i = 0; i < actx->idxlen; i++)
120  if (actx->idx[i]->content->tagged && !mutt_can_decode(actx->idx[i]->content))
121  return false;
122 
123  return true;
124 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1748
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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 131 of file recvcmd.c.

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

148 {
149  short level = actx->idx[i]->level;
150  short count = 0;
151 
152  while ((++i < actx->idxlen) && (level < actx->idx[i]->level))
153  if (actx->idx[i]->content->tagged)
154  count++;
155 
156  return count;
157 }
bool tagged
This attachment is tagged.
Definition: body.h:70
struct Body * content
Attachment.
Definition: attach.h:36
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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 166 of file recvcmd.c.

167 {
168  if (!m || !fp || !actx)
169  return;
170 
171  char prompt[256];
172  char buf[8192];
173  char *err = NULL;
174  int ret = 0;
175  int p = 0;
176 
177  if (!check_all_msg(actx, cur, true))
178  return;
179 
180  /* one or more messages? */
181  p = cur ? 1 : count_tagged(actx);
182 
183  /* RFC5322 mandates a From: header, so warn before bouncing
184  * messages without one */
185  if (cur)
186  {
187  if (TAILQ_EMPTY(&cur->email->env->from))
188  {
189  mutt_error(_("Warning: message contains no From: header"));
191  }
192  }
193  else
194  {
195  for (short i = 0; i < actx->idxlen; i++)
196  {
197  if (actx->idx[i]->content->tagged)
198  {
199  if (TAILQ_EMPTY(&actx->idx[i]->content->email->env->from))
200  {
201  mutt_error(_("Warning: message contains no From: header"));
203  break;
204  }
205  }
206  }
207  }
208 
209  if (p)
210  mutt_str_strfcpy(prompt, _("Bounce message to: "), sizeof(prompt));
211  else
212  mutt_str_strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
213 
214  buf[0] = '\0';
215  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_ALIAS) || (buf[0] == '\0'))
216  return;
217 
218  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
219  mutt_addrlist_parse(&al, buf);
220  if (TAILQ_EMPTY(&al))
221  {
222  mutt_error(_("Error parsing address"));
223  return;
224  }
225 
226  mutt_expand_aliases(&al);
227 
228  if (mutt_addrlist_to_intl(&al, &err) < 0)
229  {
230  mutt_error(_("Bad IDN: '%s'"), err);
231  FREE(&err);
232  goto end;
233  }
234 
235  buf[0] = '\0';
236  mutt_addrlist_write(buf, sizeof(buf), &al, true);
237 
238 #define EXTRA_SPACE (15 + 7 + 2)
239  /* See commands.c. */
240  snprintf(prompt, sizeof(prompt) - 4,
241  ngettext("Bounce message to %s?", "Bounce messages to %s?", p), buf);
242 
244  {
245  mutt_simple_format(prompt, sizeof(prompt) - 4, 0, MuttMessageWindow->cols - EXTRA_SPACE,
246  JUSTIFY_LEFT, 0, prompt, sizeof(prompt), false);
247  mutt_str_strcat(prompt, sizeof(prompt), "...?");
248  }
249  else
250  mutt_str_strcat(prompt, sizeof(prompt), "?");
251 
252  if (query_quadoption(C_Bounce, prompt) != MUTT_YES)
253  {
255  mutt_message(ngettext("Message not bounced", "Messages not bounced", p));
256  goto end;
257  }
258 
260 
261  if (cur)
262  ret = mutt_bounce_message(fp, cur->email, &al);
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, &al))
269  ret = 1;
270  }
271  }
272 
273  if (ret == 0)
274  mutt_message(ngettext("Message bounced", "Messages bounced", p));
275  else
276  mutt_error(ngettext("Error bouncing message", "Error bouncing messages", p));
277 
278 end:
279  mutt_addrlist_clear(&al);
280 }
WHERE unsigned char C_Bounce
Config: Confirm before bouncing a message.
Definition: globals.h:180
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:90
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:290
Left justify the text.
Definition: curs_lib.h:46
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:63
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:454
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3321
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1351
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
size_t mutt_addrlist_write(char *buf, size_t buflen, const struct AddressList *al, bool display)
Write an Address to a buffer.
Definition: address.c:1134
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:43
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:89
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
int mutt_bounce_message(FILE *fp, struct Email *e, struct AddressList *to)
Bounce an email message.
Definition: sendlib.c:3038
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1254
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:131
char * mutt_str_strcat(char *buf, size_t buflen, const char *s)
Concatenate two strings.
Definition: string.c:395
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1186
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
#define EXTRA_SPACE
#define FREE(x)
Definition: memory.h:40
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
#define TAILQ_EMPTY(head)
Definition: queue.h:715
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:631
struct Email * email
header information for message/rfc822
Definition: body.h:55
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:988
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 288 of file recvcmd.c.

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

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

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

366 {
367  struct AttachPtr *parent = NULL;
368 
369  if (cur)
370  {
371  for (short i = 0; i < actx->idxlen; i++)
372  {
373  if (mutt_is_message_type(actx->idx[i]->content->type,
374  actx->idx[i]->content->subtype) &&
375  is_parent(i, actx, cur))
376  {
377  parent = actx->idx[i];
378  }
379  if (actx->idx[i]->content == cur)
380  break;
381  }
382  }
383  else if (nattach)
384  parent = find_common_parent(actx, nattach);
385 
386  return parent;
387 }
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:1270
short idxlen
Number of attachmentes.
Definition: attach.h:55
char * subtype
content-type subtype
Definition: body.h:37
static int is_parent(short i, struct AttachCtx *actx, struct Body *cur)
Check whether one attachment is the parent of another.
Definition: recvcmd.c:344
static struct AttachPtr * find_common_parent(struct AttachCtx *actx, short nattach)
find a common parent message for the tagged attachments
Definition: recvcmd.c:310
unsigned int type
content-type primary type
Definition: body.h:65
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
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 397 of file recvcmd.c.

398 {
399  CopyHeaderFlags chflags = CH_DECODE;
400  char prefix2[128];
401 
402  if (C_Weed)
403  chflags |= CH_WEED | CH_REORDER;
404 
405  if (quote)
406  {
407  if (prefix)
408  mutt_str_strfcpy(prefix2, prefix, sizeof(prefix2));
409  else if (!C_TextFlowed)
410  {
411  mutt_make_string(prefix2, sizeof(prefix2), NONULL(C_IndentString),
412  Context, Context->mailbox, e);
413  }
414  else
415  mutt_str_strfcpy(prefix2, ">", sizeof(prefix2));
416 
417  chflags |= CH_PREFIX;
418  }
419 
420  mutt_copy_header(fp_in, e, fp_out, chflags, quote ? prefix2 : NULL);
421 }
The "current" mailbox.
Definition: context.h:39
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: globals.h:133
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix)
Copy Email header.
Definition: copy.c:389
struct Mailbox * mailbox
Definition: context.h:53
#define CH_WEED
Weed the headers?
Definition: copy.h:52
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:255
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:60
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
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 432 of file recvcmd.c.

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

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

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

749 {
750  if (check_all_msg(actx, cur, false))
751  attach_forward_msgs(fp, actx, cur, flags);
752  else
753  {
754  const short nattach = count_tagged(actx);
755  attach_forward_bodies(fp, e, actx, cur, nattach);
756  }
757 }
static bool check_all_msg(struct AttachCtx *actx, struct Body *cur, bool err)
Are all the Attachments RFC822 messages?
Definition: recvcmd.c:90
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:628
static short count_tagged(struct AttachCtx *actx)
Count the number of tagged attachments.
Definition: recvcmd.c:131
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:457
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 778 of file recvcmd.c.

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

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

Parameters
fpFile handle to attachment
fp_tmpFile handle to temporary file
eEmail

Definition at line 868 of file recvcmd.c.

869 {
871  CopyHeaderFlags chflags = CH_DECODE;
872 
874 
875  if (!C_Header)
876  cmflags |= MUTT_CM_NOHEADER;
877  if (C_Weed)
878  {
879  chflags |= CH_WEED;
880  cmflags |= MUTT_CM_WEED;
881  }
882 
883  mutt_copy_message_fp(fp_tmp, fp, e, cmflags, chflags);
885 }
The "current" mailbox.
Definition: context.h:39
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:593
#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:655
struct Mailbox * mailbox
Definition: context.h:53
#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:217
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:636
void mutt_attach_reply ( FILE *  fp,
struct Email e,
struct AttachCtx actx,
struct Body e_cur,
SendFlags  flags 
)

Attach a reply.

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

Definition at line 895 of file recvcmd.c.

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

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

Variable Documentation

unsigned char C_MimeForwardRest

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

Definition at line 61 of file recvcmd.c.