NeoMutt  2020-08-07-1-gab41a1
Teaching an old dog new tricks
DOXYGEN
copy.h File Reference

Duplicate the structure of an entire email. More...

#include "config.h"
#include <stdint.h>
#include <stdio.h>
+ Include dependency graph for copy.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MUTT_CM_NO_FLAGS   0
 No flags are set. More...
 
#define MUTT_CM_NOHEADER   (1 << 0)
 Don't copy the message header. More...
 
#define MUTT_CM_PREFIX   (1 << 1)
 Quote the header and body. More...
 
#define MUTT_CM_DECODE   (1 << 2)
 Decode the message body into text/plain. More...
 
#define MUTT_CM_DISPLAY   (1 << 3)
 Output is displayed to the user. More...
 
#define MUTT_CM_UPDATE   (1 << 4)
 Update structs on sync. More...
 
#define MUTT_CM_WEED   (1 << 5)
 Weed message/rfc822 attachment headers. More...
 
#define MUTT_CM_CHARCONV   (1 << 6)
 Perform character set conversions. More...
 
#define MUTT_CM_PRINTING   (1 << 7)
 Printing the message - display light. More...
 
#define MUTT_CM_REPLYING   (1 << 8)
 Replying the message. More...
 
#define MUTT_CM_DECODE_PGP   (1 << 9)
 Used for decoding PGP messages. More...
 
#define MUTT_CM_DECODE_SMIME   (1 << 10)
 Used for decoding S/MIME messages. More...
 
#define MUTT_CM_VERIFY   (1 << 11)
 Do signature verification. More...
 
#define MUTT_CM_DECODE_CRYPT   (MUTT_CM_DECODE_PGP | MUTT_CM_DECODE_SMIME)
 
#define CH_NO_FLAGS   0
 No flags are set. More...
 
#define CH_UPDATE   (1 << 0)
 Update the status and x-status fields? More...
 
#define CH_WEED   (1 << 1)
 Weed the headers? More...
 
#define CH_DECODE   (1 << 2)
 Do RFC2047 header decoding. More...
 
#define CH_XMIT   (1 << 3)
 Transmitting this message? (Ignore Lines: and Content-Length:) More...
 
#define CH_FROM   (1 << 4)
 Retain the "From " message separator? More...
 
#define CH_PREFIX   (1 << 5)
 Quote header using C_IndentString string? More...
 
#define CH_NOSTATUS   (1 << 6)
 Suppress the status and x-status fields. More...
 
#define CH_REORDER   (1 << 7)
 Re-order output of headers (specified by 'hdr_order') More...
 
#define CH_NONEWLINE   (1 << 8)
 Don't output terminating newline after the header. More...
 
#define CH_MIME   (1 << 9)
 Ignore MIME fields. More...
 
#define CH_UPDATE_LEN   (1 << 10)
 Update Lines: and Content-Length: More...
 
#define CH_TXTPLAIN   (1 << 11)
 Generate text/plain MIME headers. More...
 
#define CH_NOLEN   (1 << 12)
 Don't write Content-Length: and Lines: More...
 
#define CH_WEED_DELIVERED   (1 << 13)
 Weed eventual Delivered-To headers. More...
 
#define CH_FORCE_FROM   (1 << 14)
 Give CH_FROM precedence over CH_WEED? More...
 
#define CH_NOQFROM   (1 << 15)
 Ignore ">From " line. More...
 
#define CH_UPDATE_IRT   (1 << 16)
 Update In-Reply-To: More...
 
#define CH_UPDATE_REFS   (1 << 17)
 Update References: More...
 
#define CH_DISPLAY   (1 << 18)
 Display result to user. More...
 
#define CH_UPDATE_LABEL   (1 << 19)
 Update X-Label: from email->env->x_label? More...
 
#define CH_UPDATE_SUBJECT   (1 << 20)
 Update Subject: protected header update. More...
 
#define CH_VIRTUAL   (1 << 21)
 Write virtual header lines too. More...
 

Typedefs

typedef uint16_t CopyMessageFlags
 Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER. More...
 
typedef uint32_t CopyHeaderFlags
 Flags for mutt_copy_header(), e.g. CH_UPDATE. More...
 

Functions

int mutt_copy_hdr (FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix, int wraplen)
 Copy header from one file to another. More...
 
int mutt_copy_header (FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix, int wraplen)
 Copy Email header. More...
 
int mutt_copy_message_fp (FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
 make a copy of a message from a FILE pointer More...
 
int mutt_copy_message (FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
 Copy a message from a Mailbox. More...
 
int mutt_append_message (struct Mailbox *dest, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
 Append a message. More...
 

Detailed Description

Duplicate the structure of an entire email.

Authors
  • Michael R. Elkins

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 copy.h.

Macro Definition Documentation

◆ MUTT_CM_NO_FLAGS

#define MUTT_CM_NO_FLAGS   0

No flags are set.

Definition at line 34 of file copy.h.

◆ MUTT_CM_NOHEADER

#define MUTT_CM_NOHEADER   (1 << 0)

Don't copy the message header.

Definition at line 35 of file copy.h.

◆ MUTT_CM_PREFIX

#define MUTT_CM_PREFIX   (1 << 1)

Quote the header and body.

Definition at line 36 of file copy.h.

◆ MUTT_CM_DECODE

#define MUTT_CM_DECODE   (1 << 2)

Decode the message body into text/plain.

Definition at line 37 of file copy.h.

◆ MUTT_CM_DISPLAY

#define MUTT_CM_DISPLAY   (1 << 3)

Output is displayed to the user.

Definition at line 38 of file copy.h.

◆ MUTT_CM_UPDATE

#define MUTT_CM_UPDATE   (1 << 4)

Update structs on sync.

Definition at line 39 of file copy.h.

◆ MUTT_CM_WEED

#define MUTT_CM_WEED   (1 << 5)

Weed message/rfc822 attachment headers.

Definition at line 40 of file copy.h.

◆ MUTT_CM_CHARCONV

#define MUTT_CM_CHARCONV   (1 << 6)

Perform character set conversions.

Definition at line 41 of file copy.h.

◆ MUTT_CM_PRINTING

#define MUTT_CM_PRINTING   (1 << 7)

Printing the message - display light.

Definition at line 42 of file copy.h.

◆ MUTT_CM_REPLYING

#define MUTT_CM_REPLYING   (1 << 8)

Replying the message.

Definition at line 43 of file copy.h.

◆ MUTT_CM_DECODE_PGP

#define MUTT_CM_DECODE_PGP   (1 << 9)

Used for decoding PGP messages.

Definition at line 44 of file copy.h.

◆ MUTT_CM_DECODE_SMIME

#define MUTT_CM_DECODE_SMIME   (1 << 10)

Used for decoding S/MIME messages.

Definition at line 45 of file copy.h.

◆ MUTT_CM_VERIFY

#define MUTT_CM_VERIFY   (1 << 11)

Do signature verification.

Definition at line 46 of file copy.h.

◆ MUTT_CM_DECODE_CRYPT

#define MUTT_CM_DECODE_CRYPT   (MUTT_CM_DECODE_PGP | MUTT_CM_DECODE_SMIME)

Definition at line 47 of file copy.h.

◆ CH_NO_FLAGS

#define CH_NO_FLAGS   0

No flags are set.

Definition at line 50 of file copy.h.

◆ CH_UPDATE

#define CH_UPDATE   (1 << 0)

Update the status and x-status fields?

Definition at line 51 of file copy.h.

◆ CH_WEED

#define CH_WEED   (1 << 1)

Weed the headers?

Definition at line 52 of file copy.h.

◆ CH_DECODE

#define CH_DECODE   (1 << 2)

Do RFC2047 header decoding.

Definition at line 53 of file copy.h.

◆ CH_XMIT

#define CH_XMIT   (1 << 3)

Transmitting this message? (Ignore Lines: and Content-Length:)

Definition at line 54 of file copy.h.

◆ CH_FROM

#define CH_FROM   (1 << 4)

Retain the "From " message separator?

Definition at line 55 of file copy.h.

◆ CH_PREFIX

#define CH_PREFIX   (1 << 5)

Quote header using C_IndentString string?

Definition at line 56 of file copy.h.

◆ CH_NOSTATUS

#define CH_NOSTATUS   (1 << 6)

Suppress the status and x-status fields.

Definition at line 57 of file copy.h.

◆ CH_REORDER

#define CH_REORDER   (1 << 7)

Re-order output of headers (specified by 'hdr_order')

Definition at line 58 of file copy.h.

◆ CH_NONEWLINE

#define CH_NONEWLINE   (1 << 8)

Don't output terminating newline after the header.

Definition at line 59 of file copy.h.

◆ CH_MIME

#define CH_MIME   (1 << 9)

Ignore MIME fields.

Definition at line 60 of file copy.h.

◆ CH_UPDATE_LEN

#define CH_UPDATE_LEN   (1 << 10)

Update Lines: and Content-Length:

Definition at line 61 of file copy.h.

◆ CH_TXTPLAIN

#define CH_TXTPLAIN   (1 << 11)

Generate text/plain MIME headers.

Definition at line 62 of file copy.h.

◆ CH_NOLEN

#define CH_NOLEN   (1 << 12)

Don't write Content-Length: and Lines:

Definition at line 63 of file copy.h.

◆ CH_WEED_DELIVERED

#define CH_WEED_DELIVERED   (1 << 13)

Weed eventual Delivered-To headers.

Definition at line 64 of file copy.h.

◆ CH_FORCE_FROM

#define CH_FORCE_FROM   (1 << 14)

Give CH_FROM precedence over CH_WEED?

Definition at line 65 of file copy.h.

◆ CH_NOQFROM

#define CH_NOQFROM   (1 << 15)

Ignore ">From " line.

Definition at line 66 of file copy.h.

◆ CH_UPDATE_IRT

#define CH_UPDATE_IRT   (1 << 16)

Update In-Reply-To:

Definition at line 67 of file copy.h.

◆ CH_UPDATE_REFS

#define CH_UPDATE_REFS   (1 << 17)

Update References:

Definition at line 68 of file copy.h.

◆ CH_DISPLAY

#define CH_DISPLAY   (1 << 18)

Display result to user.

Definition at line 69 of file copy.h.

◆ CH_UPDATE_LABEL

#define CH_UPDATE_LABEL   (1 << 19)

Update X-Label: from email->env->x_label?

Definition at line 70 of file copy.h.

◆ CH_UPDATE_SUBJECT

#define CH_UPDATE_SUBJECT   (1 << 20)

Update Subject: protected header update.

Definition at line 71 of file copy.h.

◆ CH_VIRTUAL

#define CH_VIRTUAL   (1 << 21)

Write virtual header lines too.

Definition at line 72 of file copy.h.

Typedef Documentation

◆ CopyMessageFlags

typedef uint16_t CopyMessageFlags

Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.

Definition at line 31 of file copy.h.

◆ CopyHeaderFlags

typedef uint32_t CopyHeaderFlags

Flags for mutt_copy_header(), e.g. CH_UPDATE.

Definition at line 49 of file copy.h.

Function Documentation

◆ mutt_copy_hdr()

int mutt_copy_hdr ( FILE *  fp_in,
FILE *  fp_out,
LOFF_T  off_start,
LOFF_T  off_end,
CopyHeaderFlags  chflags,
const char *  prefix,
int  wraplen 
)

Copy header from one file to another.

Parameters
fp_inFILE pointer to read from
fp_outFILE pointer to write to
off_startOffset to start from
off_endOffset to finish at
chflagsFlags, see CopyHeaderFlags
prefixPrefix for quoting headers
wraplenWidth to wrap at (when chflags & CH_DISPLAY)
Return values
0Success
-1Failure

Ok, the only reason for not merging this with mutt_copy_header() below is to avoid creating a Email structure in message_handler(). Also, this one will wrap headers much more aggressively than the other one.

Definition at line 78 of file copy.c.

80 {
81  bool from = false;
82  bool this_is_from = false;
83  bool ignore = false;
84  char buf[1024]; /* should be long enough to get most fields in one pass */
85  char *nl = NULL;
86  char **headers = NULL;
87  int hdr_count;
88  int x;
89  char *this_one = NULL;
90  size_t this_one_len = 0;
91  int error;
92 
93  if (off_start < 0)
94  return -1;
95 
96  if (ftello(fp_in) != off_start)
97  if (fseeko(fp_in, off_start, SEEK_SET) < 0)
98  return -1;
99 
100  buf[0] = '\n';
101  buf[1] = '\0';
102 
103  if ((chflags & (CH_REORDER | CH_WEED | CH_MIME | CH_DECODE | CH_PREFIX | CH_WEED_DELIVERED)) == 0)
104  {
105  /* Without these flags to complicate things
106  * we can do a more efficient line to line copying */
107  while (ftello(fp_in) < off_end)
108  {
109  nl = strchr(buf, '\n');
110 
111  if (!fgets(buf, sizeof(buf), fp_in))
112  break;
113 
114  /* Is it the beginning of a header? */
115  if (nl && (buf[0] != ' ') && (buf[0] != '\t'))
116  {
117  ignore = true;
118  if (!from && mutt_str_startswith(buf, "From "))
119  {
120  if ((chflags & CH_FROM) == 0)
121  continue;
122  from = true;
123  }
124  else if ((chflags & CH_NOQFROM) && mutt_istr_startswith(buf, ">From "))
125  continue;
126  else if ((buf[0] == '\n') || ((buf[0] == '\r') && (buf[1] == '\n')))
127  break; /* end of header */
128 
129  if ((chflags & (CH_UPDATE | CH_XMIT | CH_NOSTATUS)) &&
130  (mutt_istr_startswith(buf, "Status:") || mutt_istr_startswith(buf, "X-Status:")))
131  {
132  continue;
133  }
134  if ((chflags & (CH_UPDATE_LEN | CH_XMIT | CH_NOLEN)) &&
135  (mutt_istr_startswith(buf, "Content-Length:") ||
136  mutt_istr_startswith(buf, "Lines:")))
137  {
138  continue;
139  }
140  if ((chflags & CH_UPDATE_REFS) &&
141  mutt_istr_startswith(buf, "References:"))
142  continue;
143  if ((chflags & CH_UPDATE_IRT) &&
144  mutt_istr_startswith(buf, "In-Reply-To:"))
145  continue;
146  if (chflags & CH_UPDATE_LABEL && mutt_istr_startswith(buf, "X-Label:"))
147  continue;
148  if ((chflags & CH_UPDATE_SUBJECT) &&
149  mutt_istr_startswith(buf, "Subject:"))
150  continue;
151 
152  ignore = false;
153  }
154 
155  if (!ignore && (fputs(buf, fp_out) == EOF))
156  return -1;
157  }
158  return 0;
159  }
160 
161  hdr_count = 1;
162  x = 0;
163  error = false;
164 
165  /* We are going to read and collect the headers in an array
166  * so we are able to do re-ordering.
167  * First count the number of entries in the array */
168  if (chflags & CH_REORDER)
169  {
170  struct ListNode *np = NULL;
171  STAILQ_FOREACH(np, &HeaderOrderList, entries)
172  {
173  mutt_debug(LL_DEBUG3, "Reorder list: %s\n", np->data);
174  hdr_count++;
175  }
176  }
177 
178  mutt_debug(LL_DEBUG1, "WEED is %sset\n", (chflags & CH_WEED) ? "" : "not ");
179 
180  headers = mutt_mem_calloc(hdr_count, sizeof(char *));
181 
182  /* Read all the headers into the array */
183  while (ftello(fp_in) < off_end)
184  {
185  nl = strchr(buf, '\n');
186 
187  /* Read a line */
188  if (!fgets(buf, sizeof(buf), fp_in))
189  break;
190 
191  /* Is it the beginning of a header? */
192  if (nl && (buf[0] != ' ') && (buf[0] != '\t'))
193  {
194  /* Do we have anything pending? */
195  if (this_one)
196  {
197  if (chflags & CH_DECODE)
198  {
199  if (address_header_decode(&this_one) == 0)
200  rfc2047_decode(&this_one);
201  this_one_len = mutt_str_len(this_one);
202 
203  /* Convert CRLF line endings to LF */
204  if ((this_one_len > 2) && (this_one[this_one_len - 2] == '\r') &&
205  (this_one[this_one_len - 1] == '\n'))
206  {
207  this_one[this_one_len - 2] = '\n';
208  this_one[this_one_len - 1] = '\0';
209  }
210  }
211 
212  if (!headers[x])
213  headers[x] = this_one;
214  else
215  {
216  int hlen = mutt_str_len(headers[x]);
217 
218  mutt_mem_realloc(&headers[x], hlen + this_one_len + sizeof(char));
219  strcat(headers[x] + hlen, this_one);
220  FREE(&this_one);
221  }
222 
223  this_one = NULL;
224  }
225 
226  ignore = true;
227  this_is_from = false;
228  if (!from && mutt_str_startswith(buf, "From "))
229  {
230  if ((chflags & CH_FROM) == 0)
231  continue;
232  this_is_from = true;
233  from = true;
234  }
235  else if ((buf[0] == '\n') || ((buf[0] == '\r') && (buf[1] == '\n')))
236  break; /* end of header */
237 
238  /* note: CH_FROM takes precedence over header weeding. */
239  if (!((chflags & CH_FROM) && (chflags & CH_FORCE_FROM) && this_is_from) &&
240  (chflags & CH_WEED) && mutt_matches_ignore(buf))
241  {
242  continue;
243  }
244  if ((chflags & CH_WEED_DELIVERED) &&
245  mutt_istr_startswith(buf, "Delivered-To:"))
246  {
247  continue;
248  }
249  if ((chflags & (CH_UPDATE | CH_XMIT | CH_NOSTATUS)) &&
250  (mutt_istr_startswith(buf, "Status:") ||
251  mutt_istr_startswith(buf, "X-Status:")))
252  {
253  continue;
254  }
255  if ((chflags & (CH_UPDATE_LEN | CH_XMIT | CH_NOLEN)) &&
256  (mutt_istr_startswith(buf, "Content-Length:") || mutt_istr_startswith(buf, "Lines:")))
257  {
258  continue;
259  }
260  if ((chflags & CH_MIME))
261  {
262  if (mutt_istr_startswith(buf, "mime-version:"))
263  {
264  continue;
265  }
266  size_t plen = mutt_istr_startswith(buf, "content-");
267  if ((plen != 0) &&
268  (mutt_istr_startswith(buf + plen, "transfer-encoding:") ||
269  mutt_istr_startswith(buf + plen, "type:")))
270  {
271  continue;
272  }
273  }
274  if ((chflags & CH_UPDATE_REFS) &&
275  mutt_istr_startswith(buf, "References:"))
276  continue;
277  if ((chflags & CH_UPDATE_IRT) &&
278  mutt_istr_startswith(buf, "In-Reply-To:"))
279  continue;
280  if ((chflags & CH_UPDATE_LABEL) && mutt_istr_startswith(buf, "X-Label:"))
281  continue;
282  if ((chflags & CH_UPDATE_SUBJECT) &&
283  mutt_istr_startswith(buf, "Subject:"))
284  continue;
285 
286  /* Find x -- the array entry where this header is to be saved */
287  if (chflags & CH_REORDER)
288  {
289  struct ListNode *np = NULL;
290  x = 0;
291  STAILQ_FOREACH(np, &HeaderOrderList, entries)
292  {
293  ++x;
294  if (mutt_istr_startswith(buf, np->data))
295  {
296  mutt_debug(LL_DEBUG2, "Reorder: %s matches %s", np->data, buf);
297  break;
298  }
299  }
300  }
301 
302  ignore = false;
303  } /* If beginning of header */
304 
305  if (!ignore)
306  {
307  mutt_debug(LL_DEBUG2, "Reorder: x = %d; hdr_count = %d\n", x, hdr_count);
308  if (this_one)
309  {
310  size_t blen = mutt_str_len(buf);
311 
312  mutt_mem_realloc(&this_one, this_one_len + blen + sizeof(char));
313  strcat(this_one + this_one_len, buf);
314  this_one_len += blen;
315  }
316  else
317  {
318  this_one = mutt_str_dup(buf);
319  this_one_len = mutt_str_len(this_one);
320  }
321  }
322  } /* while (ftello (fp_in) < off_end) */
323 
324  /* Do we have anything pending? -- XXX, same code as in above in the loop. */
325  if (this_one)
326  {
327  if (chflags & CH_DECODE)
328  {
329  if (address_header_decode(&this_one) == 0)
330  rfc2047_decode(&this_one);
331  this_one_len = mutt_str_len(this_one);
332  }
333 
334  if (!headers[x])
335  headers[x] = this_one;
336  else
337  {
338  int hlen = mutt_str_len(headers[x]);
339 
340  mutt_mem_realloc(&headers[x], hlen + this_one_len + sizeof(char));
341  strcat(headers[x] + hlen, this_one);
342  FREE(&this_one);
343  }
344 
345  this_one = NULL;
346  }
347 
348  /* Now output the headers in order */
349  for (x = 0; x < hdr_count; x++)
350  {
351  if (headers[x])
352  {
353  /* We couldn't do the prefixing when reading because RFC2047
354  * decoding may have concatenated lines. */
355  if (chflags & (CH_DECODE | CH_PREFIX))
356  {
357  const char *pre = (chflags & CH_PREFIX) ? prefix : NULL;
358  wraplen = mutt_window_wrap_cols(wraplen, C_Wrap);
359 
360  if (mutt_write_one_header(fp_out, 0, headers[x], pre, wraplen, chflags,
361  NeoMutt->sub) == -1)
362  {
363  error = true;
364  break;
365  }
366  }
367  else
368  {
369  if (fputs(headers[x], fp_out) == EOF)
370  {
371  error = true;
372  break;
373  }
374  }
375  }
376  }
377 
378  /* Free in a separate loop to be sure that all headers are freed
379  * in case of error. */
380  for (x = 0; x < hdr_count; x++)
381  FREE(&headers[x]);
382  FREE(&headers);
383 
384  if (error)
385  return -1;
386  return 0;
387 }
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:314
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:55
#define CH_NOSTATUS
Suppress the status and x-status fields.
Definition: copy.h:57
#define CH_UPDATE
Update the status and x-status fields?
Definition: copy.h:51
#define CH_UPDATE_REFS
Update References:
Definition: copy.h:68
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CH_WEED_DELIVERED
Weed eventual Delivered-To headers.
Definition: copy.h:64
Log at debug level 2.
Definition: logging.h:41
static int address_header_decode(char **h)
Parse an email&#39;s headers.
Definition: copy.c:1047
void rfc2047_decode(char **pd)
Decode any RFC2047-encoded header fields.
Definition: rfc2047.c:639
#define CH_WEED
Weed the headers?
Definition: copy.h:52
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define CH_FORCE_FROM
Give CH_FROM precedence over CH_WEED?
Definition: copy.h:65
#define CH_UPDATE_LABEL
Update X-Label: from email->env->x_label?
Definition: copy.h:70
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: mutt_globals.h:117
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:165
#define CH_UPDATE_IRT
Update In-Reply-To:
Definition: copy.h:67
#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
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:487
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:177
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define CH_NOLEN
Don&#39;t write Content-Length: and Lines:
Definition: copy.h:63
#define CH_UPDATE_SUBJECT
Update Subject: protected header update.
Definition: copy.h:71
#define CH_NOQFROM
Ignore ">From " line.
Definition: copy.h:66
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
char * data
String.
Definition: list.h:36
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
A List node for strings.
Definition: list.h:34
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
Log at debug level 3.
Definition: logging.h:42
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
Write one header line to a file.
Definition: header.c:419
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_copy_header()

int mutt_copy_header ( FILE *  fp_in,
struct Email e,
FILE *  fp_out,
CopyHeaderFlags  chflags,
const char *  prefix,
int  wraplen 
)

Copy Email header.

Parameters
fp_inFILE pointer to read from
eEmail
fp_outFILE pointer to write to
chflagsSee CopyHeaderFlags
prefixPrefix for quoting headers (if CH_PREFIX is set)
wraplenWidth to wrap at (when chflags & CH_DISPLAY)
Return values
0Success
-1Failure

Definition at line 400 of file copy.c.

402 {
403  char *temp_hdr = NULL;
404 
405  if (e->env)
406  {
407  chflags |= ((e->env->changed & MUTT_ENV_CHANGED_IRT) ? CH_UPDATE_IRT : 0) |
411  }
412 
413  if (mutt_copy_hdr(fp_in, fp_out, e->offset, e->body->offset, chflags, prefix, wraplen) == -1)
414  return -1;
415 
416  if (chflags & CH_TXTPLAIN)
417  {
418  char chsbuf[128];
419  char buf[128];
420  fputs("MIME-Version: 1.0\n", fp_out);
421  fputs("Content-Transfer-Encoding: 8bit\n", fp_out);
422  fputs("Content-Type: text/plain; charset=", fp_out);
423  mutt_ch_canonical_charset(chsbuf, sizeof(chsbuf), C_Charset ? C_Charset : "us-ascii");
424  mutt_addr_cat(buf, sizeof(buf), chsbuf, MimeSpecials);
425  fputs(buf, fp_out);
426  fputc('\n', fp_out);
427  }
428 
429  if ((chflags & CH_UPDATE_IRT) && !STAILQ_EMPTY(&e->env->in_reply_to))
430  {
431  fputs("In-Reply-To:", fp_out);
432  struct ListNode *np = NULL;
433  STAILQ_FOREACH(np, &e->env->in_reply_to, entries)
434  {
435  fputc(' ', fp_out);
436  fputs(np->data, fp_out);
437  }
438  fputc('\n', fp_out);
439  }
440 
441  if ((chflags & CH_UPDATE_REFS) && !STAILQ_EMPTY(&e->env->references))
442  {
443  fputs("References:", fp_out);
444  mutt_write_references(&e->env->references, fp_out, 0, NeoMutt->sub);
445  fputc('\n', fp_out);
446  }
447 
448  if ((chflags & CH_UPDATE) && ((chflags & CH_NOSTATUS) == 0))
449  {
450  if (e->old || e->read)
451  {
452  fputs("Status: ", fp_out);
453  if (e->read)
454  fputs("RO", fp_out);
455  else if (e->old)
456  fputc('O', fp_out);
457  fputc('\n', fp_out);
458  }
459 
460  if (e->flagged || e->replied)
461  {
462  fputs("X-Status: ", fp_out);
463  if (e->replied)
464  fputc('A', fp_out);
465  if (e->flagged)
466  fputc('F', fp_out);
467  fputc('\n', fp_out);
468  }
469  }
470 
471  if (chflags & CH_UPDATE_LEN && ((chflags & CH_NOLEN) == 0))
472  {
473  fprintf(fp_out, "Content-Length: " OFF_T_FMT "\n", e->body->length);
474  if ((e->lines != 0) || (e->body->length == 0))
475  fprintf(fp_out, "Lines: %d\n", e->lines);
476  }
477 
478 #ifdef USE_NOTMUCH
479  if (chflags & CH_VIRTUAL)
480  {
481  /* Add some fake headers based on notmuch data */
482  char *folder = nm_email_get_folder(e);
483  if (folder && !(C_Weed && mutt_matches_ignore("folder")))
484  {
485  char buf[1024];
486  mutt_str_copy(buf, folder, sizeof(buf));
487  mutt_pretty_mailbox(buf, sizeof(buf));
488 
489  fputs("Folder: ", fp_out);
490  fputs(buf, fp_out);
491  fputc('\n', fp_out);
492  }
493  }
494 #endif
495  char *tags = driver_tags_get(&e->tags);
496  if (tags && !(C_Weed && mutt_matches_ignore("tags")))
497  {
498  fputs("Tags: ", fp_out);
499  fputs(tags, fp_out);
500  fputc('\n', fp_out);
501  }
502  FREE(&tags);
503 
504  if ((chflags & CH_UPDATE_LABEL) && e->env->x_label)
505  {
506  temp_hdr = e->env->x_label;
507  /* env->x_label isn't currently stored with direct references elsewhere.
508  * Context->label_hash strdups the keys. But to be safe, encode a copy */
509  if (!(chflags & CH_DECODE))
510  {
511  temp_hdr = mutt_str_dup(temp_hdr);
512  rfc2047_encode(&temp_hdr, NULL, sizeof("X-Label:"), C_SendCharset);
513  }
515  fp_out, "X-Label", temp_hdr, (chflags & CH_PREFIX) ? prefix : 0,
516  mutt_window_wrap_cols(wraplen, C_Wrap), chflags, NeoMutt->sub) == -1)
517  {
518  return -1;
519  }
520  if (!(chflags & CH_DECODE))
521  FREE(&temp_hdr);
522  }
523 
524  if ((chflags & CH_UPDATE_SUBJECT) && e->env->subject)
525  {
526  temp_hdr = e->env->subject;
527  /* env->subject is directly referenced in Context->subj_hash, so we
528  * have to be careful not to encode (and thus free) that memory. */
529  if (!(chflags & CH_DECODE))
530  {
531  temp_hdr = mutt_str_dup(temp_hdr);
532  rfc2047_encode(&temp_hdr, NULL, sizeof("Subject:"), C_SendCharset);
533  }
535  fp_out, "Subject", temp_hdr, (chflags & CH_PREFIX) ? prefix : 0,
536  mutt_window_wrap_cols(wraplen, C_Wrap), chflags, NeoMutt->sub) == -1)
537  {
538  return -1;
539  }
540  if (!(chflags & CH_DECODE))
541  FREE(&temp_hdr);
542  }
543 
544  if ((chflags & CH_NONEWLINE) == 0)
545  {
546  if (chflags & CH_PREFIX)
547  fputs(prefix, fp_out);
548  fputc('\n', fp_out); /* add header terminator */
549  }
550 
551  if (ferror(fp_out) || feof(fp_out))
552  return -1;
553 
554  return 0;
555 }
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:314
int lines
How many lines in the body of this message?
Definition: email.h:85
struct Body * body
List of MIME parts.
Definition: email.h:91
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define CH_NOSTATUS
Suppress the status and x-status fields.
Definition: copy.h:57
#define CH_UPDATE
Update the status and x-status fields?
Definition: copy.h:51
#define CH_UPDATE_REFS
Update References:
Definition: copy.h:68
void mutt_write_references(const struct ListHead *r, FILE *fp, size_t trim, struct ConfigSubset *sub)
Add the message references to a list.
Definition: header.c:514
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:35
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:88
bool read
Email is read.
Definition: email.h:51
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
bool old
Email is seen, but unread.
Definition: email.h:50
struct Envelope * env
Envelope information.
Definition: email.h:90
void mutt_ch_canonical_charset(char *buf, size_t buflen, const char *name)
Canonicalise the charset of a string.
Definition: charset.c:352
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:72
struct TagList tags
For drivers that support server tagging.
Definition: email.h:107
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:62
#define CH_UPDATE_LABEL
Update X-Label: from email->env->x_label?
Definition: copy.h:70
#define MUTT_ENV_CHANGED_XLABEL
X-Label edited.
Definition: envelope.h:34
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: mutt_globals.h:117
#define CH_UPDATE_IRT
Update In-Reply-To:
Definition: copy.h:67
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:142
const char MimeSpecials[]
Characters that need special treatment in MIME.
Definition: mime.c:67
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
char * nm_email_get_folder(struct Email *e)
Get the folder for a Email.
Definition: notmuch.c:1637
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:487
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:522
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define CH_NOLEN
Don&#39;t write Content-Length: and Lines:
Definition: copy.h:63
#define CH_UPDATE_SUBJECT
Update Subject: protected header update.
Definition: copy.h:71
void rfc2047_encode(char **pd, const char *specials, int col, const char *charsets)
RFC-2047-encode a string.
Definition: rfc2047.c:615
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:84
char * data
String.
Definition: list.h:36
char * subject
Email&#39;s subject.
Definition: envelope.h:66
bool flagged
Marked important?
Definition: email.h:43
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
bool replied
Email has been replied to.
Definition: email.h:54
int mutt_copy_hdr(FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy header from one file to another.
Definition: copy.c:78
#define FREE(x)
Definition: memory.h:40
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: globals.c:40
#define STAILQ_EMPTY(head)
Definition: queue.h:345
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
char * C_SendCharset
Config: Character sets for outgoing mail.
Definition: globals.c:38
#define MUTT_ENV_CHANGED_REFS
References changed to break thread.
Definition: envelope.h:33
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define MUTT_ENV_CHANGED_IRT
In-Reply-To changed to link/break threads.
Definition: envelope.h:32
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
A List node for strings.
Definition: list.h:34
char * x_label
X-Label.
Definition: envelope.h:72
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:681
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
Write one header line to a file.
Definition: header.c:419
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_copy_message_fp()

int mutt_copy_message_fp ( FILE *  fp_out,
FILE *  fp_in,
struct Email e,
CopyMessageFlags  cmflags,
CopyHeaderFlags  chflags,
int  wraplen 
)

make a copy of a message from a FILE pointer

Parameters
fp_outWhere to write output
fp_inWhere to get input
eEmail being copied
cmflagsFlags, see CopyMessageFlags
chflagsFlags, see CopyHeaderFlags
wraplenWidth to wrap at (when chflags & CH_DISPLAY)
Return values
0Success
-1Failure

Definition at line 611 of file copy.c.

613 {
614  struct Body *body = e->body;
615  char prefix[128];
616  LOFF_T new_offset = -1;
617  int rc = 0;
618 
619  if (cmflags & MUTT_CM_PREFIX)
620  {
621  if (C_TextFlowed)
622  mutt_str_copy(prefix, ">", sizeof(prefix));
623  else
624  {
625  mutt_make_string(prefix, sizeof(prefix), wraplen, NONULL(C_IndentString),
627  }
628  }
629 
630  if ((cmflags & MUTT_CM_NOHEADER) == 0)
631  {
632  if (cmflags & MUTT_CM_PREFIX)
633  chflags |= CH_PREFIX;
634  else if (e->attach_del && (chflags & CH_UPDATE_LEN))
635  {
636  int new_lines;
637  int rc_attach_del = -1;
638  LOFF_T new_length = body->length;
639  struct Buffer *quoted_date = NULL;
640 
641  quoted_date = mutt_buffer_pool_get();
642  mutt_buffer_addch(quoted_date, '"');
643  mutt_date_make_date(quoted_date);
644  mutt_buffer_addch(quoted_date, '"');
645 
646  /* Count the number of lines and bytes to be deleted */
647  fseeko(fp_in, body->offset, SEEK_SET);
648  new_lines = e->lines - count_delete_lines(fp_in, body, &new_length,
649  mutt_buffer_len(quoted_date));
650 
651  /* Copy the headers */
652  if (mutt_copy_header(fp_in, e, fp_out, chflags | CH_NOLEN | CH_NONEWLINE, NULL, wraplen))
653  goto attach_del_cleanup;
654  fprintf(fp_out, "Content-Length: " OFF_T_FMT "\n", new_length);
655  if (new_lines <= 0)
656  new_lines = 0;
657  else
658  fprintf(fp_out, "Lines: %d\n", new_lines);
659 
660  putc('\n', fp_out);
661  if (ferror(fp_out) || feof(fp_out))
662  goto attach_del_cleanup;
663  new_offset = ftello(fp_out);
664 
665  /* Copy the body */
666  if (fseeko(fp_in, body->offset, SEEK_SET) < 0)
667  goto attach_del_cleanup;
668  if (copy_delete_attach(body, fp_in, fp_out, mutt_b2s(quoted_date)))
669  goto attach_del_cleanup;
670 
671  mutt_buffer_pool_release(&quoted_date);
672 
673  LOFF_T fail = ((ftello(fp_out) - new_offset) - new_length);
674  if (fail)
675  {
676  mutt_error(ngettext("The length calculation was wrong by %ld byte",
677  "The length calculation was wrong by %ld bytes", fail),
678  fail);
679  new_length += fail;
680  }
681 
682  /* Update original message if we are sync'ing a mailfolder */
683  if (cmflags & MUTT_CM_UPDATE)
684  {
685  e->attach_del = false;
686  e->lines = new_lines;
687  body->offset = new_offset;
688 
689  /* update the total size of the mailbox to reflect this deletion */
690  Context->mailbox->size -= body->length - new_length;
691  /* if the message is visible, update the visible size of the mailbox as well. */
692  if (Context->mailbox->v2r[e->msgno] != -1)
693  Context->vsize -= body->length - new_length;
694 
695  body->length = new_length;
696  mutt_body_free(&body->parts);
697  }
698 
699  rc_attach_del = 0;
700 
701  attach_del_cleanup:
702  mutt_buffer_pool_release(&quoted_date);
703  return rc_attach_del;
704  }
705 
706  if (mutt_copy_header(fp_in, e, fp_out, chflags,
707  (chflags & CH_PREFIX) ? prefix : NULL, wraplen) == -1)
708  {
709  return -1;
710  }
711 
712  new_offset = ftello(fp_out);
713  }
714 
715  if (cmflags & MUTT_CM_DECODE)
716  {
717  /* now make a text/plain version of the message */
718  struct State s = { 0 };
719  s.fp_in = fp_in;
720  s.fp_out = fp_out;
721  if (cmflags & MUTT_CM_PREFIX)
722  s.prefix = prefix;
723  if (cmflags & MUTT_CM_DISPLAY)
724  {
725  s.flags |= MUTT_DISPLAY;
726  s.wraplen = wraplen;
727  }
728  if (cmflags & MUTT_CM_PRINTING)
729  s.flags |= MUTT_PRINTING;
730  if (cmflags & MUTT_CM_WEED)
731  s.flags |= MUTT_WEED;
732  if (cmflags & MUTT_CM_CHARCONV)
733  s.flags |= MUTT_CHARCONV;
734  if (cmflags & MUTT_CM_REPLYING)
735  s.flags |= MUTT_REPLYING;
736 
737  if ((WithCrypto != 0) && cmflags & MUTT_CM_VERIFY)
738  s.flags |= MUTT_VERIFY;
739 
740  rc = mutt_body_handler(body, &s);
741  }
742  else if ((WithCrypto != 0) && (cmflags & MUTT_CM_DECODE_CRYPT) && (e->security & SEC_ENCRYPT))
743  {
744  struct Body *cur = NULL;
745  FILE *fp = NULL;
746 
747  if (((WithCrypto & APPLICATION_PGP) != 0) && (cmflags & MUTT_CM_DECODE_PGP) &&
748  (e->security & APPLICATION_PGP) && (e->body->type == TYPE_MULTIPART))
749  {
750  if (crypt_pgp_decrypt_mime(fp_in, &fp, e->body, &cur))
751  return -1;
752  fputs("MIME-Version: 1.0\n", fp_out);
753  }
754 
755  if (((WithCrypto & APPLICATION_SMIME) != 0) && (cmflags & MUTT_CM_DECODE_SMIME) &&
756  (e->security & APPLICATION_SMIME) && (e->body->type == TYPE_APPLICATION))
757  {
758  if (crypt_smime_decrypt_mime(fp_in, &fp, e->body, &cur))
759  return -1;
760  }
761 
762  if (!cur)
763  {
764  mutt_error(_("No decryption engine available for message"));
765  return -1;
766  }
767 
768  mutt_write_mime_header(cur, fp_out, NeoMutt->sub);
769  fputc('\n', fp_out);
770 
771  if (fseeko(fp, cur->offset, SEEK_SET) < 0)
772  return -1;
773  if (mutt_file_copy_bytes(fp, fp_out, cur->length) == -1)
774  {
775  mutt_file_fclose(&fp);
776  mutt_body_free(&cur);
777  return -1;
778  }
779  mutt_body_free(&cur);
780  mutt_file_fclose(&fp);
781  }
782  else
783  {
784  if (fseeko(fp_in, body->offset, SEEK_SET) < 0)
785  return -1;
786  if (cmflags & MUTT_CM_PREFIX)
787  {
788  int c;
789  size_t bytes = body->length;
790 
791  fputs(prefix, fp_out);
792 
793  while (((c = fgetc(fp_in)) != EOF) && bytes--)
794  {
795  fputc(c, fp_out);
796  if (c == '\n')
797  {
798  fputs(prefix, fp_out);
799  }
800  }
801  }
802  else if (mutt_file_copy_bytes(fp_in, fp_out, body->length) == -1)
803  return -1;
804  }
805 
806  if ((cmflags & MUTT_CM_UPDATE) && ((cmflags & MUTT_CM_NOHEADER) == 0) &&
807  (new_offset != -1))
808  {
809  body->offset = new_offset;
810  mutt_body_free(&body->parts);
811  }
812 
813  return rc;
814 }
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
The "current" mailbox.
Definition: context.h:38
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
int lines
How many lines in the body of this message?
Definition: email.h:85
#define NONULL(x)
Definition: string2.h:37
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
#define WithCrypto
Definition: lib.h:123
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:44
void mutt_date_make_date(struct Buffer *buf)
Write a date in RFC822 format to a buffer.
Definition: date.c:377
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct Body * body
List of MIME parts.
Definition: email.h:91
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
#define MUTT_CM_UPDATE
Update structs on sync.
Definition: copy.h:39
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
String manipulation buffer.
Definition: buffer.h:33
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
static int count_delete_lines(FILE *fp, struct Body *b, LOFF_T *length, size_t datelen)
Count lines to be deleted in this email body.
Definition: copy.c:567
FILE * fp_out
File to write to.
Definition: state.h:47
#define MUTT_PRINTING
Are we printing? - MUTT_DISPLAY "light".
Definition: state.h:37
#define MUTT_CM_PRINTING
Printing the message - display light.
Definition: copy.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:36
FILE * fp_in
File to read from.
Definition: state.h:46
#define MUTT_CM_REPLYING
Replying the message.
Definition: copy.h:43
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Mailbox * mailbox
Definition: context.h:50
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:38
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int mutt_write_mime_header(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Create a MIME header.
Definition: header.c:760
int wraplen
Width to wrap lines to (when flags & MUTT_DISPLAY)
Definition: state.h:50
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:40
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_VERIFY
Perform signature verification.
Definition: state.h:33
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
static int copy_delete_attach(struct Body *b, FILE *fp_in, FILE *fp_out, const char *quoted_date)
Copy a message, deleting marked attachments.
Definition: copy.c:924
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define MUTT_WEED
Weed headers even when not in display mode.
Definition: state.h:35
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:431
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
int mutt_file_copy_bytes(FILE *fp_in, FILE *fp_out, size_t size)
Copy some content from one file to another.
Definition: file.c:241
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:46
#define CH_NOLEN
Don&#39;t write Content-Length: and Lines:
Definition: copy.h:63
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:207
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
int mutt_copy_header(FILE *fp_in, struct Email *e, FILE *fp_out, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy Email header.
Definition: copy.c:400
#define mutt_error(...)
Definition: logging.h:84
#define MUTT_CM_DECODE_PGP
Used for decoding PGP messages.
Definition: copy.h:44
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
Keep track when processing files.
Definition: state.h:44
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1593
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
#define mutt_make_string(BUF, BUFLEN, COLS, S, M, INPGR, E)
Definition: hdrline.h:58
int msgno
Number displayed to the user.
Definition: email.h:87
WHERE char * C_IndentString
Config: String used to indent &#39;reply&#39; text.
Definition: mutt_globals.h:103
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: mutt_globals.h:168
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_copy_message()

int mutt_copy_message ( FILE *  fp_out,
struct Mailbox m,
struct Email e,
CopyMessageFlags  cmflags,
CopyHeaderFlags  chflags,
int  wraplen 
)

Copy a message from a Mailbox.

Parameters
fp_outFILE pointer to write to
mSource mailbox
eEmail
cmflagsFlags, see CopyMessageFlags
chflagsFlags, see CopyHeaderFlags
wraplenWidth to wrap at (when chflags & CH_DISPLAY)
Return values
0Success
-1Failure

should be made to return -1 on fatal errors, and 1 on non-fatal errors like partial decode, where it is worth displaying as much as possible

Definition at line 830 of file copy.c.

832 {
833  struct Message *msg = mx_msg_open(m, e->msgno);
834  if (!msg)
835  return -1;
836  if (!e->body)
837  return -1;
838  int rc = mutt_copy_message_fp(fp_out, msg->fp, e, cmflags, chflags, wraplen);
839  if ((rc == 0) && (ferror(fp_out) || feof(fp_out)))
840  {
841  mutt_debug(LL_DEBUG1, "failed to detect EOF!\n");
842  rc = -1;
843  }
844  mx_msg_close(m, &msg);
845  return rc;
846 }
struct Body * body
List of MIME parts.
Definition: email.h:91
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1206
A local copy of an email.
Definition: mx.h:83
Log at debug level 1.
Definition: logging.h:40
FILE * fp
pointer to the message data
Definition: mx.h:85
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
make a copy of a message from a FILE pointer
Definition: copy.c:611
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1158
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_append_message()

int mutt_append_message ( struct Mailbox dest,
struct Mailbox src,
struct Email e,
CopyMessageFlags  cmflags,
CopyHeaderFlags  chflags 
)

Append a message.

Parameters
destDestination Mailbox
srcSource Mailbox
eEmail
cmflagsFlags, see CopyMessageFlags
chflagsFlags, see CopyHeaderFlags
Return values
0Success
-1Failure

Definition at line 900 of file copy.c.

902 {
903  struct Message *msg = mx_msg_open(src, e->msgno);
904  if (!msg)
905  return -1;
906  int rc = append_message(dest, msg->fp, src, e, cmflags, chflags);
907  mx_msg_close(src, &msg);
908  return rc;
909 }
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1206
static int append_message(struct Mailbox *dest, FILE *fp_in, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
appends a copy of the given message to a mailbox
Definition: copy.c:859
A local copy of an email.
Definition: mx.h:83
FILE * fp
pointer to the message data
Definition: mx.h:85
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1158
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function: